[PATCH] hgweb: fix url base generation to handle absolute paths in baseurl
Alexander Solovyov
piranha at piranha.org.ua
Thu May 14 15:14:31 CDT 2009
# HG changeset patch
# User Alexander Solovyov <piranha at piranha.org.ua>
# Date 1242332038 -10800
# Node ID 98e8235939ca4265b1aaf80d313e6c856365bdca
# Parent 9dfee83c93c80570ff1e3f98e937dfa6caf28801
hgweb: fix url base generation to handle absolute paths in baseurl
Adds possibility to specify hostname, port and protocol, used in absolute url
building (f.e. in atom urls), in webdir-conf via web.baseurl. This allows usage
of hgweb behind mod_proxy or nginx.
diff --git a/mercurial/hgweb/hgweb_mod.py b/mercurial/hgweb/hgweb_mod.py
--- a/mercurial/hgweb/hgweb_mod.py
+++ b/mercurial/hgweb/hgweb_mod.py
@@ -105,7 +105,7 @@ class hgweb(object):
# work with CGI variables to create coherent structure
# use SCRIPT_NAME, PATH_INFO and QUERY_STRING as well as our REPO_NAME
- req.url = req.env['SCRIPT_NAME']
+ req.url = self.config('web', 'baseurl', req.env['SCRIPT_NAME'])
if not req.url.endswith('/'):
req.url += '/'
if 'REPO_NAME' in req.env:
@@ -200,17 +200,24 @@ class hgweb(object):
# determine scheme, port and server name
# this is needed to create absolute urls
- proto = req.env.get('wsgi.url_scheme')
- if proto == 'https':
- proto = 'https'
- default_port = "443"
+ if not '://' in req.url:
+ proto = req.env.get('wsgi.url_scheme')
+ if proto == 'https':
+ proto = 'https'
+ default_port = "443"
+ else:
+ proto = 'http'
+ default_port = "80"
+
+ if not req.url.startswith('//'):
+ port = req.env["SERVER_PORT"]
+ port = port != default_port and (":" + port) or ""
+ urlbase = '%s://%s%s' % (proto, req.env['SERVER_NAME'], port)
+ else:
+ urlbase = proto + '://'
else:
- proto = 'http'
- default_port = "80"
+ urlbase = ''
- port = req.env["SERVER_PORT"]
- port = port != default_port and (":" + port) or ""
- urlbase = '%s://%s%s' % (proto, req.env['SERVER_NAME'], port)
staticurl = self.config("web", "staticurl") or req.url + 'static/'
if not staticurl.endswith('/'):
staticurl += '/'
diff --git a/mercurial/hgweb/hgwebdir_mod.py b/mercurial/hgweb/hgwebdir_mod.py
--- a/mercurial/hgweb/hgwebdir_mod.py
+++ b/mercurial/hgweb/hgwebdir_mod.py
@@ -52,7 +52,6 @@ class hgwebdir(object):
self.stripecount = self.ui.config('web', 'stripes', 1)
if self.stripecount:
self.stripecount = int(self.stripecount)
- self._baseurl = self.ui.config('web', 'baseurl')
if self.repos:
return
@@ -216,11 +215,15 @@ class hgwebdir(object):
continue
parts = [name]
+ baseurl = self.ui.config('web', 'baseurl')
if 'PATH_INFO' in req.env:
parts.insert(0, req.env['PATH_INFO'].rstrip('/'))
- if req.env['SCRIPT_NAME']:
+ if req.env['SCRIPT_NAME'] and baseurl is None:
parts.insert(0, req.env['SCRIPT_NAME'])
- url = ('/'.join(parts).replace("//", "/")) + '/'
+ url = ('/'.join(parts)).replace('//', '/') + '/'
+ if baseurl is not None:
+ baseurl = baseurl.rstrip('/')
+ url = baseurl + url
# update time with local timezone
try:
@@ -272,8 +275,6 @@ class hgwebdir(object):
for column in sortable]
self.refresh()
- if self._baseurl is not None:
- req.env['SCRIPT_NAME'] = self._baseurl
return tmpl("index", entries=entries, subdir=subdir,
sortcolumn=sortcolumn, descending=descending,
@@ -296,10 +297,7 @@ class hgwebdir(object):
def config(section, name, default=None, untrusted=True):
return self.ui.config(section, name, default, untrusted)
- if self._baseurl is not None:
- req.env['SCRIPT_NAME'] = self._baseurl
-
- url = req.env.get('SCRIPT_NAME', '')
+ url = self.ui.config('web', 'baseurl', req.env.get('SCRIPT_NAME', ''))
if not url.endswith('/'):
url += '/'
diff --git a/tests/test-hgweb b/tests/test-hgweb
--- a/tests/test-hgweb
+++ b/tests/test-hgweb
@@ -42,3 +42,17 @@ echo % static file
echo % errors
cat errors.log
+
+echo % relative baseurl
+"$TESTDIR/killdaemons.py"
+echo "[web]\nbaseurl=/prefix/" > .hg/hgrc
+hg serve -p $HGPORT -d --pid-file=hg.pid -A access.log
+cat hg.pid >> $DAEMON_PIDS
+("$TESTDIR/get-with-headers.py" localhost:$HGPORT '/file/tip/foo')
+
+echo % absolute baseurl
+"$TESTDIR/killdaemons.py"
+echo "[web]\nbaseurl=http://example.com" > .hg/hgrc
+hg serve -p $HGPORT -d --pid-file=hg.pid -A access.log
+cat hg.pid >> $DAEMON_PIDS
+("$TESTDIR/get-with-headers.py" localhost:$HGPORT '/file/tip/foo')
diff --git a/tests/test-hgweb.out b/tests/test-hgweb.out
--- a/tests/test-hgweb.out
+++ b/tests/test-hgweb.out
@@ -277,3 +277,175 @@ ul#graphnodes li .info {
font-style: italic;
}
% errors
+% relative baseurl
+200 Script output follows
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
+<head>
+<link rel="icon" href="/prefix/static/hgicon.png" type="image/png" />
+<meta name="robots" content="index, nofollow" />
+<link rel="stylesheet" href="/prefix/static/style-paper.css" type="text/css" />
+
+<title>prefix: 2ef0ac749a14 foo</title>
+</head>
+<body>
+
+<div class="container">
+<div class="menu">
+<div class="logo">
+<a href="http://www.selenic.com/mercurial/">
+<img src="/prefix/static/hglogo.png" alt="mercurial" /></a>
+</div>
+<ul>
+<li><a href="/prefix/shortlog/2ef0ac749a14">log</a></li>
+<li><a href="/prefix/graph/2ef0ac749a14">graph</a></li>
+<li><a href="/prefix/tags">tags</a></li>
+<li><a href="/prefix/branches">branches</a></li>
+</ul>
+<ul>
+<li><a href="/prefix/rev/2ef0ac749a14">changeset</a></li>
+<li><a href="/prefix/file/2ef0ac749a14/">browse</a></li>
+</ul>
+<ul>
+<li class="active">file</li>
+<li><a href="/prefix/diff/2ef0ac749a14/foo">diff</a></li>
+<li><a href="/prefix/annotate/2ef0ac749a14/foo">annotate</a></li>
+<li><a href="/prefix/log/2ef0ac749a14/foo">file log</a></li>
+<li><a href="/prefix/raw-file/2ef0ac749a14/foo">raw</a></li>
+</ul>
+</div>
+
+<div class="main">
+<h2><a href="/prefix/">prefix</a></h2>
+<h3>view foo @ 0:2ef0ac749a14</h3>
+
+<form class="search" action="/prefix/log">
+
+<p><input name="rev" id="search1" type="text" size="30" /></p>
+<div id="hint">find changesets by author, revision,
+files, or words in the commit message</div>
+</form>
+
+<div class="description">base</div>
+
+<table id="changesetEntry">
+<tr>
+ <th class="author">author</th>
+ <td class="author">test</td>
+</tr>
+<tr>
+ <th class="date">date</th>
+ <td class="date">Thu Jan 01 00:00:00 1970 +0000 (many years ago)</td>
+</tr>
+<tr>
+ <th class="author">parents</th>
+ <td class="author"></td>
+</tr>
+<tr>
+ <th class="author">children</th>
+ <td class="author"></td>
+</tr>
+
+</table>
+
+<div class="overflow">
+<div class="sourcefirst"> line source</div>
+<div class="parity0 source"><a href="#l1" id="l1"> 1</a> foo
+</div>
+<div class="sourcelast"></div>
+</div>
+</div>
+</div>
+
+
+
+</body>
+</html>
+
+% absolute baseurl
+200 Script output follows
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
+<head>
+<link rel="icon" href="http://example.com/static/hgicon.png" type="image/png" />
+<meta name="robots" content="index, nofollow" />
+<link rel="stylesheet" href="http://example.com/static/style-paper.css" type="text/css" />
+
+<title>http://example.com: 2ef0ac749a14 foo</title>
+</head>
+<body>
+
+<div class="container">
+<div class="menu">
+<div class="logo">
+<a href="http://www.selenic.com/mercurial/">
+<img src="http://example.com/static/hglogo.png" alt="mercurial" /></a>
+</div>
+<ul>
+<li><a href="http://example.com/shortlog/2ef0ac749a14">log</a></li>
+<li><a href="http://example.com/graph/2ef0ac749a14">graph</a></li>
+<li><a href="http://example.com/tags">tags</a></li>
+<li><a href="http://example.com/branches">branches</a></li>
+</ul>
+<ul>
+<li><a href="http://example.com/rev/2ef0ac749a14">changeset</a></li>
+<li><a href="http://example.com/file/2ef0ac749a14/">browse</a></li>
+</ul>
+<ul>
+<li class="active">file</li>
+<li><a href="http://example.com/diff/2ef0ac749a14/foo">diff</a></li>
+<li><a href="http://example.com/annotate/2ef0ac749a14/foo">annotate</a></li>
+<li><a href="http://example.com/log/2ef0ac749a14/foo">file log</a></li>
+<li><a href="http://example.com/raw-file/2ef0ac749a14/foo">raw</a></li>
+</ul>
+</div>
+
+<div class="main">
+<h2><a href="http://example.com/">http://example.com</a></h2>
+<h3>view foo @ 0:2ef0ac749a14</h3>
+
+<form class="search" action="http://example.com/log">
+
+<p><input name="rev" id="search1" type="text" size="30" /></p>
+<div id="hint">find changesets by author, revision,
+files, or words in the commit message</div>
+</form>
+
+<div class="description">base</div>
+
+<table id="changesetEntry">
+<tr>
+ <th class="author">author</th>
+ <td class="author">test</td>
+</tr>
+<tr>
+ <th class="date">date</th>
+ <td class="date">Thu Jan 01 00:00:00 1970 +0000 (many years ago)</td>
+</tr>
+<tr>
+ <th class="author">parents</th>
+ <td class="author"></td>
+</tr>
+<tr>
+ <th class="author">children</th>
+ <td class="author"></td>
+</tr>
+
+</table>
+
+<div class="overflow">
+<div class="sourcefirst"> line source</div>
+<div class="parity0 source"><a href="#l1" id="l1"> 1</a> foo
+</div>
+<div class="sourcelast"></div>
+</div>
+</div>
+</div>
+
+
+
+</body>
+</html>
+
diff --git a/tests/test-hgwebdir b/tests/test-hgwebdir
--- a/tests/test-hgwebdir
+++ b/tests/test-hgwebdir
@@ -82,6 +82,13 @@ echo % should succeed, slashy names
"$TESTDIR/get-with-headers.py" localhost:$HGPORT1 '/rcoll/?style=raw'
"$TESTDIR/get-with-headers.py" localhost:$HGPORT1 '/rcoll/b/d/file/tip/d?style=raw'
+echo % baseurl
+"$TESTDIR/killdaemons.py"
+echo '\n[web]\nbaseurl=http://example.com/' >> collections.conf
+hg serve -p $HGPORT -d --pid-file=hg.pid --webdir-conf collections.conf \
+ -A access-collections.log -E error-collections.log
+cat hg.pid >> $DAEMON_PIDS
+"$TESTDIR/get-with-headers.py" localhost:$HGPORT '/error404/'
cat > collections.conf <<EOF
[collections]
diff --git a/tests/test-hgwebdir.out b/tests/test-hgwebdir.out
--- a/tests/test-hgwebdir.out
+++ b/tests/test-hgwebdir.out
@@ -307,6 +307,31 @@ 200 Script output follows
200 Script output follows
d
+% baseurl
+404 Not Found
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
+<head>
+<link rel="icon" href="http://example.com/static/hgicon.png" type="image/png" />
+<meta name="robots" content="index, nofollow" />
+<link rel="stylesheet" href="http://example.com/static/style-paper.css" type="text/css" />
+
+<title>Mercurial repository not found</title>
+</head>
+<body>
+
+<h2>Mercurial repository not found</h2>
+
+The specified repository "error404" is unknown, sorry.
+
+Please go back to the main repository list page.
+
+
+
+</body>
+</html>
+
% collections: should succeed
200 Script output follows
More information about the Mercurial-devel
mailing list