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

2018-02-07 Thread indygreg (Gregory Szorc)
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=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
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


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

2018-02-06 Thread indygreg (Gregory Szorc)
indygreg updated this revision to Diff 5258.

REPOSITORY
  rHG Mercurial

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

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
@@ -217,6 +217,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 []
@@ -345,7 +352,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
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


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

2018-02-01 Thread indygreg (Gregory Szorc)
indygreg created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  Currently, we perform simple membership testing for whether a wire
  command is available. In the future, not all wire protocol commands
  will be available on all transports. For example, a legacy transport
  may not support newer commands.
  
  In preparation of this, teach the protocol handlers to call into a
  function to determine if a wire protocol command is available. That
  function currently does membership testing like before, so behavior
  should be identical.
  
  In the case of the HTTP server, behavior is a bit wonkier. "cmd" is
  used by both the wire protocol and hgweb. We do want the protocol
  handler to handle requests for all commands that look like wire
  protocol commands, even if they aren't available. Otherwise, the
  fallback to hgweb would only confuse automated clients and make it
  easier for hgweb to accidentally implement a "cmd" that is identical
  to wire protocol commands (since they aren't centrally registered).

REPOSITORY
  rHG Mercurial

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
@@ -220,6 +220,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 []
@@ -348,7 +355,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
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel