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: |
|
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> |
|
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 |
$ |
|
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: |
|
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> |
|
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