D2080: wireprotoserver: split ssh protocol handler and server

2018-02-12 Thread indygreg (Gregory Szorc)
This revision was automatically updated to reflect the committed changes.
Closed by commit rHGbf676267f64f: wireprotoserver: split ssh protocol handler 
and server (authored by indygreg, committed by ).

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D2080?vs=5343=5526

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

AFFECTED FILES
  mercurial/wireprotoserver.py
  tests/sshprotoext.py
  tests/test-sshserver.py

CHANGE DETAILS

diff --git a/tests/test-sshserver.py b/tests/test-sshserver.py
--- a/tests/test-sshserver.py
+++ b/tests/test-sshserver.py
@@ -24,7 +24,7 @@
 def assertparse(self, cmd, input, expected):
 server = mockserver(input)
 _func, spec = wireproto.commands[cmd]
-self.assertEqual(server.getargs(spec), expected)
+self.assertEqual(server._proto.getargs(spec), expected)
 
 def mockserver(inbytes):
 ui = mockui(inbytes)
diff --git a/tests/sshprotoext.py b/tests/sshprotoext.py
--- a/tests/sshprotoext.py
+++ b/tests/sshprotoext.py
@@ -48,7 +48,7 @@
 wireprotoserver._sshv1respondbytes(self._fout, b'')
 l = self._fin.readline()
 assert l == b'between\n'
-rsp = wireproto.dispatch(self._repo, self, b'between')
+rsp = wireproto.dispatch(self._repo, self._proto, b'between')
 wireprotoserver._sshv1respondbytes(self._fout, rsp)
 
 super(prehelloserver, self).serve_forever()
@@ -73,7 +73,7 @@
 
 # Send the upgrade response.
 self._fout.write(b'upgraded %s %s\n' % (token, name))
-servercaps = wireproto.capabilities(self._repo, self)
+servercaps = wireproto.capabilities(self._repo, self._proto)
 rsp = b'capabilities: %s' % servercaps
 self._fout.write(b'%d\n' % len(rsp))
 self._fout.write(rsp)
diff --git a/mercurial/wireprotoserver.py b/mercurial/wireprotoserver.py
--- a/mercurial/wireprotoserver.py
+++ b/mercurial/wireprotoserver.py
@@ -354,19 +354,12 @@
 fout.write(b'\n')
 fout.flush()
 
-class sshserver(baseprotocolhandler):
-def __init__(self, ui, repo):
+class sshv1protocolhandler(baseprotocolhandler):
+"""Handler for requests services via version 1 of SSH protocol."""
+def __init__(self, ui, fin, fout):
 self._ui = ui
-self._repo = repo
-self._fin = ui.fin
-self._fout = ui.fout
-
-hook.redirect(True)
-ui.fout = repo.ui.fout = ui.ferr
-
-# Prevent insertion/deletion of CRs
-util.setbinary(self._fin)
-util.setbinary(self._fout)
+self._fin = fin
+self._fout = fout
 
 @property
 def name(self):
@@ -403,15 +396,35 @@
 def redirect(self):
 pass
 
+def _client(self):
+client = encoding.environ.get('SSH_CLIENT', '').split(' ', 1)[0]
+return 'remote:ssh:' + client
+
+class sshserver(object):
+def __init__(self, ui, repo):
+self._ui = ui
+self._repo = repo
+self._fin = ui.fin
+self._fout = ui.fout
+
+hook.redirect(True)
+ui.fout = repo.ui.fout = ui.ferr
+
+# Prevent insertion/deletion of CRs
+util.setbinary(self._fin)
+util.setbinary(self._fout)
+
+self._proto = sshv1protocolhandler(self._ui, self._fin, self._fout)
+
 def serve_forever(self):
 while self.serve_one():
 pass
 sys.exit(0)
 
 def serve_one(self):
 cmd = self._fin.readline()[:-1]
-if cmd and wireproto.commands.commandavailable(cmd, self):
-rsp = wireproto.dispatch(self._repo, self, cmd)
+if cmd and wireproto.commands.commandavailable(cmd, self._proto):
+rsp = wireproto.dispatch(self._repo, self._proto, cmd)
 
 if isinstance(rsp, bytes):
 _sshv1respondbytes(self._fout, rsp)
@@ -432,7 +445,3 @@
 elif cmd:
 _sshv1respondbytes(self._fout, b'')
 return cmd != ''
-
-def _client(self):
-client = encoding.environ.get('SSH_CLIENT', '').split(' ', 1)[0]
-return 'remote:ssh:' + client



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


D2080: wireprotoserver: split ssh protocol handler and server

2018-02-07 Thread indygreg (Gregory Szorc)
indygreg updated this revision to Diff 5332.
indygreg edited the summary of this revision.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D2080?vs=5314=5332

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

