##// END OF EJS Templates
wireprotov2: client support for advertising redirect targets...
Gregory Szorc -
r40060:86b22a4c default
parent child Browse files
Show More
@@ -508,7 +508,8 b' class httppeer(wireprotov1peer.wirepeer)'
508 def _abort(self, exception):
508 def _abort(self, exception):
509 raise exception
509 raise exception
510
510
511 def sendv2request(ui, opener, requestbuilder, apiurl, permission, requests):
511 def sendv2request(ui, opener, requestbuilder, apiurl, permission, requests,
512 redirect):
512 reactor = wireprotoframing.clientreactor(hasmultiplesend=False,
513 reactor = wireprotoframing.clientreactor(hasmultiplesend=False,
513 buffersends=True)
514 buffersends=True)
514
515
@@ -525,7 +526,8 b' def sendv2request(ui, opener, requestbui'
525 for command, args, f in requests:
526 for command, args, f in requests:
526 ui.debug('sending command %s: %s\n' % (
527 ui.debug('sending command %s: %s\n' % (
527 command, stringutil.pprint(args, indent=2)))
528 command, stringutil.pprint(args, indent=2)))
528 assert not list(handler.callcommand(command, args, f))
529 assert not list(handler.callcommand(command, args, f,
530 redirect=redirect))
529
531
530 # TODO stream this.
532 # TODO stream this.
531 body = b''.join(map(bytes, handler.flushcommands()))
533 body = b''.join(map(bytes, handler.flushcommands()))
@@ -567,12 +569,14 b' class queuedcommandfuture(pycompat.futur'
567
569
568 @interfaceutil.implementer(repository.ipeercommandexecutor)
570 @interfaceutil.implementer(repository.ipeercommandexecutor)
569 class httpv2executor(object):
571 class httpv2executor(object):
570 def __init__(self, ui, opener, requestbuilder, apiurl, descriptor):
572 def __init__(self, ui, opener, requestbuilder, apiurl, descriptor,
573 redirect):
571 self._ui = ui
574 self._ui = ui
572 self._opener = opener
575 self._opener = opener
573 self._requestbuilder = requestbuilder
576 self._requestbuilder = requestbuilder
574 self._apiurl = apiurl
577 self._apiurl = apiurl
575 self._descriptor = descriptor
578 self._descriptor = descriptor
579 self._redirect = redirect
576 self._sent = False
580 self._sent = False
577 self._closed = False
581 self._closed = False
578 self._neededpermissions = set()
582 self._neededpermissions = set()
@@ -672,7 +676,7 b' class httpv2executor(object):'
672
676
673 handler, resp = sendv2request(
677 handler, resp = sendv2request(
674 self._ui, self._opener, self._requestbuilder, self._apiurl,
678 self._ui, self._opener, self._requestbuilder, self._apiurl,
675 permission, calls)
679 permission, calls, self._redirect)
676
680
677 # TODO we probably want to validate the HTTP code, media type, etc.
681 # TODO we probably want to validate the HTTP code, media type, etc.
678
682
@@ -734,6 +738,8 b' class httpv2peer(object):'
734 self._requestbuilder = requestbuilder
738 self._requestbuilder = requestbuilder
735 self._descriptor = apidescriptor
739 self._descriptor = apidescriptor
736
740
741 self._redirect = wireprotov2peer.supportedredirects(ui, apidescriptor)
742
737 # Start of ipeerconnection.
743 # Start of ipeerconnection.
738
744
739 def url(self):
745 def url(self):
@@ -791,7 +797,7 b' class httpv2peer(object):'
791
797
792 def commandexecutor(self):
798 def commandexecutor(self):
793 return httpv2executor(self.ui, self._opener, self._requestbuilder,
799 return httpv2executor(self.ui, self._opener, self._requestbuilder,
794 self._apiurl, self._descriptor)
800 self._apiurl, self._descriptor, self._redirect)
795
801
796 # Registry of API service names to metadata about peers that handle it.
802 # Registry of API service names to metadata about peers that handle it.
797 #
803 #
@@ -280,7 +280,8 b' def readframe(fh):'
280 payload)
280 payload)
281
281
282 def createcommandframes(stream, requestid, cmd, args, datafh=None,
282 def createcommandframes(stream, requestid, cmd, args, datafh=None,
283 maxframesize=DEFAULT_MAX_FRAME_SIZE):
283 maxframesize=DEFAULT_MAX_FRAME_SIZE,
284 redirect=None):
284 """Create frames necessary to transmit a request to run a command.
285 """Create frames necessary to transmit a request to run a command.
285
286
286 This is a generator of bytearrays. Each item represents a frame
287 This is a generator of bytearrays. Each item represents a frame
@@ -290,6 +291,9 b' def createcommandframes(stream, requesti'
290 if args:
291 if args:
291 data[b'args'] = args
292 data[b'args'] = args
292
293
294 if redirect:
295 data[b'redirect'] = redirect
296
293 data = b''.join(cborutil.streamencode(data))
297 data = b''.join(cborutil.streamencode(data))
294
298
295 offset = 0
299 offset = 0
@@ -1135,11 +1139,12 b' class serverreactor(object):'
1135 class commandrequest(object):
1139 class commandrequest(object):
1136 """Represents a request to run a command."""
1140 """Represents a request to run a command."""
1137
1141
1138 def __init__(self, requestid, name, args, datafh=None):
1142 def __init__(self, requestid, name, args, datafh=None, redirect=None):
1139 self.requestid = requestid
1143 self.requestid = requestid
1140 self.name = name
1144 self.name = name
1141 self.args = args
1145 self.args = args
1142 self.datafh = datafh
1146 self.datafh = datafh
1147 self.redirect = redirect
1143 self.state = 'pending'
1148 self.state = 'pending'
1144
1149
1145 class clientreactor(object):
1150 class clientreactor(object):
@@ -1178,7 +1183,7 b' class clientreactor(object):'
1178 self._activerequests = {}
1183 self._activerequests = {}
1179 self._incomingstreams = {}
1184 self._incomingstreams = {}
1180
1185
1181 def callcommand(self, name, args, datafh=None):
1186 def callcommand(self, name, args, datafh=None, redirect=None):
1182 """Request that a command be executed.
1187 """Request that a command be executed.
1183
1188
1184 Receives the command name, a dict of arguments to pass to the command,
1189 Receives the command name, a dict of arguments to pass to the command,
@@ -1192,7 +1197,8 b' class clientreactor(object):'
1192 requestid = self._nextrequestid
1197 requestid = self._nextrequestid
1193 self._nextrequestid += 2
1198 self._nextrequestid += 2
1194
1199
1195 request = commandrequest(requestid, name, args, datafh=datafh)
1200 request = commandrequest(requestid, name, args, datafh=datafh,
1201 redirect=redirect)
1196
1202
1197 if self._buffersends:
1203 if self._buffersends:
1198 self._pendingrequests.append(request)
1204 self._pendingrequests.append(request)
@@ -1256,7 +1262,8 b' class clientreactor(object):'
1256 request.requestid,
1262 request.requestid,
1257 request.name,
1263 request.name,
1258 request.args,
1264 request.args,
1259 request.datafh)
1265 datafh=request.datafh,
1266 redirect=request.redirect)
1260
1267
1261 for frame in res:
1268 for frame in res:
1262 yield frame
1269 yield frame
@@ -13,6 +13,7 b' from .i18n import _'
13 from . import (
13 from . import (
14 encoding,
14 encoding,
15 error,
15 error,
16 sslutil,
16 wireprotoframing,
17 wireprotoframing,
17 )
18 )
18 from .utils import (
19 from .utils import (
@@ -34,6 +35,74 b' def formatrichmessage(atoms):'
34
35
35 return b''.join(chunks)
36 return b''.join(chunks)
36
37
38 SUPPORTED_REDIRECT_PROTOCOLS = {
39 b'http',
40 b'https',
41 }
42
43 SUPPORTED_CONTENT_HASHES = {
44 b'sha1',
45 b'sha256',
46 }
47
48 def redirecttargetsupported(ui, target):
49 """Determine whether a redirect target entry is supported.
50
51 ``target`` should come from the capabilities data structure emitted by
52 the server.
53 """
54 if target.get(b'protocol') not in SUPPORTED_REDIRECT_PROTOCOLS:
55 ui.note(_('(remote redirect target %s uses unsupported protocol: %s)\n')
56 % (target[b'name'], target.get(b'protocol', b'')))
57 return False
58
59 if target.get(b'snirequired') and not sslutil.hassni:
60 ui.note(_('(redirect target %s requires SNI, which is unsupported)\n') %
61 target[b'name'])
62 return False
63
64 if b'tlsversions' in target:
65 tlsversions = set(target[b'tlsversions'])
66 supported = set()
67
68 for v in sslutil.supportedprotocols:
69 assert v.startswith(b'tls')
70 supported.add(v[3:])
71
72 if not tlsversions & supported:
73 ui.note(_('(remote redirect target %s requires unsupported TLS '
74 'versions: %s)\n') % (
75 target[b'name'], b', '.join(sorted(tlsversions))))
76 return False
77
78 ui.note(_('(remote redirect target %s is compatible)\n') % target[b'name'])
79
80 return True
81
82 def supportedredirects(ui, apidescriptor):
83 """Resolve the "redirect" command request key given an API descriptor.
84
85 Given an API descriptor returned by the server, returns a data structure
86 that can be used in hte "redirect" field of command requests to advertise
87 support for compatible redirect targets.
88
89 Returns None if no redirect targets are remotely advertised or if none are
90 supported.
91 """
92 if not apidescriptor or b'redirect' not in apidescriptor:
93 return None
94
95 targets = [t[b'name'] for t in apidescriptor[b'redirect'][b'targets']
96 if redirecttargetsupported(ui, t)]
97
98 hashes = [h for h in apidescriptor[b'redirect'][b'hashes']
99 if h in SUPPORTED_CONTENT_HASHES]
100
101 return {
102 b'targets': targets,
103 b'hashes': hashes,
104 }
105
37 class commandresponse(object):
106 class commandresponse(object):
38 """Represents the response to a command request.
107 """Represents the response to a command request.
39
108
@@ -87,9 +156,12 b' class commandresponse(object):'
87
156
88 def _handleinitial(self, o):
157 def _handleinitial(self, o):
89 self._seeninitial = True
158 self._seeninitial = True
90 if o[b'status'] == 'ok':
159 if o[b'status'] == b'ok':
91 return
160 return
92
161
162 elif o[b'status'] == b'redirect':
163 raise error.Abort(_('redirect responses not yet supported'))
164
93 atoms = [{'msg': o[b'error'][b'message']}]
165 atoms = [{'msg': o[b'error'][b'message']}]
94 if b'args' in o[b'error']:
166 if b'args' in o[b'error']:
95 atoms[0]['args'] = o[b'error'][b'args']
167 atoms[0]['args'] = o[b'error'][b'args']
@@ -150,12 +222,13 b' class clienthandler(object):'
150 self._responses = {}
222 self._responses = {}
151 self._frameseof = False
223 self._frameseof = False
152
224
153 def callcommand(self, command, args, f):
225 def callcommand(self, command, args, f, redirect=None):
154 """Register a request to call a command.
226 """Register a request to call a command.
155
227
156 Returns an iterable of frames that should be sent over the wire.
228 Returns an iterable of frames that should be sent over the wire.
157 """
229 """
158 request, action, meta = self._reactor.callcommand(command, args)
230 request, action, meta = self._reactor.callcommand(command, args,
231 redirect=redirect)
159
232
160 if action != 'noop':
233 if action != 'noop':
161 raise error.ProgrammingError('%s not yet supported' % action)
234 raise error.ProgrammingError('%s not yet supported' % action)
@@ -139,6 +139,29 b' class StreamTests(unittest.TestCase):'
139 ffs(b'%d 0 0 command-response eos bar' % request.requestid))
139 ffs(b'%d 0 0 command-response eos bar' % request.requestid))
140 self.assertEqual(action, b'responsedata')
140 self.assertEqual(action, b'responsedata')
141
141
142 class RedirectTests(unittest.TestCase):
143 def testredirect(self):
144 reactor = framing.clientreactor(buffersends=False)
145
146 redirect = {
147 b'targets': [b'a', b'b'],
148 b'hashes': [b'sha256'],
149 }
150
151 request, action, meta = reactor.callcommand(
152 b'foo', {}, redirect=redirect)
153
154 self.assertEqual(action, b'sendframes')
155
156 frames = list(meta[b'framegen'])
157 self.assertEqual(len(frames), 1)
158
159 self.assertEqual(frames[0],
160 ffs(b'1 1 stream-begin command-request new '
161 b"cbor:{b'name': b'foo', "
162 b"b'redirect': {b'targets': [b'a', b'b'], "
163 b"b'hashes': [b'sha256']}}"))
164
142 if __name__ == '__main__':
165 if __name__ == '__main__':
143 import silenttestrunner
166 import silenttestrunner
144 silenttestrunner.main(__name__)
167 silenttestrunner.main(__name__)
This diff has been collapsed as it changes many lines, (594 lines changed) Show them Hide them
@@ -57,16 +57,17 b' Redirect targets advertised when configu'
57 s> Content-Length: 1970\r\n
57 s> Content-Length: 1970\r\n
58 s> \r\n
58 s> \r\n
59 s> \xa3GapibaseDapi/Dapis\xa1Pexp-http-v2-0002\xa6Hcommands\xaaIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x84IbookmarksGparentsEphaseHrevisionInoderange\xa3Gdefault\xf6Hrequired\xf4DtypeDlistEnodes\xa3Gdefault\xf6Hrequired\xf4DtypeDlistJnodesdepth\xa3Gdefault\xf6Hrequired\xf4DtypeCintKpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDpath\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullEheads\xa2Dargs\xa1Jpubliconly\xa3Gdefault\xf4Hrequired\xf4DtypeDboolKpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\xa3Gdefault\x80Hrequired\xf4DtypeDlistKpermissions\x81DpullHlistkeys\xa2Dargs\xa1Inamespace\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullFlookup\xa2Dargs\xa1Ckey\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullLmanifestdata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDtree\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullGpushkey\xa2Dargs\xa4Ckey\xa2Hrequired\xf5DtypeEbytesInamespace\xa2Hrequired\xf5DtypeEbytesCnew\xa2Hrequired\xf5DtypeEbytesCold\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpushKcompression\x82\xa1DnameDzstd\xa1DnameDzlibQframingmediatypes\x81X&application/mercurial-exp-framing-0005Rpathfilterprefixes\xd9\x01\x02\x82Epath:Lrootfilesin:Nrawrepoformats\x82LgeneraldeltaHrevlogv1Hredirect\xa2Fhashes\x82Fsha256Dsha1Gtargets\x81\xa5DnameHtarget-aHprotocolDhttpKsnirequired\xf4Ktlsversions\x82C1.2C1.3Duris\x81Shttp://example.com/Nv1capabilitiesY\x01\xd8batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
59 s> \xa3GapibaseDapi/Dapis\xa1Pexp-http-v2-0002\xa6Hcommands\xaaIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x84IbookmarksGparentsEphaseHrevisionInoderange\xa3Gdefault\xf6Hrequired\xf4DtypeDlistEnodes\xa3Gdefault\xf6Hrequired\xf4DtypeDlistJnodesdepth\xa3Gdefault\xf6Hrequired\xf4DtypeCintKpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDpath\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullEheads\xa2Dargs\xa1Jpubliconly\xa3Gdefault\xf4Hrequired\xf4DtypeDboolKpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\xa3Gdefault\x80Hrequired\xf4DtypeDlistKpermissions\x81DpullHlistkeys\xa2Dargs\xa1Inamespace\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullFlookup\xa2Dargs\xa1Ckey\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullLmanifestdata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDtree\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullGpushkey\xa2Dargs\xa4Ckey\xa2Hrequired\xf5DtypeEbytesInamespace\xa2Hrequired\xf5DtypeEbytesCnew\xa2Hrequired\xf5DtypeEbytesCold\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpushKcompression\x82\xa1DnameDzstd\xa1DnameDzlibQframingmediatypes\x81X&application/mercurial-exp-framing-0005Rpathfilterprefixes\xd9\x01\x02\x82Epath:Lrootfilesin:Nrawrepoformats\x82LgeneraldeltaHrevlogv1Hredirect\xa2Fhashes\x82Fsha256Dsha1Gtargets\x81\xa5DnameHtarget-aHprotocolDhttpKsnirequired\xf4Ktlsversions\x82C1.2C1.3Duris\x81Shttp://example.com/Nv1capabilitiesY\x01\xd8batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
60 (remote redirect target target-a is compatible)
60 sending capabilities command
61 sending capabilities command
61 s> POST /api/exp-http-v2-0002/ro/capabilities HTTP/1.1\r\n
62 s> POST /api/exp-http-v2-0002/ro/capabilities HTTP/1.1\r\n
62 s> Accept-Encoding: identity\r\n
63 s> Accept-Encoding: identity\r\n
63 s> accept: application/mercurial-exp-framing-0005\r\n
64 s> accept: application/mercurial-exp-framing-0005\r\n
64 s> content-type: application/mercurial-exp-framing-0005\r\n
65 s> content-type: application/mercurial-exp-framing-0005\r\n
65 s> content-length: 27\r\n
66 s> content-length: 75\r\n
66 s> host: $LOCALIP:$HGPORT\r\n (glob)
67 s> host: $LOCALIP:$HGPORT\r\n (glob)
67 s> user-agent: Mercurial debugwireproto\r\n
68 s> user-agent: Mercurial debugwireproto\r\n
68 s> \r\n
69 s> \r\n
69 s> \x13\x00\x00\x01\x00\x01\x01\x11\xa1DnameLcapabilities
70 s> C\x00\x00\x01\x00\x01\x01\x11\xa2DnameLcapabilitiesHredirect\xa2Fhashes\x82Fsha256Dsha1Gtargets\x81Htarget-a
70 s> makefile('rb', None)
71 s> makefile('rb', None)
71 s> HTTP/1.1 200 OK\r\n
72 s> HTTP/1.1 200 OK\r\n
72 s> Server: testing stub value\r\n
73 s> Server: testing stub value\r\n
@@ -308,6 +309,8 b' Redirect targets advertised when configu'
308 }
309 }
309 ]
310 ]
310
311
312 Unknown protocol is filtered from compatible targets
313
311 $ cat > redirects.py << EOF
314 $ cat > redirects.py << EOF
312 > [
315 > [
313 > {
316 > {
@@ -344,16 +347,18 b' Redirect targets advertised when configu'
344 s> Content-Length: 1997\r\n
347 s> Content-Length: 1997\r\n
345 s> \r\n
348 s> \r\n
346 s> \xa3GapibaseDapi/Dapis\xa1Pexp-http-v2-0002\xa6Hcommands\xaaIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x84IbookmarksGparentsEphaseHrevisionInoderange\xa3Gdefault\xf6Hrequired\xf4DtypeDlistEnodes\xa3Gdefault\xf6Hrequired\xf4DtypeDlistJnodesdepth\xa3Gdefault\xf6Hrequired\xf4DtypeCintKpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDpath\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullEheads\xa2Dargs\xa1Jpubliconly\xa3Gdefault\xf4Hrequired\xf4DtypeDboolKpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\xa3Gdefault\x80Hrequired\xf4DtypeDlistKpermissions\x81DpullHlistkeys\xa2Dargs\xa1Inamespace\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullFlookup\xa2Dargs\xa1Ckey\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullLmanifestdata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDtree\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullGpushkey\xa2Dargs\xa4Ckey\xa2Hrequired\xf5DtypeEbytesInamespace\xa2Hrequired\xf5DtypeEbytesCnew\xa2Hrequired\xf5DtypeEbytesCold\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpushKcompression\x82\xa1DnameDzstd\xa1DnameDzlibQframingmediatypes\x81X&application/mercurial-exp-framing-0005Rpathfilterprefixes\xd9\x01\x02\x82Epath:Lrootfilesin:Nrawrepoformats\x82LgeneraldeltaHrevlogv1Hredirect\xa2Fhashes\x82Fsha256Dsha1Gtargets\x82\xa3DnameHtarget-aHprotocolDhttpDuris\x81Shttp://example.com/\xa3DnameHtarget-bHprotocolGunknownDuris\x81Vunknown://example.com/Nv1capabilitiesY\x01\xd8batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
349 s> \xa3GapibaseDapi/Dapis\xa1Pexp-http-v2-0002\xa6Hcommands\xaaIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x84IbookmarksGparentsEphaseHrevisionInoderange\xa3Gdefault\xf6Hrequired\xf4DtypeDlistEnodes\xa3Gdefault\xf6Hrequired\xf4DtypeDlistJnodesdepth\xa3Gdefault\xf6Hrequired\xf4DtypeCintKpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDpath\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullEheads\xa2Dargs\xa1Jpubliconly\xa3Gdefault\xf4Hrequired\xf4DtypeDboolKpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\xa3Gdefault\x80Hrequired\xf4DtypeDlistKpermissions\x81DpullHlistkeys\xa2Dargs\xa1Inamespace\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullFlookup\xa2Dargs\xa1Ckey\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullLmanifestdata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDtree\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullGpushkey\xa2Dargs\xa4Ckey\xa2Hrequired\xf5DtypeEbytesInamespace\xa2Hrequired\xf5DtypeEbytesCnew\xa2Hrequired\xf5DtypeEbytesCold\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpushKcompression\x82\xa1DnameDzstd\xa1DnameDzlibQframingmediatypes\x81X&application/mercurial-exp-framing-0005Rpathfilterprefixes\xd9\x01\x02\x82Epath:Lrootfilesin:Nrawrepoformats\x82LgeneraldeltaHrevlogv1Hredirect\xa2Fhashes\x82Fsha256Dsha1Gtargets\x82\xa3DnameHtarget-aHprotocolDhttpDuris\x81Shttp://example.com/\xa3DnameHtarget-bHprotocolGunknownDuris\x81Vunknown://example.com/Nv1capabilitiesY\x01\xd8batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
350 (remote redirect target target-a is compatible)
351 (remote redirect target target-b uses unsupported protocol: unknown)
347 sending capabilities command
352 sending capabilities command
348 s> POST /api/exp-http-v2-0002/ro/capabilities HTTP/1.1\r\n
353 s> POST /api/exp-http-v2-0002/ro/capabilities HTTP/1.1\r\n
349 s> Accept-Encoding: identity\r\n
354 s> Accept-Encoding: identity\r\n
350 s> accept: application/mercurial-exp-framing-0005\r\n
355 s> accept: application/mercurial-exp-framing-0005\r\n
351 s> content-type: application/mercurial-exp-framing-0005\r\n
356 s> content-type: application/mercurial-exp-framing-0005\r\n
352 s> content-length: 27\r\n
357 s> content-length: 75\r\n
353 s> host: $LOCALIP:$HGPORT\r\n (glob)
358 s> host: $LOCALIP:$HGPORT\r\n (glob)
354 s> user-agent: Mercurial debugwireproto\r\n
359 s> user-agent: Mercurial debugwireproto\r\n
355 s> \r\n
360 s> \r\n
356 s> \x13\x00\x00\x01\x00\x01\x01\x11\xa1DnameLcapabilities
361 s> C\x00\x00\x01\x00\x01\x01\x11\xa2DnameLcapabilitiesHredirect\xa2Fhashes\x82Fsha256Dsha1Gtargets\x81Htarget-a
357 s> makefile('rb', None)
362 s> makefile('rb', None)
358 s> HTTP/1.1 200 OK\r\n
363 s> HTTP/1.1 200 OK\r\n
359 s> Server: testing stub value\r\n
364 s> Server: testing stub value\r\n
@@ -597,5 +602,586 b' Redirect targets advertised when configu'
597 }
602 }
598 ]
603 ]
599
604
605 Missing SNI support filters targets that require SNI
606
607 $ cat > nosni.py << EOF
608 > from mercurial import sslutil
609 > sslutil.hassni = False
610 > EOF
611 $ cat >> $HGRCPATH << EOF
612 > [extensions]
613 > nosni=`pwd`/nosni.py
614 > EOF
615
616 $ cat > redirects.py << EOF
617 > [
618 > {
619 > b'name': b'target-bad-tls',
620 > b'protocol': b'https',
621 > b'uris': [b'https://example.com/'],
622 > b'snirequired': True,
623 > },
624 > ]
625 > EOF
626
627 $ sendhttpv2peerhandshake << EOF
628 > command capabilities
629 > EOF
630 creating http peer for wire protocol version 2
631 s> GET /?cmd=capabilities HTTP/1.1\r\n
632 s> Accept-Encoding: identity\r\n
633 s> vary: X-HgProto-1,X-HgUpgrade-1\r\n
634 s> x-hgproto-1: cbor\r\n
635 s> x-hgupgrade-1: exp-http-v2-0002\r\n
636 s> accept: application/mercurial-0.1\r\n
637 s> host: $LOCALIP:$HGPORT\r\n (glob)
638 s> user-agent: Mercurial debugwireproto\r\n
639 s> \r\n
640 s> makefile('rb', None)
641 s> HTTP/1.1 200 OK\r\n
642 s> Server: testing stub value\r\n
643 s> Date: $HTTP_DATE$\r\n
644 s> Content-Type: application/mercurial-cbor\r\n
645 s> Content-Length: 1957\r\n
646 s> \r\n
647 s> \xa3GapibaseDapi/Dapis\xa1Pexp-http-v2-0002\xa6Hcommands\xaaIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x84IbookmarksGparentsEphaseHrevisionInoderange\xa3Gdefault\xf6Hrequired\xf4DtypeDlistEnodes\xa3Gdefault\xf6Hrequired\xf4DtypeDlistJnodesdepth\xa3Gdefault\xf6Hrequired\xf4DtypeCintKpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDpath\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullEheads\xa2Dargs\xa1Jpubliconly\xa3Gdefault\xf4Hrequired\xf4DtypeDboolKpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\xa3Gdefault\x80Hrequired\xf4DtypeDlistKpermissions\x81DpullHlistkeys\xa2Dargs\xa1Inamespace\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullFlookup\xa2Dargs\xa1Ckey\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullLmanifestdata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDtree\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullGpushkey\xa2Dargs\xa4Ckey\xa2Hrequired\xf5DtypeEbytesInamespace\xa2Hrequired\xf5DtypeEbytesCnew\xa2Hrequired\xf5DtypeEbytesCold\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpushKcompression\x82\xa1DnameDzstd\xa1DnameDzlibQframingmediatypes\x81X&application/mercurial-exp-framing-0005Rpathfilterprefixes\xd9\x01\x02\x82Epath:Lrootfilesin:Nrawrepoformats\x82LgeneraldeltaHrevlogv1Hredirect\xa2Fhashes\x82Fsha256Dsha1Gtargets\x81\xa4DnameNtarget-bad-tlsHprotocolEhttpsKsnirequired\xf5Duris\x81Thttps://example.com/Nv1capabilitiesY\x01\xd8batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
648 (redirect target target-bad-tls requires SNI, which is unsupported)
649 sending capabilities command
650 s> POST /api/exp-http-v2-0002/ro/capabilities HTTP/1.1\r\n
651 s> Accept-Encoding: identity\r\n
652 s> accept: application/mercurial-exp-framing-0005\r\n
653 s> content-type: application/mercurial-exp-framing-0005\r\n
654 s> content-length: 66\r\n
655 s> host: $LOCALIP:$HGPORT\r\n (glob)
656 s> user-agent: Mercurial debugwireproto\r\n
657 s> \r\n
658 s> :\x00\x00\x01\x00\x01\x01\x11\xa2DnameLcapabilitiesHredirect\xa2Fhashes\x82Fsha256Dsha1Gtargets\x80
659 s> makefile('rb', None)
660 s> HTTP/1.1 200 OK\r\n
661 s> Server: testing stub value\r\n
662 s> Date: $HTTP_DATE$\r\n
663 s> Content-Type: application/mercurial-exp-framing-0005\r\n
664 s> Transfer-Encoding: chunked\r\n
665 s> \r\n
666 s> 13\r\n
667 s> \x0b\x00\x00\x01\x00\x02\x011
668 s> \xa1FstatusBok
669 s> \r\n
670 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
671 s> 59e\r\n
672 s> \x96\x05\x00\x01\x00\x02\x001
673 s> \xa6Hcommands\xaaIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x84IbookmarksGparentsEphaseHrevisionInoderange\xa3Gdefault\xf6Hrequired\xf4DtypeDlistEnodes\xa3Gdefault\xf6Hrequired\xf4DtypeDlistJnodesdepth\xa3Gdefault\xf6Hrequired\xf4DtypeCintKpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDpath\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullEheads\xa2Dargs\xa1Jpubliconly\xa3Gdefault\xf4Hrequired\xf4DtypeDboolKpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\xa3Gdefault\x80Hrequired\xf4DtypeDlistKpermissions\x81DpullHlistkeys\xa2Dargs\xa1Inamespace\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullFlookup\xa2Dargs\xa1Ckey\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullLmanifestdata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDtree\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullGpushkey\xa2Dargs\xa4Ckey\xa2Hrequired\xf5DtypeEbytesInamespace\xa2Hrequired\xf5DtypeEbytesCnew\xa2Hrequired\xf5DtypeEbytesCold\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpushKcompression\x82\xa1DnameDzstd\xa1DnameDzlibQframingmediatypes\x81X&application/mercurial-exp-framing-0005Rpathfilterprefixes\xd9\x01\x02\x82Epath:Lrootfilesin:Nrawrepoformats\x82LgeneraldeltaHrevlogv1Hredirect\xa2Fhashes\x82Fsha256Dsha1Gtargets\x81\xa4DnameNtarget-bad-tlsHprotocolEhttpsKsnirequired\xf5Duris\x81Thttps://example.com/
674 s> \r\n
675 received frame(size=1430; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
676 s> 8\r\n
677 s> \x00\x00\x00\x01\x00\x02\x002
678 s> \r\n
679 s> 0\r\n
680 s> \r\n
681 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
682 response: gen[
683 {
684 b'commands': {
685 b'branchmap': {
686 b'args': {},
687 b'permissions': [
688 b'pull'
689 ]
690 },
691 b'capabilities': {
692 b'args': {},
693 b'permissions': [
694 b'pull'
695 ]
696 },
697 b'changesetdata': {
698 b'args': {
699 b'fields': {
700 b'default': set([]),
701 b'required': False,
702 b'type': b'set',
703 b'validvalues': set([
704 b'bookmarks',
705 b'parents',
706 b'phase',
707 b'revision'
708 ])
709 },
710 b'noderange': {
711 b'default': None,
712 b'required': False,
713 b'type': b'list'
714 },
715 b'nodes': {
716 b'default': None,
717 b'required': False,
718 b'type': b'list'
719 },
720 b'nodesdepth': {
721 b'default': None,
722 b'required': False,
723 b'type': b'int'
724 }
725 },
726 b'permissions': [
727 b'pull'
728 ]
729 },
730 b'filedata': {
731 b'args': {
732 b'fields': {
733 b'default': set([]),
734 b'required': False,
735 b'type': b'set',
736 b'validvalues': set([
737 b'parents',
738 b'revision'
739 ])
740 },
741 b'haveparents': {
742 b'default': False,
743 b'required': False,
744 b'type': b'bool'
745 },
746 b'nodes': {
747 b'required': True,
748 b'type': b'list'
749 },
750 b'path': {
751 b'required': True,
752 b'type': b'bytes'
753 }
754 },
755 b'permissions': [
756 b'pull'
757 ]
758 },
759 b'heads': {
760 b'args': {
761 b'publiconly': {
762 b'default': False,
763 b'required': False,
764 b'type': b'bool'
765 }
766 },
767 b'permissions': [
768 b'pull'
769 ]
770 },
771 b'known': {
772 b'args': {
773 b'nodes': {
774 b'default': [],
775 b'required': False,
776 b'type': b'list'
777 }
778 },
779 b'permissions': [
780 b'pull'
781 ]
782 },
783 b'listkeys': {
784 b'args': {
785 b'namespace': {
786 b'required': True,
787 b'type': b'bytes'
788 }
789 },
790 b'permissions': [
791 b'pull'
792 ]
793 },
794 b'lookup': {
795 b'args': {
796 b'key': {
797 b'required': True,
798 b'type': b'bytes'
799 }
800 },
801 b'permissions': [
802 b'pull'
803 ]
804 },
805 b'manifestdata': {
806 b'args': {
807 b'fields': {
808 b'default': set([]),
809 b'required': False,
810 b'type': b'set',
811 b'validvalues': set([
812 b'parents',
813 b'revision'
814 ])
815 },
816 b'haveparents': {
817 b'default': False,
818 b'required': False,
819 b'type': b'bool'
820 },
821 b'nodes': {
822 b'required': True,
823 b'type': b'list'
824 },
825 b'tree': {
826 b'required': True,
827 b'type': b'bytes'
828 }
829 },
830 b'permissions': [
831 b'pull'
832 ]
833 },
834 b'pushkey': {
835 b'args': {
836 b'key': {
837 b'required': True,
838 b'type': b'bytes'
839 },
840 b'namespace': {
841 b'required': True,
842 b'type': b'bytes'
843 },
844 b'new': {
845 b'required': True,
846 b'type': b'bytes'
847 },
848 b'old': {
849 b'required': True,
850 b'type': b'bytes'
851 }
852 },
853 b'permissions': [
854 b'push'
855 ]
856 }
857 },
858 b'compression': [
859 {
860 b'name': b'zstd'
861 },
862 {
863 b'name': b'zlib'
864 }
865 ],
866 b'framingmediatypes': [
867 b'application/mercurial-exp-framing-0005'
868 ],
869 b'pathfilterprefixes': set([
870 b'path:',
871 b'rootfilesin:'
872 ]),
873 b'rawrepoformats': [
874 b'generaldelta',
875 b'revlogv1'
876 ],
877 b'redirect': {
878 b'hashes': [
879 b'sha256',
880 b'sha1'
881 ],
882 b'targets': [
883 {
884 b'name': b'target-bad-tls',
885 b'protocol': b'https',
886 b'snirequired': True,
887 b'uris': [
888 b'https://example.com/'
889 ]
890 }
891 ]
892 }
893 }
894 ]
895
896 $ cat >> $HGRCPATH << EOF
897 > [extensions]
898 > nosni=!
899 > EOF
900
901 Unknown tls value is filtered from compatible targets
902
903 $ cat > redirects.py << EOF
904 > [
905 > {
906 > b'name': b'target-bad-tls',
907 > b'protocol': b'https',
908 > b'uris': [b'https://example.com/'],
909 > b'tlsversions': [b'42', b'39'],
910 > },
911 > ]
912 > EOF
913
914 $ sendhttpv2peerhandshake << EOF
915 > command capabilities
916 > EOF
917 creating http peer for wire protocol version 2
918 s> GET /?cmd=capabilities HTTP/1.1\r\n
919 s> Accept-Encoding: identity\r\n
920 s> vary: X-HgProto-1,X-HgUpgrade-1\r\n
921 s> x-hgproto-1: cbor\r\n
922 s> x-hgupgrade-1: exp-http-v2-0002\r\n
923 s> accept: application/mercurial-0.1\r\n
924 s> host: $LOCALIP:$HGPORT\r\n (glob)
925 s> user-agent: Mercurial debugwireproto\r\n
926 s> \r\n
927 s> makefile('rb', None)
928 s> HTTP/1.1 200 OK\r\n
929 s> Server: testing stub value\r\n
930 s> Date: $HTTP_DATE$\r\n
931 s> Content-Type: application/mercurial-cbor\r\n
932 s> Content-Length: 1963\r\n
933 s> \r\n
934 s> \xa3GapibaseDapi/Dapis\xa1Pexp-http-v2-0002\xa6Hcommands\xaaIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x84IbookmarksGparentsEphaseHrevisionInoderange\xa3Gdefault\xf6Hrequired\xf4DtypeDlistEnodes\xa3Gdefault\xf6Hrequired\xf4DtypeDlistJnodesdepth\xa3Gdefault\xf6Hrequired\xf4DtypeCintKpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDpath\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullEheads\xa2Dargs\xa1Jpubliconly\xa3Gdefault\xf4Hrequired\xf4DtypeDboolKpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\xa3Gdefault\x80Hrequired\xf4DtypeDlistKpermissions\x81DpullHlistkeys\xa2Dargs\xa1Inamespace\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullFlookup\xa2Dargs\xa1Ckey\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullLmanifestdata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDtree\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullGpushkey\xa2Dargs\xa4Ckey\xa2Hrequired\xf5DtypeEbytesInamespace\xa2Hrequired\xf5DtypeEbytesCnew\xa2Hrequired\xf5DtypeEbytesCold\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpushKcompression\x82\xa1DnameDzstd\xa1DnameDzlibQframingmediatypes\x81X&application/mercurial-exp-framing-0005Rpathfilterprefixes\xd9\x01\x02\x82Epath:Lrootfilesin:Nrawrepoformats\x82LgeneraldeltaHrevlogv1Hredirect\xa2Fhashes\x82Fsha256Dsha1Gtargets\x81\xa4DnameNtarget-bad-tlsHprotocolEhttpsKtlsversions\x82B42B39Duris\x81Thttps://example.com/Nv1capabilitiesY\x01\xd8batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
935 (remote redirect target target-bad-tls requires unsupported TLS versions: 39, 42)
936 sending capabilities command
937 s> POST /api/exp-http-v2-0002/ro/capabilities HTTP/1.1\r\n
938 s> Accept-Encoding: identity\r\n
939 s> accept: application/mercurial-exp-framing-0005\r\n
940 s> content-type: application/mercurial-exp-framing-0005\r\n
941 s> content-length: 66\r\n
942 s> host: $LOCALIP:$HGPORT\r\n (glob)
943 s> user-agent: Mercurial debugwireproto\r\n
944 s> \r\n
945 s> :\x00\x00\x01\x00\x01\x01\x11\xa2DnameLcapabilitiesHredirect\xa2Fhashes\x82Fsha256Dsha1Gtargets\x80
946 s> makefile('rb', None)
947 s> HTTP/1.1 200 OK\r\n
948 s> Server: testing stub value\r\n
949 s> Date: $HTTP_DATE$\r\n
950 s> Content-Type: application/mercurial-exp-framing-0005\r\n
951 s> Transfer-Encoding: chunked\r\n
952 s> \r\n
953 s> 13\r\n
954 s> \x0b\x00\x00\x01\x00\x02\x011
955 s> \xa1FstatusBok
956 s> \r\n
957 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
958 s> 5a4\r\n
959 s> \x9c\x05\x00\x01\x00\x02\x001
960 s> \xa6Hcommands\xaaIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x84IbookmarksGparentsEphaseHrevisionInoderange\xa3Gdefault\xf6Hrequired\xf4DtypeDlistEnodes\xa3Gdefault\xf6Hrequired\xf4DtypeDlistJnodesdepth\xa3Gdefault\xf6Hrequired\xf4DtypeCintKpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDpath\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullEheads\xa2Dargs\xa1Jpubliconly\xa3Gdefault\xf4Hrequired\xf4DtypeDboolKpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\xa3Gdefault\x80Hrequired\xf4DtypeDlistKpermissions\x81DpullHlistkeys\xa2Dargs\xa1Inamespace\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullFlookup\xa2Dargs\xa1Ckey\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullLmanifestdata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDtree\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullGpushkey\xa2Dargs\xa4Ckey\xa2Hrequired\xf5DtypeEbytesInamespace\xa2Hrequired\xf5DtypeEbytesCnew\xa2Hrequired\xf5DtypeEbytesCold\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpushKcompression\x82\xa1DnameDzstd\xa1DnameDzlibQframingmediatypes\x81X&application/mercurial-exp-framing-0005Rpathfilterprefixes\xd9\x01\x02\x82Epath:Lrootfilesin:Nrawrepoformats\x82LgeneraldeltaHrevlogv1Hredirect\xa2Fhashes\x82Fsha256Dsha1Gtargets\x81\xa4DnameNtarget-bad-tlsHprotocolEhttpsKtlsversions\x82B42B39Duris\x81Thttps://example.com/
961 s> \r\n
962 received frame(size=1436; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
963 s> 8\r\n
964 s> \x00\x00\x00\x01\x00\x02\x002
965 s> \r\n
966 s> 0\r\n
967 s> \r\n
968 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
969 response: gen[
970 {
971 b'commands': {
972 b'branchmap': {
973 b'args': {},
974 b'permissions': [
975 b'pull'
976 ]
977 },
978 b'capabilities': {
979 b'args': {},
980 b'permissions': [
981 b'pull'
982 ]
983 },
984 b'changesetdata': {
985 b'args': {
986 b'fields': {
987 b'default': set([]),
988 b'required': False,
989 b'type': b'set',
990 b'validvalues': set([
991 b'bookmarks',
992 b'parents',
993 b'phase',
994 b'revision'
995 ])
996 },
997 b'noderange': {
998 b'default': None,
999 b'required': False,
1000 b'type': b'list'
1001 },
1002 b'nodes': {
1003 b'default': None,
1004 b'required': False,
1005 b'type': b'list'
1006 },
1007 b'nodesdepth': {
1008 b'default': None,
1009 b'required': False,
1010 b'type': b'int'
1011 }
1012 },
1013 b'permissions': [
1014 b'pull'
1015 ]
1016 },
1017 b'filedata': {
1018 b'args': {
1019 b'fields': {
1020 b'default': set([]),
1021 b'required': False,
1022 b'type': b'set',
1023 b'validvalues': set([
1024 b'parents',
1025 b'revision'
1026 ])
1027 },
1028 b'haveparents': {
1029 b'default': False,
1030 b'required': False,
1031 b'type': b'bool'
1032 },
1033 b'nodes': {
1034 b'required': True,
1035 b'type': b'list'
1036 },
1037 b'path': {
1038 b'required': True,
1039 b'type': b'bytes'
1040 }
1041 },
1042 b'permissions': [
1043 b'pull'
1044 ]
1045 },
1046 b'heads': {
1047 b'args': {
1048 b'publiconly': {
1049 b'default': False,
1050 b'required': False,
1051 b'type': b'bool'
1052 }
1053 },
1054 b'permissions': [
1055 b'pull'
1056 ]
1057 },
1058 b'known': {
1059 b'args': {
1060 b'nodes': {
1061 b'default': [],
1062 b'required': False,
1063 b'type': b'list'
1064 }
1065 },
1066 b'permissions': [
1067 b'pull'
1068 ]
1069 },
1070 b'listkeys': {
1071 b'args': {
1072 b'namespace': {
1073 b'required': True,
1074 b'type': b'bytes'
1075 }
1076 },
1077 b'permissions': [
1078 b'pull'
1079 ]
1080 },
1081 b'lookup': {
1082 b'args': {
1083 b'key': {
1084 b'required': True,
1085 b'type': b'bytes'
1086 }
1087 },
1088 b'permissions': [
1089 b'pull'
1090 ]
1091 },
1092 b'manifestdata': {
1093 b'args': {
1094 b'fields': {
1095 b'default': set([]),
1096 b'required': False,
1097 b'type': b'set',
1098 b'validvalues': set([
1099 b'parents',
1100 b'revision'
1101 ])
1102 },
1103 b'haveparents': {
1104 b'default': False,
1105 b'required': False,
1106 b'type': b'bool'
1107 },
1108 b'nodes': {
1109 b'required': True,
1110 b'type': b'list'
1111 },
1112 b'tree': {
1113 b'required': True,
1114 b'type': b'bytes'
1115 }
1116 },
1117 b'permissions': [
1118 b'pull'
1119 ]
1120 },
1121 b'pushkey': {
1122 b'args': {
1123 b'key': {
1124 b'required': True,
1125 b'type': b'bytes'
1126 },
1127 b'namespace': {
1128 b'required': True,
1129 b'type': b'bytes'
1130 },
1131 b'new': {
1132 b'required': True,
1133 b'type': b'bytes'
1134 },
1135 b'old': {
1136 b'required': True,
1137 b'type': b'bytes'
1138 }
1139 },
1140 b'permissions': [
1141 b'push'
1142 ]
1143 }
1144 },
1145 b'compression': [
1146 {
1147 b'name': b'zstd'
1148 },
1149 {
1150 b'name': b'zlib'
1151 }
1152 ],
1153 b'framingmediatypes': [
1154 b'application/mercurial-exp-framing-0005'
1155 ],
1156 b'pathfilterprefixes': set([
1157 b'path:',
1158 b'rootfilesin:'
1159 ]),
1160 b'rawrepoformats': [
1161 b'generaldelta',
1162 b'revlogv1'
1163 ],
1164 b'redirect': {
1165 b'hashes': [
1166 b'sha256',
1167 b'sha1'
1168 ],
1169 b'targets': [
1170 {
1171 b'name': b'target-bad-tls',
1172 b'protocol': b'https',
1173 b'tlsversions': [
1174 b'42',
1175 b'39'
1176 ],
1177 b'uris': [
1178 b'https://example.com/'
1179 ]
1180 }
1181 ]
1182 }
1183 }
1184 ]
1185
600 $ cat error.log
1186 $ cat error.log
601 $ killdaemons.py
1187 $ killdaemons.py
General Comments 0
You need to be logged in to leave comments. Login now