D1999: wireproto: function for testing if wire protocol command is available

indygreg (Gregory Szorc) phabricator at mercurial-scm.org
Wed Feb 7 17:41:33 EST 2018


This revision was automatically updated to reflect the committed changes.
Closed by commit rHG5a56bf4180ad: wireproto: function for testing if wire protocol command is available (authored by indygreg, committed by ).

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D1999?vs=5258&id=5307

REVISION DETAIL
  https://phab.mercurial-scm.org/D1999

AFFECTED FILES
  mercurial/hgweb/hgweb_mod.py
  mercurial/wireproto.py
  mercurial/wireprotoserver.py

CHANGE DETAILS

diff --git a/mercurial/wireprotoserver.py b/mercurial/wireprotoserver.py
--- a/mercurial/wireprotoserver.py
+++ b/mercurial/wireprotoserver.py
@@ -223,6 +223,13 @@
             yield chunk
 
     rsp = wireproto.dispatch(repo, proto, cmd)
+
+    if not wireproto.commands.commandavailable(cmd, proto):
+        req.respond(HTTP_OK, HGERRTYPE,
+                    body=_('requested wire protocol command is not available '
+                           'over HTTP'))
+        return []
+
     if isinstance(rsp, bytes):
         req.respond(HTTP_OK, HGTYPE, body=rsp)
         return []
@@ -351,7 +358,7 @@
 
     def serve_one(self):
         cmd = self._fin.readline()[:-1]
-        if cmd and cmd in wireproto.commands:
+        if cmd and wireproto.commands.commandavailable(cmd, self):
             rsp = wireproto.dispatch(self._repo, self, cmd)
             self._handlers[rsp.__class__](self, rsp)
         elif cmd:
diff --git a/mercurial/wireproto.py b/mercurial/wireproto.py
--- a/mercurial/wireproto.py
+++ b/mercurial/wireproto.py
@@ -691,6 +691,12 @@
 
         return super(commanddict, self).__setitem__(k, v)
 
+    def commandavailable(self, command, proto):
+        """Determine if a command is available for the requested protocol."""
+        # For now, commands are available for all protocols. So do a simple
+        # membership test.
+        return command in self
+
 commands = commanddict()
 
 def wireprotocommand(name, args=''):
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
@@ -357,6 +357,14 @@
             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.
+
         # 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



To: indygreg, #hg-reviewers, durin42
Cc: mercurial-devel


More information about the Mercurial-devel mailing list