D3177: wireproto: crude support for version 2 HTTP peer
This revision was automatically updated to reflect the committed changes. Closed by commit rHG61e405fb6372: wireproto: crude support for version 2 HTTP peer (authored by indygreg, committed by ). CHANGED PRIOR TO COMMIT https://phab.mercurial-scm.org/D3177?vs=7862=7894#toc REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3177?vs=7862=7894 REVISION DETAIL https://phab.mercurial-scm.org/D3177 AFFECTED FILES mercurial/debugcommands.py mercurial/httppeer.py tests/test-http-api-httpv2.t tests/test-http-protocol.t tests/wireprotohelpers.sh CHANGE DETAILS diff --git a/tests/wireprotohelpers.sh b/tests/wireprotohelpers.sh --- a/tests/wireprotohelpers.sh +++ b/tests/wireprotohelpers.sh @@ -5,6 +5,10 @@ hg --verbose debugwireproto --peer raw http://$LOCALIP:$HGPORT/ } +sendhttpv2peer() { + hg --verbose debugwireproto --peer http2 http://$LOCALIP:$HGPORT/ +} + cat > dummycommands.py << EOF from mercurial import ( wireprototypes, 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 @@ -179,7 +179,7 @@ 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> user-agent: Mercurial debugwireproto\r\n s> \r\n s> makefile('rb', None) s> HTTP/1.1 200 Script output follows\r\n @@ -197,7 +197,7 @@ 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> user-agent: Mercurial debugwireproto\r\n s> \r\n s> makefile('rb', None) s> HTTP/1.1 200 Script output follows\r\n diff --git a/tests/test-http-api-httpv2.t b/tests/test-http-api-httpv2.t --- a/tests/test-http-api-httpv2.t +++ b/tests/test-http-api-httpv2.t @@ -180,6 +180,36 @@ s> 0\r\n s> \r\n + $ sendhttpv2peer << EOF + > command customreadonly + > EOF + creating http peer for wire protocol version 2 + sending customreadonly command + s> POST /api/exp-http-v2-0001/ro/customreadonly HTTP/1.1\r\n + s> Accept-Encoding: identity\r\n + s> accept: application/mercurial-exp-framing-0003\r\n + s> content-type: application/mercurial-exp-framing-0003\r\n + s> content-length: 29\r\n + s> host: $LOCALIP:$HGPORT\r\n (glob) + s> user-agent: Mercurial debugwireproto\r\n + s> \r\n + s> \x15\x00\x00\x01\x00\x01\x01\x11\xa1DnameNcustomreadonly + s> makefile('rb', None) + s> HTTP/1.1 200 OK\r\n + s> Server: testing stub value\r\n + s> Date: $HTTP_DATE$\r\n + s> Content-Type: application/mercurial-exp-framing-0003\r\n + s> Transfer-Encoding: chunked\r\n + s> \r\n + s> 25\r\n + s> \x1d\x00\x00\x01\x00\x02\x01B + s> customreadonly bytes response + s> \r\n + received frame(size=29; request=1; stream=2; streamflags=stream-begin; type=bytes-response; flags=eos) + s> 0\r\n + s> \r\n + response: [b'customreadonly bytes response'] + Request to read-write command fails because server is read-only by default GET to read-write request yields 405 diff --git a/mercurial/httppeer.py b/mercurial/httppeer.py --- a/mercurial/httppeer.py +++ b/mercurial/httppeer.py @@ -16,6 +16,9 @@ import tempfile from .i18n import _ +from .thirdparty import ( +cbor, +) from . import ( bundle2, error, @@ -25,6 +28,8 @@ url as urlmod, util, wireproto, +wireprotoframing, +wireprotoserver, ) httplib = util.httplib @@ -467,6 +472,95 @@ def _abort(self, exception): raise exception +# TODO implement interface for version 2 peers +class httpv2peer(object): +def __init__(self, ui, repourl, opener): +self.ui = ui + +if repourl.endswith('/'): +repourl = repourl[:-1] + +self.url = repourl +self._opener = opener +# This is an its own attribute to facilitate extensions overriding +# the default type. +self._requestbuilder = urlreq.request + +def close(self): +pass + +# TODO require to be part of a batched primitive, use futures. +def _call(self, name, **args): +"""Call a wire protocol command with arguments.""" + +# TODO permissions should come from capabilities results. +permission = wireproto.commandsv2[name].permission +if permission not in ('push', 'pull'): +raise error.ProgrammingError('unknown permission type: %s' % + permission) + +permission = { +'push': 'rw', +'pull': 'ro', +}[permission] + +url = '%s/api/%s/%s/%s' % (self.url, wireprotoserver.HTTPV2, permission, + name) + +
D3177: wireproto: crude support for version 2 HTTP peer
yuja added inline comments. INLINE COMMENTS > debugcommands.py:2962 > +if value.startswith('eval:'): > +value = stringutil.evalpython(value[5:]) > +else: My patch broke this, so fixed in flight. :) REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3177 To: indygreg, #hg-reviewers, yuja Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: D3177: wireproto: crude support for version 2 HTTP peer
On Sat, Apr 07, 2018 at 05:53:50 +, indygreg (Gregory Szorc) wrote: > indygreg created this revision. > Herald added a subscriber: mercurial-devel. > Herald added a reviewer: hg-reviewers. > > REVISION SUMMARY > As part of implementing the server-side bits of the wire protocol > command handlers for version 2, we want a way to easily test those This seems a bit confusing... is this wireproto2 or HTTP2? (There are places in this diff with similar ambiguity.) Jeff. > commands. Currently, we use the "httprequest" action of `hg > debugwireproto`. But this requires explicitly specifying the HTTP > request headers, low-level frame details, and the data structure > to encode with CBOR. That's a lot of boilerplate and a lot of it can > change as the wire protocol evolves. > > `hg debugwireproto` has a mechanism to issue commands via the peer > interface. That is *much* easier to use and we prefer to test with > that going forward. > > This commit implements enough parts of the peer API to send basic > requests via the HTTP version 2 transport. > > The peer code is super hacky. Again, the goal is to facilitate > server testing, not robustly implement a client. The client code > will receive love at a later time. > > REPOSITORY > rHG Mercurial > > REVISION DETAIL > https://phab.mercurial-scm.org/D3177 > > AFFECTED FILES > mercurial/debugcommands.py > mercurial/httppeer.py > tests/test-http-api-httpv2.t > tests/test-http-protocol.t > tests/wireprotohelpers.sh > > CHANGE DETAILS > > diff --git a/tests/wireprotohelpers.sh b/tests/wireprotohelpers.sh > --- a/tests/wireprotohelpers.sh > +++ b/tests/wireprotohelpers.sh > @@ -5,6 +5,10 @@ >hg --verbose debugwireproto --peer raw http://$LOCALIP:$HGPORT/ > } > > +sendhttpv2peer() { > + hg --verbose debugwireproto --peer http2 http://$LOCALIP:$HGPORT/ -- Only two things are infinite, the universe and human stupidity, and I'm not sure about the former. - Albert Einstein ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3177: wireproto: crude support for version 2 HTTP peer
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY As part of implementing the server-side bits of the wire protocol command handlers for version 2, we want a way to easily test those commands. Currently, we use the "httprequest" action of `hg debugwireproto`. But this requires explicitly specifying the HTTP request headers, low-level frame details, and the data structure to encode with CBOR. That's a lot of boilerplate and a lot of it can change as the wire protocol evolves. `hg debugwireproto` has a mechanism to issue commands via the peer interface. That is *much* easier to use and we prefer to test with that going forward. This commit implements enough parts of the peer API to send basic requests via the HTTP version 2 transport. The peer code is super hacky. Again, the goal is to facilitate server testing, not robustly implement a client. The client code will receive love at a later time. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3177 AFFECTED FILES mercurial/debugcommands.py mercurial/httppeer.py tests/test-http-api-httpv2.t tests/test-http-protocol.t tests/wireprotohelpers.sh CHANGE DETAILS diff --git a/tests/wireprotohelpers.sh b/tests/wireprotohelpers.sh --- a/tests/wireprotohelpers.sh +++ b/tests/wireprotohelpers.sh @@ -5,6 +5,10 @@ hg --verbose debugwireproto --peer raw http://$LOCALIP:$HGPORT/ } +sendhttpv2peer() { + hg --verbose debugwireproto --peer http2 http://$LOCALIP:$HGPORT/ +} + cat > dummycommands.py << EOF from mercurial import ( wireprototypes, 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 @@ -179,7 +179,7 @@ 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> user-agent: Mercurial debugwireproto\r\n s> \r\n s> makefile('rb', None) s> HTTP/1.1 200 Script output follows\r\n @@ -197,7 +197,7 @@ 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> user-agent: Mercurial debugwireproto\r\n s> \r\n s> makefile('rb', None) s> HTTP/1.1 200 Script output follows\r\n diff --git a/tests/test-http-api-httpv2.t b/tests/test-http-api-httpv2.t --- a/tests/test-http-api-httpv2.t +++ b/tests/test-http-api-httpv2.t @@ -180,6 +180,36 @@ s> 0\r\n s> \r\n + $ sendhttpv2peer << EOF + > command customreadonly + > EOF + creating http peer for wire protocol version 2 + sending customreadonly command + s> POST /api/exp-http-v2-0001/ro/customreadonly HTTP/1.1\r\n + s> Accept-Encoding: identity\r\n + s> accept: application/mercurial-exp-framing-0003\r\n + s> content-type: application/mercurial-exp-framing-0003\r\n + s> content-length: 29\r\n + s> host: $LOCALIP:$HGPORT\r\n (glob) + s> user-agent: Mercurial debugwireproto\r\n + s> \r\n + s> \x15\x00\x00\x01\x00\x01\x01\x11\xa1DnameNcustomreadonly + s> makefile('rb', None) + s> HTTP/1.1 200 OK\r\n + s> Server: testing stub value\r\n + s> Date: $HTTP_DATE$\r\n + s> Content-Type: application/mercurial-exp-framing-0003\r\n + s> Transfer-Encoding: chunked\r\n + s> \r\n + s> 25\r\n + s> \x1d\x00\x00\x01\x00\x02\x01B + s> customreadonly bytes response + s> \r\n + received frame(size=29; request=1; stream=2; streamflags=stream-begin; type=bytes-response; flags=eos) + s> 0\r\n + s> \r\n + response: [b'customreadonly bytes response'] + Request to read-write command fails because server is read-only by default GET to read-write request yields 405 diff --git a/mercurial/httppeer.py b/mercurial/httppeer.py --- a/mercurial/httppeer.py +++ b/mercurial/httppeer.py @@ -16,6 +16,9 @@ import tempfile from .i18n import _ +from .thirdparty import ( +cbor, +) from . import ( bundle2, error, @@ -25,6 +28,8 @@ url as urlmod, util, wireproto, +wireprotoframing, +wireprotoserver, ) httplib = util.httplib @@ -467,6 +472,95 @@ def _abort(self, exception): raise exception +# TODO implement interface for version 2 peers +class httpv2peer(object): +def __init__(self, ui, repourl, opener): +self.ui = ui + +if repourl.endswith('/'): +repourl = repourl[:-1] + +self.url = repourl +self._opener = opener +# This is an its own attribute to facilitate extensions overriding +# the default type. +self._requestbuilder = urlreq.request + +def close(self): +pass + +# TODO require to be part of a