AFFECTED FILES
  mercurial/wireprotoserver.py
  tests/sshprotoext.py
  tests/test-sshserver.py

CHANGE DETAILS

diff --git a/tests/test-sshserver.py b/tests/test-sshserver.py
--- a/tests/test-sshserver.py
+++ b/tests/test-sshserver.py
@@ -24,7 +24,7 @@
 def assertparse(self, cmd, input, expected):
 server = mockserver(input)
 _func, spec = wireproto.commands[cmd]
-self.assertEqual(server.getargs(spec), expected)
+self.assertEqual(server._proto.getargs(spec), expected)
 
 def mockserver(inbytes):
 ui = mockui(inbytes)
diff --git a/tests/sshprotoext.py b/tests/sshprotoext.py
--- a/tests/sshprotoext.py
+++ b/tests/sshprotoext.py
@@ -48,7 +48,7 @@
 wireprotoserver._sshv1respondbytes(self._fout, b'')
 l = self._fin.readline()
 assert l == b'between\n'
-rsp = wireproto.dispatch(self._repo, self, b'between')
+rsp = wireproto.dispatch(self._repo, self._proto, b'between')
 wireprotoserver._sshv1respondbytes(self._fout, rsp)
 
 super(prehelloserver, self).serve_forever()
@@ -73,7 +73,7 @@
 
 # Send the upgrade response.
 self._fout.write(b'upgraded %s %s\n' % (token, name))
-servercaps = wireproto.capabilities(self._repo, self)
+servercaps = wireproto.capabilities(self._repo, self._proto)
 rsp = b'capabilities: %s' % servercaps
 self._fout.write(b'%d\n' % len(rsp))
 self._fout.write(rsp)
diff --git a/mercurial/wireprotoserver.py b/mercurial/wireprotoserver.py
--- a/mercurial/wireprotoserver.py
+++ b/mercurial/wireprotoserver.py
@@ -354,19 +354,12 @@
 fout.write(b'\n')
 fout.flush()
 
-class sshserver(baseprotocolhandler):
-def __init__(self, ui, repo):
+class sshv1protocolhandler(baseprotocolhandler):
+"""Handler for requests services via version 1 of SSH protocol."""
+def __init__(self, ui, fin, fout):
 self._ui = ui
-self._repo = repo
-self._fin = ui.fin
-self._fout = ui.fout
-
-hook.redirect(True)
-ui.fout = repo.ui.fout = ui.ferr
-
-# Prevent insertion/deletion of CRs
-util.setbinary(self._fin)
-util.setbinary(self._fout)
+self._fin = fin
+self._fout = fout
 
 @property
 def name(self):
@@ -403,15 +396,35 @@
 def redirect(self):
 pass
 
+def _client(self):
+client = encoding.environ.get('SSH_CLIENT', '').split(' ', 1)[0]
+return 'remote:ssh:' + client
+
+class sshserver(object):
+def __init__(self, ui, repo):
+self._ui = ui
+self._repo = repo
+self._fin = ui.fin
+self._fout = ui.fout
+
+hook.redirect(True)
+ui.fout = repo.ui.fout = ui.ferr
+
+# Prevent insertion/deletion of CRs
+util.setbinary(self._fin)
+util.setbinary(self._fout)
+
+self._proto = sshv1protocolhandler(self._ui, self._fin, self._fout)
+
 def serve_forever(self):
 while self.serve_one():
 pass
 sys.exit(0)
 
 def serve_one(self):
 cmd = self._fin.readline()[:-1]
-if cmd and wireproto.commands.commandavailable(cmd, self):
-rsp = wireproto.dispatch(self._repo, self, cmd)
+if cmd and wireproto.commands.commandavailable(cmd, self._proto):
+rsp = wireproto.dispatch(self._repo, self._proto, cmd)
 
 if isinstance(rsp, bytes):
 _sshv1respondbytes(self._fout, rsp)
@@ -432,7 +445,3 @@
 elif cmd:
 _sshv1respondbytes(self._fout, b'')
 return cmd != ''
-
-def _client(self):
-client = encoding.environ.get('SSH_CLIENT', '').split(' ', 1)[0]
-return 'remote:ssh:' + client



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


D2080: wireprotoserver: split ssh protocol handler and server

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

REVISION SUMMARY
  We want to formalize the interface for protocol handlers. Today,
  server functionality (which is domain specific) is interleaved
  with protocol handling functionality (which conforms to a generic
  interface) in the sshserver class.
  
  This commit splits the ssh protocol handling code out of the
  sshserver class.
  
  The state of the new code isn't great in terms of purity: there
  are still some private attribute accesses from sshserver into
  sshprotocolhandler that shouldn't be there. This will likely
  require some interface changes to address. I'm not yet sure how
  to reconcile things. But this split seems strictly better in
  terms of isolating the wire protocol interface from the rest of
  the code.

