diff mercurial/hgweb/hgweb_mod.py @ 36023:cdc93fe1da77

wireprotoserver: move protocol parsing and dispatch out of hgweb Previously, hgweb_mod had code for detecting if the request was for the wire protocol. It would then (eventually) call wireprotoserver.callhttp() to dispatch the request handling. Detection of wire protocol requests is not trivial. There's currently a big gotcha in the handling of the "cmd" request parameter, for example. Furthermore, in the near future we will have a second HTTP protocol handler. Its mechanism for calling commands will be a bit different. And we don't want the low-level logic for detecting protocol commands to live in hgweb. We establish a new function in wireprotoserver for detecting an HTTP protocol request and for giving the caller an easy-to-use mechanism for dispatching requests to it. Some wire protocol specific functionality still lives in hgweb. This will be addressed in subsequent commits. Differential Revision: https://phab.mercurial-scm.org/D2019
author Gregory Szorc <gregory.szorc@gmail.com>
date Wed, 31 Jan 2018 16:21:43 -0800
parents 5a56bf4180ad
children e69e65b2b4a9
line wrap: on
line diff
--- a/mercurial/hgweb/hgweb_mod.py	Thu Feb 01 18:48:52 2018 -0800
+++ b/mercurial/hgweb/hgweb_mod.py	Wed Jan 31 16:21:43 2018 -0800
@@ -357,26 +357,18 @@
             query = req.env[r'QUERY_STRING'].partition(r'&')[0]
             query = query.partition(r';')[0]
 
-        # The ``cmd`` request parameter is used by both the wire protocol
-        # and hgweb. We route all known wire protocol commands to the
-        # wire protocol handler, even if the command isn't available for
-        # this transport. That's better for machine clients in the case
-        # of an errant request to an unavailable protocol command. And it
-        # prevents hgweb from accidentally using ``cmd`` values used by
-        # the wire protocol.
+        # Route it to a wire protocol handler if it looks like a wire protocol
+        # request.
+        protohandler = wireprotoserver.parsehttprequest(rctx.repo, req, query)
 
-        # process this if it's a protocol request
-        # protocol bits don't need to create any URLs
-        # and the clients always use the old URL structure
-
-        cmd = pycompat.sysbytes(req.form.get(r'cmd', [r''])[0])
-        if wireprotoserver.iscmd(cmd):
+        if protohandler:
+            cmd = protohandler['cmd']
             try:
                 if query:
                     raise ErrorResponse(HTTP_NOT_FOUND)
                 if cmd in perms:
                     self.check_perm(rctx, req, perms[cmd])
-                return wireprotoserver.callhttp(rctx.repo, req, cmd)
+                return protohandler['dispatch']()
             except ErrorResponse as inst:
                 # A client that sends unbundle without 100-continue will
                 # break if we respond early.
@@ -425,6 +417,8 @@
                     if fn.endswith(ext):
                         req.form['node'] = [fn[:-len(ext)]]
                         req.form['type'] = [type_]
+        else:
+            cmd = pycompat.sysbytes(req.form.get(r'cmd', [r''])[0])
 
         # process the web interface request