D2726: debugcommands: support connecting to HTTP peers

2018-03-19 Thread indygreg (Gregory Szorc)
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=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 

D2726: debugcommands: support connecting to HTTP peers

2018-03-13 Thread indygreg (Gregory Szorc)
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=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

2018-03-12 Thread indygreg (Gregory Szorc)
indygreg updated this revision to Diff 6977.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D2726?vs=6721=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 = 

D2726: debugcommands: support connecting to HTTP peers

2018-03-07 Thread indygreg (Gregory Szorc)
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))