D2726: debugcommands: support connecting to HTTP peers
This revision was automatically updated to reflect the committed changes. Closed by commit rHGfc8939825632: debugcommands: support connecting to HTTP peers (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D2726?vs=6994&id=7158 REVISION DETAIL https://phab.mercurial-scm.org/D2726 AFFECTED FILES mercurial/debugcommands.py tests/test-http-protocol.t CHANGE DETAILS diff --git a/tests/test-http-protocol.t b/tests/test-http-protocol.t --- a/tests/test-http-protocol.t +++ b/tests/test-http-protocol.t @@ -161,3 +161,69 @@ : 32 30 30 20 53 63 72 69 70 74 20 6f 75 74 70 75 |200 Script outpu| 0010: 74 20 66 6f 6c 6c 6f 77 73 0a 0a 04 7a 6c 69 62 |t follows...zlib| 0020: 78 |x| + + $ killdaemons.py + $ cd .. + +Test listkeys for listing namespaces + + $ hg init empty + $ hg -R empty serve -p $HGPORT -d --pid-file hg.pid + $ cat hg.pid > $DAEMON_PIDS + + $ hg --verbose debugwireproto http://$LOCALIP:$HGPORT << EOF + > command listkeys + > namespace namespaces + > EOF + s> sendall(*, 0): (glob) + s> GET /?cmd=capabilities HTTP/1.1\r\n + s> Accept-Encoding: identity\r\n + s> accept: application/mercurial-0.1\r\n + s> host: $LOCALIP:$HGPORT\r\n (glob) + s> user-agent: mercurial/proto-1.0 (Mercurial *)\r\n (glob) + s> \r\n + s> makefile('rb', None) + s> readline() -> 36: + s> HTTP/1.1 200 Script output follows\r\n + s> readline() -> 28: + s> Server: testing stub value\r\n + s> readline() -> *: (glob) + s> Date: $HTTP_DATE$\r\n + s> readline() -> 41: + s> Content-Type: application/mercurial-0.1\r\n + s> readline() -> 21: + s> Content-Length: *\r\n (glob) + s> readline() -> 2: + s> \r\n + s> read(*) -> *: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx compression=$BUNDLE2_COMPRESSIONS$ (glob) + sending listkeys command + s> sendall(*, 0): (glob) + s> GET /?cmd=listkeys HTTP/1.1\r\n + s> Accept-Encoding: identity\r\n + s> vary: X-HgArg-1,X-HgProto-1\r\n + s> x-hgarg-1: namespace=namespaces\r\n + s> x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$\r\n + s> accept: application/mercurial-0.1\r\n + s> host: $LOCALIP:$HGPORT\r\n (glob) + s> user-agent: mercurial/proto-1.0 (Mercurial *)\r\n (glob) + s> \r\n + s> makefile('rb', None) + s> readline() -> 36: + s> HTTP/1.1 200 Script output follows\r\n + s> readline() -> 28: + s> Server: testing stub value\r\n + s> readline() -> *: (glob) + s> Date: $HTTP_DATE$\r\n + s> readline() -> 41: + s> Content-Type: application/mercurial-0.1\r\n + s> readline() -> 20: + s> Content-Length: 30\r\n + s> readline() -> 2: + s> \r\n + s> read(30) -> 30: + s> bookmarks \n + s> namespaces\n + s> phases + response: bookmarks \nnamespaces\nphases + + $ killdaemons.py diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py --- a/mercurial/debugcommands.py +++ b/mercurial/debugcommands.py @@ -48,6 +48,7 @@ fileset, formatter, hg, +httppeer, localrepo, lock as lockmod, logcmdutil, @@ -2602,9 +2603,9 @@ ('', 'peer', '', _('construct a specific version of the peer')), ('', 'noreadstderr', False, _('do not read from stderr of the remote')), ] + cmdutil.remoteopts, -_('[REPO]'), +_('[PATH]'), optionalrepo=True) -def debugwireproto(ui, repo, **opts): +def debugwireproto(ui, repo, path=None, **opts): """send wire protocol commands to a server This command can be used to issue wire protocol commands to remote @@ -2740,12 +2741,19 @@ raise error.Abort(_('invalid value for --peer'), hint=_('valid values are "raw", "ssh1", and "ssh2"')) +if path and opts['localssh']: +raise error.Abort(_('cannot specify --localssh with an explicit ' +'path')) + if ui.interactive(): ui.write(_('(waiting for commands on stdin)\n')) blocks = list(_parsewirelangblocks(ui.fin)) proc = None +stdin = None +stdout = None +stderr = None if opts['localssh']: # We start the SSH server in its own process so there is process @@ -2793,22 +2801,61 @@ peer = sshpeer.makepeer(ui, url, proc, stdin, stdout, stderr, autoreadstderr=autoreadstderr) +elif path: +# We bypass hg.peer() so we can proxy the sockets. +# TODO consider not doing this because we skip +# ``hg.wirepeersetupfuncs`` and potentially other useful functionality. +u = util.url(path) +if u.scheme != 'http': +raise error.Abort(_('only http
D2726: debugcommands: support connecting to HTTP peers
indygreg updated this revision to Diff 6994. indygreg edited the summary of this revision. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D2726?vs=6977&id=6994 REVISION DETAIL https://phab.mercurial-scm.org/D2726 AFFECTED FILES mercurial/debugcommands.py tests/test-http-protocol.t CHANGE DETAILS diff --git a/tests/test-http-protocol.t b/tests/test-http-protocol.t --- a/tests/test-http-protocol.t +++ b/tests/test-http-protocol.t @@ -161,3 +161,69 @@ : 32 30 30 20 53 63 72 69 70 74 20 6f 75 74 70 75 |200 Script outpu| 0010: 74 20 66 6f 6c 6c 6f 77 73 0a 0a 04 7a 6c 69 62 |t follows...zlib| 0020: 78 |x| + + $ killdaemons.py + $ cd .. + +Test listkeys for listing namespaces + + $ hg init empty + $ hg -R empty serve -p $HGPORT -d --pid-file hg.pid + $ cat hg.pid > $DAEMON_PIDS + + $ hg --verbose debugwireproto http://$LOCALIP:$HGPORT << EOF + > command listkeys + > namespace namespaces + > EOF + s> sendall(*, 0): (glob) + s> GET /?cmd=capabilities HTTP/1.1\r\n + s> Accept-Encoding: identity\r\n + s> accept: application/mercurial-0.1\r\n + s> host: $LOCALIP:$HGPORT\r\n (glob) + s> user-agent: mercurial/proto-1.0 (Mercurial *)\r\n (glob) + s> \r\n + s> makefile('rb', None) + s> readline() -> 36: + s> HTTP/1.1 200 Script output follows\r\n + s> readline() -> 28: + s> Server: testing stub value\r\n + s> readline() -> *: (glob) + s> Date: $HTTP_DATE$\r\n + s> readline() -> 41: + s> Content-Type: application/mercurial-0.1\r\n + s> readline() -> 21: + s> Content-Length: *\r\n (glob) + s> readline() -> 2: + s> \r\n + s> read(*) -> *: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx compression=$BUNDLE2_COMPRESSIONS$ (glob) + sending listkeys command + s> sendall(*, 0): (glob) + s> GET /?cmd=listkeys HTTP/1.1\r\n + s> Accept-Encoding: identity\r\n + s> vary: X-HgArg-1,X-HgProto-1\r\n + s> x-hgarg-1: namespace=namespaces\r\n + s> x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$\r\n + s> accept: application/mercurial-0.1\r\n + s> host: $LOCALIP:$HGPORT\r\n (glob) + s> user-agent: mercurial/proto-1.0 (Mercurial *)\r\n (glob) + s> \r\n + s> makefile('rb', None) + s> readline() -> 36: + s> HTTP/1.1 200 Script output follows\r\n + s> readline() -> 28: + s> Server: testing stub value\r\n + s> readline() -> *: (glob) + s> Date: $HTTP_DATE$\r\n + s> readline() -> 41: + s> Content-Type: application/mercurial-0.1\r\n + s> readline() -> 20: + s> Content-Length: 30\r\n + s> readline() -> 2: + s> \r\n + s> read(30) -> 30: + s> bookmarks \n + s> namespaces\n + s> phases + response: bookmarks \nnamespaces\nphases + + $ killdaemons.py diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py --- a/mercurial/debugcommands.py +++ b/mercurial/debugcommands.py @@ -48,6 +48,7 @@ fileset, formatter, hg, +httppeer, localrepo, lock as lockmod, logcmdutil, @@ -2588,9 +2589,9 @@ ('', 'peer', '', _('construct a specific version of the peer')), ('', 'noreadstderr', False, _('do not read from stderr of the remote')), ] + cmdutil.remoteopts, -_('[REPO]'), +_('[PATH]'), optionalrepo=True) -def debugwireproto(ui, repo, **opts): +def debugwireproto(ui, repo, path=None, **opts): """send wire protocol commands to a server This command can be used to issue wire protocol commands to remote @@ -2726,12 +2727,19 @@ raise error.Abort(_('invalid value for --peer'), hint=_('valid values are "raw", "ssh1", and "ssh2"')) +if path and opts['localssh']: +raise error.Abort(_('cannot specify --localssh with an explicit ' +'path')) + if ui.interactive(): ui.write(_('(waiting for commands on stdin)\n')) blocks = list(_parsewirelangblocks(ui.fin)) proc = None +stdin = None +stdout = None +stderr = None if opts['localssh']: # We start the SSH server in its own process so there is process @@ -2779,22 +2787,61 @@ peer = sshpeer.makepeer(ui, url, proc, stdin, stdout, stderr, autoreadstderr=autoreadstderr) +elif path: +# We bypass hg.peer() so we can proxy the sockets. +# TODO consider not doing this because we skip +# ``hg.wirepeersetupfuncs`` and potentially other useful functionality. +u = util.url(path) +if u.scheme != 'http': +raise error.Abort(_('only http:// paths are currently supported')) + +url, authinfo = u.authinfo() +openerargs = {} + +
D2726: debugcommands: support connecting to HTTP peers
indygreg updated this revision to Diff 6977. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D2726?vs=6721&id=6977 REVISION DETAIL https://phab.mercurial-scm.org/D2726 AFFECTED FILES mercurial/debugcommands.py tests/test-http-protocol.t CHANGE DETAILS diff --git a/tests/test-http-protocol.t b/tests/test-http-protocol.t --- a/tests/test-http-protocol.t +++ b/tests/test-http-protocol.t @@ -161,3 +161,68 @@ : 32 30 30 20 53 63 72 69 70 74 20 6f 75 74 70 75 |200 Script outpu| 0010: 74 20 66 6f 6c 6c 6f 77 73 0a 0a 04 7a 6c 69 62 |t follows...zlib| 0020: 78 |x| + + $ killdaemons.py + $ cd .. + +Test listkeys for listing namespaces + + $ hg init empty + $ hg -R empty serve -p $HGPORT -d --pid-file hg.pid + $ cat hg.pid > $DAEMON_PIDS + $ hg --verbose debugwireproto http://$LOCALIP:$HGPORT << EOF + > command listkeys + > namespace namespaces + > EOF + s> sendall(*, 0): (glob) + s> GET /?cmd=capabilities HTTP/1.1\r\n + s> Accept-Encoding: identity\r\n + s> accept: application/mercurial-0.1\r\n + s> host: $LOCALIP:$HGPORT\r\n (glob) + s> user-agent: mercurial/proto-1.0 (Mercurial *)\r\n (glob) + s> \r\n + s> makefile('rb', None) + s> readline() -> 36: + s> HTTP/1.1 200 Script output follows\r\n + s> readline() -> *: (glob) + s> Server: *\r\n (glob) + s> readline() -> *: (glob) + s> Date: *\r\n (glob) + s> readline() -> 41: + s> Content-Type: application/mercurial-0.1\r\n + s> readline() -> 21: + s> Content-Length: *\r\n (glob) + s> readline() -> 2: + s> \r\n + s> read(*) -> *: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx compression=$BUNDLE2_COMPRESSIONS$ (glob) + sending listkeys command + s> sendall(*, 0): (glob) + s> GET /?cmd=listkeys HTTP/1.1\r\n + s> Accept-Encoding: identity\r\n + s> vary: X-HgArg-1,X-HgProto-1\r\n + s> x-hgarg-1: namespace=namespaces\r\n + s> x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$\r\n + s> accept: application/mercurial-0.1\r\n + s> host: $LOCALIP:$HGPORT\r\n (glob) + s> user-agent: mercurial/proto-1.0 (Mercurial *)\r\n (glob) + s> \r\n + s> makefile('rb', None) + s> readline() -> 36: + s> HTTP/1.1 200 Script output follows\r\n + s> readline() -> 36: + s> Server: *\r\n (glob) + s> readline() -> *: (glob) + s> Date: *\r\n (glob) + s> readline() -> 41: + s> Content-Type: application/mercurial-0.1\r\n + s> readline() -> 20: + s> Content-Length: 30\r\n + s> readline() -> 2: + s> \r\n + s> read(30) -> 30: + s> bookmarks \n + s> namespaces\n + s> phases + response: bookmarks \nnamespaces\nphases + + $ killdaemons.py diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py --- a/mercurial/debugcommands.py +++ b/mercurial/debugcommands.py @@ -48,6 +48,7 @@ fileset, formatter, hg, +httppeer, localrepo, lock as lockmod, logcmdutil, @@ -2588,9 +2589,9 @@ ('', 'peer', '', _('construct a specific version of the peer')), ('', 'noreadstderr', False, _('do not read from stderr of the remote')), ] + cmdutil.remoteopts, -_('[REPO]'), +_('[PATH]'), optionalrepo=True) -def debugwireproto(ui, repo, **opts): +def debugwireproto(ui, repo, path=None, **opts): """send wire protocol commands to a server This command can be used to issue wire protocol commands to remote @@ -2726,12 +2727,19 @@ raise error.Abort(_('invalid value for --peer'), hint=_('valid values are "raw", "ssh1", and "ssh2"')) +if path and opts['localssh']: +raise error.Abort(_('cannot specify --localssh with an explicit ' +'path')) + if ui.interactive(): ui.write(_('(waiting for commands on stdin)\n')) blocks = list(_parsewirelangblocks(ui.fin)) proc = None +stdin = None +stdout = None +stderr = None if opts['localssh']: # We start the SSH server in its own process so there is process @@ -2779,22 +2787,55 @@ peer = sshpeer.makepeer(ui, url, proc, stdin, stdout, stderr, autoreadstderr=autoreadstderr) +elif path: +# We bypass hg.peer() so we can proxy the sockets. +# TODO consider not doing this because we skip +# ``hg.wirepeersetupfuncs`` and potentially other useful functionality. +u = util.url(path) +if u.scheme != 'http': +raise error.Abort(_('only http:// paths are currently supported')) + +if opts['peer']: +raise error.Abort(_('--peer is not supported with HTTP peers')) + +url, authinfo = u.au
D2726: debugcommands: support connecting to HTTP peers
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY Now that we have the plumbing for logging socket activity, let's hook it up to `hg debugwireproto` so we can collect low-level activity on sockets. The new code is a bit incomplete. But it is better than nothing: `hg debugwireproto` is still heavily evolving. The added test demonstrates some interesting behavior. For example, we're calling socket.makefile() and doing I/O on that. TIL. We're also sending an "Accept-Encoding: identity" request header. (This is probably not necessary.) I don't plan on implementing too many HTTP protocol tests at this time because they are a bit verbose and the liberal use of ignoring variable length fields is annoying. Although, I may evolve `hg debugwireproto` to make the output less verbose to facilitate testing. I'm still working things out... REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D2726 AFFECTED FILES mercurial/debugcommands.py tests/test-http-protocol.t CHANGE DETAILS diff --git a/tests/test-http-protocol.t b/tests/test-http-protocol.t --- a/tests/test-http-protocol.t +++ b/tests/test-http-protocol.t @@ -161,3 +161,68 @@ : 32 30 30 20 53 63 72 69 70 74 20 6f 75 74 70 75 |200 Script outpu| 0010: 74 20 66 6f 6c 6c 6f 77 73 0a 0a 04 7a 6c 69 62 |t follows...zlib| 0020: 78 |x| + + $ killdaemons.py + $ cd .. + +Test listkeys for listing namespaces + + $ hg init empty + $ hg -R empty serve -p $HGPORT -d --pid-file hg.pid + $ cat hg.pid > $DAEMON_PIDS + $ hg --verbose debugwireproto http://$LOCALIP:$HGPORT << EOF + > command listkeys + > namespace namespaces + > EOF + s> sendall(*, 0): (glob) + s> GET /?cmd=capabilities HTTP/1.1\r\n + s> Accept-Encoding: identity\r\n + s> accept: application/mercurial-0.1\r\n + s> host: $LOCALIP:$HGPORT\r\n (glob) + s> user-agent: mercurial/proto-1.0 (Mercurial *)\r\n (glob) + s> \r\n + s> makefile('rb', None) + s> readline() -> 36: + s> HTTP/1.1 200 Script output follows\r\n + s> readline() -> *: (glob) + s> Server: *\r\n (glob) + s> readline() -> *: (glob) + s> Date: *\r\n (glob) + s> readline() -> 41: + s> Content-Type: application/mercurial-0.1\r\n + s> readline() -> 21: + s> Content-Length: *\r\n (glob) + s> readline() -> 2: + s> \r\n + s> read(*) -> *: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx compression=$BUNDLE2_COMPRESSIONS$ (glob) + sending listkeys command + s> sendall(*, 0): (glob) + s> GET /?cmd=listkeys HTTP/1.1\r\n + s> Accept-Encoding: identity\r\n + s> vary: X-HgArg-1,X-HgProto-1\r\n + s> x-hgarg-1: namespace=namespaces\r\n + s> x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$\r\n + s> accept: application/mercurial-0.1\r\n + s> host: $LOCALIP:$HGPORT\r\n (glob) + s> user-agent: mercurial/proto-1.0 (Mercurial *)\r\n (glob) + s> \r\n + s> makefile('rb', None) + s> readline() -> 36: + s> HTTP/1.1 200 Script output follows\r\n + s> readline() -> 36: + s> Server: *\r\n (glob) + s> readline() -> *: (glob) + s> Date: *\r\n (glob) + s> readline() -> 41: + s> Content-Type: application/mercurial-0.1\r\n + s> readline() -> 20: + s> Content-Length: 30\r\n + s> readline() -> 2: + s> \r\n + s> read(30) -> 30: + s> bookmarks \n + s> namespaces\n + s> phases + response: bookmarks \nnamespaces\nphases + + $ killdaemons.py diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py --- a/mercurial/debugcommands.py +++ b/mercurial/debugcommands.py @@ -47,6 +47,7 @@ fileset, formatter, hg, +httppeer, localrepo, lock as lockmod, logcmdutil, @@ -2571,9 +2572,9 @@ ('', 'peer', '', _('construct a specific version of the peer')), ('', 'noreadstderr', False, _('do not read from stderr of the remote')), ] + cmdutil.remoteopts, -_('[REPO]'), +_('[PATH]'), optionalrepo=True) -def debugwireproto(ui, repo, **opts): +def debugwireproto(ui, repo, path=None, **opts): """send wire protocol commands to a server This command can be used to issue wire protocol commands to remote @@ -2708,12 +2709,19 @@ raise error.Abort(_('invalid value for --peer'), hint=_('valid values are "raw", "ssh1", and "ssh2"')) +if path and opts['localssh']: +raise error.Abort(_('cannot specify --localssh with an explicit ' +'path')) + if ui.interactive(): ui.write(_('(waiting for commands on stdin)\n')) blocks = list(_parsewirelangblocks(ui.fin))