REPOSITORY
  rHG Mercurial

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

AFFECTED FILES
  mercurial/wireprotoserver.py
  tests/sshprotoext.py
  tests/test-sshserver.py

CHANGE DETAILS

diff --git a/tests/test-sshserver.py b/tests/test-sshserver.py
--- a/tests/test-sshserver.py
+++ b/tests/test-sshserver.py
@@ -24,7 +24,7 @@
 def assertparse(self, cmd, input, expected):
 server = mockserver(input)
 _func, spec = wireproto.commands[cmd]
-self.assertEqual(server.getargs(spec), expected)
+self.assertEqual(server._proto.getargs(spec), expected)
 
 def mockserver(inbytes):
 ui = mockui(inbytes)
diff --git a/tests/sshprotoext.py b/tests/sshprotoext.py
--- a/tests/sshprotoext.py
+++ b/tests/sshprotoext.py
@@ -45,11 +45,11 @@
 l = self._fin.readline()
 assert l == b'hello\n'
 # Respond to unknown commands with an empty reply.
-self._sendresponse(b'')
+self._proto._sendresponse(b'')
 l = self._fin.readline()
 assert l == b'between\n'
-rsp = wireproto.dispatch(self._repo, self, b'between')
-self._handlers[rsp.__class__](self, rsp)
+rsp = wireproto.dispatch(self._repo, self._proto, b'between')
+self._proto._handlers[rsp.__class__](self._proto, rsp)
 
 super(prehelloserver, self).serve_forever()
 
@@ -73,7 +73,7 @@
 
 # Send the upgrade response.
 self._fout.write(b'upgraded %s %s\n' % (token, name))
-servercaps = wireproto.capabilities(self._repo, self)
+servercaps = wireproto.capabilities(self._repo, self._proto)
 rsp = b'capabilities: %s' % servercaps
 self._fout.write(b'%d\n' % len(rsp))
 self._fout.write(rsp)
diff --git a/mercurial/wireprotoserver.py b/mercurial/wireprotoserver.py
--- a/mercurial/wireprotoserver.py
+++ b/mercurial/wireprotoserver.py
@@ -336,19 +336,11 @@
 
 return ''
 
-class sshserver(baseprotocolhandler):
-def __init__(self, ui, repo):
+class sshprotocolhandler(baseprotocolhandler):
+def __init__(self, ui, fin, fout):
 self._ui = ui
-self._repo = repo
-self._fin = ui.fin
-self._fout = ui.fout
-
-hook.redirect(True)
-ui.fout = repo.ui.fout = ui.ferr
-
-# Prevent insertion/deletion of CRs
-util.setbinary(self._fin)
-util.setbinary(self._fout)
+self._fin = fin
+self._fout = fout
 
 @property
 def name(self):
@@ -409,11 +401,6 @@
 self._fout.write('\n')
 self._fout.flush()
 
-def serve_forever(self):
-while self.serve_one():
-pass
-sys.exit(0)
-
 _handlers = {
 str: _sendresponse,
 wireproto.streamres: _sendstream,
@@ -423,15 +410,38 @@
 wireproto.ooberror: _sendooberror,
 }
 
-def serve_one(self):
-cmd = self._fin.readline()[:-1]
-if cmd and wireproto.commands.commandavailable(cmd, self):
-rsp = wireproto.dispatch(self._repo, self, cmd)
-self._handlers[rsp.__class__](self, rsp)
-elif cmd:
-self._sendresponse("")
-return cmd != ''
-
 def _client(self):
 client = encoding.environ.get('SSH_CLIENT', '').split(' ', 1)[0]
 return 'remote:ssh:' + client
+
+class sshserver(object):
+def __init__(self, ui, repo):
+self._ui = ui
+self._repo = repo
+self._fin = ui.fin
+self._fout = ui.fout
+
+hook.redirect(True)
+ui.fout = repo.ui.fout = ui.ferr
+
+# Prevent insertion/deletion of CRs
+util.setbinary(self._fin)
+util.setbinary(self._fout)
+
+self._proto = sshprotocolhandler(self._ui, self._fin, self._fout)
+
+def serve_forever(self):
+while self.serve_one():
+pass
+sys.exit(0)
+
+def serve_one(self):
+# TODO improve boundary between transport layer and protocol handler.
+cmd = self._fin.readline()[:-1]
+if cmd and wireproto.commands.commandavailable(cmd, self._proto):
+rsp = wireproto.dispatch(self._repo, self._proto, cmd)
+