hgweb: allow symbolic revisions with forward slashes in urls
authorAnton Shestakov <av6@dwimlabs.net>
Sun, 12 Jul 2015 16:06:57 +0800
changeset 25777 1c2a8db33b8f
parent 25776 809c3e4a9e31
child 25778 3a33412792f1
hgweb: allow symbolic revisions with forward slashes in urls It's possible to have a branch/tag/bookmark with all kinds of special characters, such as {}/\!?. While not very conveniently, symbolic revisions with such characters work from command line if user correctly quotes the characters. These characters also work in hgweb, when they are properly encoded, with one exception: '/' (forward slash, urlencoded as '%2F'), which was getting decoded before hgweb could parse it as a part of PATH_INFO. Because of that, hgweb was seeing it as any other forward slash, that is, as just another url parts separator. For example, if user wanted to see the content of dir/file at bookmark 'feature/eggs', url could be: '/file/feature%2Feggs/dir/file'. But hgweb tried to find a revision 'feature' and get contents of 'eggs/dir/file'. To fix this, let's assume forward slashes are doubly-urlencoded (%252F), so CGI/WSGI server decodes it into %2F. Then we can decode %2F in the revision part of the url into an actual '/' character. Making hgweb produce such urls will be done in the next 2 patches.
mercurial/hgweb/hgweb_mod.py
tests/test-hgweb.t
--- a/mercurial/hgweb/hgweb_mod.py	Mon Jul 13 15:05:03 2015 +0100
+++ b/mercurial/hgweb/hgweb_mod.py	Sun Jul 12 16:06:57 2015 +0800
@@ -235,7 +235,7 @@
                 req.form['file'] = ['/'.join(args)]
             else:
                 if args and args[0]:
-                    node = args.pop(0)
+                    node = args.pop(0).replace('%2F', '/')
                     req.form['node'] = [node]
                 if args:
                     req.form['file'] = args
--- a/tests/test-hgweb.t	Mon Jul 13 15:05:03 2015 +0100
+++ b/tests/test-hgweb.t	Sun Jul 12 16:06:57 2015 +0800
@@ -10,6 +10,9 @@
   $ hg ci -Ambase
   adding da/foo
   adding foo
+  $ hg bookmark -r0 '@'
+  $ hg bookmark -r0 'a b c'
+  $ hg bookmark -r0 'd/e/f'
   $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
   $ cat hg.pid >> $DAEMON_PIDS
 
@@ -264,7 +267,7 @@
   <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
   <h3>
    directory / @ 0:<a href="/rev/2ef0ac749a14">2ef0ac749a14</a>
-   <span class="tag">tip</span> 
+   <span class="tag">tip</span> <span class="tag">@</span> <span class="tag">a b c</span> <span class="tag">d/e/f</span> 
   </h3>
   
   <form class="search" action="/log">
@@ -557,6 +560,9 @@
   summary:     base
   branch:      default
   tag:         tip
+  bookmark:    @
+  bookmark:    a b c
+  bookmark:    d/e/f
   
   
   $ hg phase --draft tip
@@ -580,9 +586,30 @@
   user:        test
   date:        Thu, 01 Jan 1970 00:00:00 +0000
   summary:     base
+  bookmark:    @
+  bookmark:    a b c
+  bookmark:    d/e/f
   
   
 
+access bookmarks
+
+  $ get-with-headers.py localhost:$HGPORT 'rev/@?style=paper' | egrep '^200|changeset 0:'
+  200 Script output follows
+   changeset 0:<a href="/rev/2ef0ac749a14?style=paper">2ef0ac749a14</a>
+
+  $ get-with-headers.py localhost:$HGPORT 'rev/%40?style=paper' | egrep '^200|changeset 0:'
+  200 Script output follows
+   changeset 0:<a href="/rev/2ef0ac749a14?style=paper">2ef0ac749a14</a>
+
+  $ get-with-headers.py localhost:$HGPORT 'rev/a%20b%20c?style=paper' | egrep '^200|changeset 0:'
+  200 Script output follows
+   changeset 0:<a href="/rev/2ef0ac749a14?style=paper">2ef0ac749a14</a>
+
+  $ get-with-headers.py localhost:$HGPORT 'rev/d%252Fe%252Ff?style=paper' | egrep '^200|changeset 0:'
+  200 Script output follows
+   changeset 0:<a href="/rev/2ef0ac749a14?style=paper">2ef0ac749a14</a>
+
 no style can be loaded from directories other than the specified paths
 
   $ mkdir -p x/templates/fallback