hgweb: only accept POST requests for unbundle
authorDirkjan Ochtman <dirkjan@ochtman.nl>
Fri, 21 Mar 2008 00:55:53 +0100
changeset 6335 e29557d687c9
parent 6334 7016f7fb8fe3
child 6336 4b0c9c674707
hgweb: only accept POST requests for unbundle
mercurial/hgweb/protocol.py
tests/test-hgweb-commands
tests/test-hgweb-commands.out
tests/test-push-http.out
--- a/mercurial/hgweb/protocol.py	Fri Mar 21 00:39:39 2008 +0100
+++ b/mercurial/hgweb/protocol.py	Fri Mar 21 00:55:53 2008 +0100
@@ -106,17 +106,26 @@
     req.write(resp)
 
 def unbundle(web, req):
+
     def bail(response, headers={}):
-        length = int(req.env['CONTENT_LENGTH'])
+        length = int(req.env.get('CONTENT_LENGTH', 0))
         for s in util.filechunkiter(req, limit=length):
             # drain incoming bundle, else client will not see
             # response when run outside cgi script
             pass
+
+        status = headers.pop('status', HTTP_OK)
         req.header(headers.items())
-        req.respond(HTTP_OK, HGTYPE)
+        req.respond(status, HGTYPE)
         req.write('0\n')
         req.write(response)
 
+    # enforce that you can only unbundle with POST requests
+    if req.env['REQUEST_METHOD'] != 'POST':
+        headers = {'status': '405 Method Not Allowed'}
+        bail('unbundle requires POST request\n', headers)
+        return
+
     # require ssl by default, auth info cannot be sniffed and
     # replayed
     ssl_req = web.configbool('web', 'push_ssl', True)
@@ -130,8 +139,7 @@
 
     # do not allow push unless explicitly allowed
     if not web.check_perm(req, 'push', False):
-        bail('push not authorized\n',
-             headers={'status': '401 Unauthorized'})
+        bail('push not authorized\n', headers={'status': '401 Unauthorized'})
         return
 
     their_heads = req.form['heads'][0].split(' ')
--- a/tests/test-hgweb-commands	Fri Mar 21 00:39:39 2008 +0100
+++ b/tests/test-hgweb-commands	Fri Mar 21 00:55:53 2008 +0100
@@ -47,6 +47,8 @@
 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/changegroup'
 echo % stream_out
 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/stream_out'
+echo % failing unbundle, requires POST request
+"$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/unbundle'
 
 echo % Static files
 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/static/style.css'
Binary file tests/test-hgweb-commands.out has changed
--- a/tests/test-push-http.out	Fri Mar 21 00:39:39 2008 +0100
+++ b/tests/test-push-http.out	Fri Mar 21 00:55:53 2008 +0100
@@ -6,14 +6,14 @@
 ssl required
 % serve errors
 % expect authorization error
+abort: authorization failed
 pushing to http://localhost/
 searching for changes
-push not authorized
 % serve errors
 % expect authorization error: must have authorized user
+abort: authorization failed
 pushing to http://localhost/
 searching for changes
-push not authorized
 % serve errors
 % expect success
 pushing to http://localhost/
@@ -26,12 +26,12 @@
 changegroup hook: HG_NODE=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_SOURCE=serve HG_URL=remote:http 
 rolling back last transaction
 % expect authorization error: all users denied
+abort: authorization failed
 pushing to http://localhost/
 searching for changes
-push not authorized
 % serve errors
 % expect authorization error: some users denied, users must be authenticated
+abort: authorization failed
 pushing to http://localhost/
 searching for changes
-push not authorized
 % serve errors