D3237: httppeer: perform capabilities request in makepeer()

indygreg (Gregory Szorc) phabricator at mercurial-scm.org
Wed Apr 11 13:01:43 EDT 2018


This revision was automatically updated to reflect the committed changes.
Closed by commit rHG8b8a845c85fc: httppeer: perform capabilities request in makepeer() (authored by indygreg, committed by ).

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D3237?vs=7955&id=7998

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

AFFECTED FILES
  mercurial/debugcommands.py
  mercurial/httppeer.py
  tests/test-check-interfaces.py

CHANGE DETAILS

diff --git a/tests/test-check-interfaces.py b/tests/test-check-interfaces.py
--- a/tests/test-check-interfaces.py
+++ b/tests/test-check-interfaces.py
@@ -67,10 +67,11 @@
 class dummyopener(object):
     handlers = []
 
-# Facilitates testing sshpeer without requiring an SSH server.
+# Facilitates testing sshpeer without requiring a server.
 class badpeer(httppeer.httppeer):
     def __init__(self):
-        super(badpeer, self).__init__(None, None, None, dummyopener(), None)
+        super(badpeer, self).__init__(None, None, None, dummyopener(), None,
+                                      None)
         self.badattribute = True
 
     def badmethod(self):
@@ -89,7 +90,7 @@
 
     ziverify.verifyClass(repository.ipeerbaselegacycommands,
                          httppeer.httppeer)
-    checkzobject(httppeer.httppeer(None, None, None, dummyopener(), None))
+    checkzobject(httppeer.httppeer(None, None, None, dummyopener(), None, None))
 
     ziverify.verifyClass(repository.ipeerbase,
                          localrepo.localpeer)
diff --git a/mercurial/httppeer.py b/mercurial/httppeer.py
--- a/mercurial/httppeer.py
+++ b/mercurial/httppeer.py
@@ -366,11 +366,11 @@
     return respurl, resp
 
 class httppeer(wireproto.wirepeer):
-    def __init__(self, ui, path, url, opener, requestbuilder):
+    def __init__(self, ui, path, url, opener, requestbuilder, caps):
         self.ui = ui
         self._path = path
         self._url = url
-        self._caps = None
+        self._caps = caps
         self._urlopener = opener
         self._requestbuilder = requestbuilder
 
@@ -401,18 +401,12 @@
     # Begin of ipeercommands interface.
 
     def capabilities(self):
-        # self._fetchcaps() should have been called as part of peer
-        # handshake. So self._caps should always be set.
-        assert self._caps is not None
         return self._caps
 
     # End of ipeercommands interface.
 
     # look up capabilities only when needed
 
-    def _fetchcaps(self):
-        self._caps = set(self._call('capabilities').split())
-
     def _callstream(self, cmd, _compressible=False, **args):
         args = pycompat.byteskwargs(args)
 
@@ -603,6 +597,29 @@
 
         return results
 
+def performhandshake(ui, url, opener, requestbuilder):
+    # The handshake is a request to the capabilities command.
+
+    caps = None
+    def capable(x):
+        raise error.ProgrammingError('should not be called')
+
+    req, requrl, qs = makev1commandrequest(ui, requestbuilder, caps,
+                                           capable, url, 'capabilities',
+                                           {})
+
+    resp = sendrequest(ui, opener, req)
+
+    respurl, resp = parsev1commandresponse(ui, url, requrl, qs, resp,
+                                           compressible=False)
+
+    try:
+        rawcaps = resp.read()
+    finally:
+        resp.close()
+
+    return respurl, set(rawcaps.split())
+
 def makepeer(ui, path, requestbuilder=urlreq.request):
     """Construct an appropriate HTTP peer instance.
 
@@ -620,7 +637,9 @@
 
     opener = urlmod.opener(ui, authinfo)
 
-    return httppeer(ui, path, url, opener, requestbuilder)
+    respurl, caps = performhandshake(ui, url, opener, requestbuilder)
+
+    return httppeer(ui, path, respurl, opener, requestbuilder, caps)
 
 def instance(ui, path, create):
     if create:
@@ -631,7 +650,6 @@
                                 'is not installed'))
 
         inst = makepeer(ui, path)
-        inst._fetchcaps()
 
         return inst
     except error.RepoError as httpexception:
diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py
--- a/mercurial/debugcommands.py
+++ b/mercurial/debugcommands.py
@@ -2915,9 +2915,12 @@
             raise error.Abort(_('--peer %s not supported with HTTP peers') %
                               opts['peer'])
         else:
+            url, caps = httppeer.performhandshake(ui, url, opener,
+                                                  httppeer.urlreq.request)
+
             peer = httppeer.httppeer(ui, path, url, opener,
-                                     requestbuilder=httppeer.urlreq.request)
-            peer._fetchcaps()
+                                     httppeer.urlreq.request,
+                                     caps)
 
         # We /could/ populate stdin/stdout with sock.makefile()...
     else:



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


More information about the Mercurial-devel mailing list