##// END OF EJS Templates
wireprotov2: declare command arguments richly...
Gregory Szorc -
r39835:0b61d21f default
parent child Browse files
Show More
@@ -1,921 +1,1058
1 1 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
2 2 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 3 #
4 4 # This software may be used and distributed according to the terms of the
5 5 # GNU General Public License version 2 or any later version.
6 6
7 7 from __future__ import absolute_import
8 8
9 9 import contextlib
10 10
11 11 from .i18n import _
12 12 from .node import (
13 13 hex,
14 14 nullid,
15 15 nullrev,
16 16 )
17 17 from . import (
18 18 changegroup,
19 19 dagop,
20 20 discovery,
21 21 encoding,
22 22 error,
23 23 pycompat,
24 24 streamclone,
25 25 util,
26 26 wireprotoframing,
27 27 wireprototypes,
28 28 )
29 29 from .utils import (
30 30 interfaceutil,
31 31 )
32 32
33 33 FRAMINGTYPE = b'application/mercurial-exp-framing-0005'
34 34
35 35 HTTP_WIREPROTO_V2 = wireprototypes.HTTP_WIREPROTO_V2
36 36
37 37 COMMANDS = wireprototypes.commanddict()
38 38
39 39 def handlehttpv2request(rctx, req, res, checkperm, urlparts):
40 40 from .hgweb import common as hgwebcommon
41 41
42 42 # URL space looks like: <permissions>/<command>, where <permission> can
43 43 # be ``ro`` or ``rw`` to signal read-only or read-write, respectively.
44 44
45 45 # Root URL does nothing meaningful... yet.
46 46 if not urlparts:
47 47 res.status = b'200 OK'
48 48 res.headers[b'Content-Type'] = b'text/plain'
49 49 res.setbodybytes(_('HTTP version 2 API handler'))
50 50 return
51 51
52 52 if len(urlparts) == 1:
53 53 res.status = b'404 Not Found'
54 54 res.headers[b'Content-Type'] = b'text/plain'
55 55 res.setbodybytes(_('do not know how to process %s\n') %
56 56 req.dispatchpath)
57 57 return
58 58
59 59 permission, command = urlparts[0:2]
60 60
61 61 if permission not in (b'ro', b'rw'):
62 62 res.status = b'404 Not Found'
63 63 res.headers[b'Content-Type'] = b'text/plain'
64 64 res.setbodybytes(_('unknown permission: %s') % permission)
65 65 return
66 66
67 67 if req.method != 'POST':
68 68 res.status = b'405 Method Not Allowed'
69 69 res.headers[b'Allow'] = b'POST'
70 70 res.setbodybytes(_('commands require POST requests'))
71 71 return
72 72
73 73 # At some point we'll want to use our own API instead of recycling the
74 74 # behavior of version 1 of the wire protocol...
75 75 # TODO return reasonable responses - not responses that overload the
76 76 # HTTP status line message for error reporting.
77 77 try:
78 78 checkperm(rctx, req, 'pull' if permission == b'ro' else 'push')
79 79 except hgwebcommon.ErrorResponse as e:
80 80 res.status = hgwebcommon.statusmessage(e.code, pycompat.bytestr(e))
81 81 for k, v in e.headers:
82 82 res.headers[k] = v
83 83 res.setbodybytes('permission denied')
84 84 return
85 85
86 86 # We have a special endpoint to reflect the request back at the client.
87 87 if command == b'debugreflect':
88 88 _processhttpv2reflectrequest(rctx.repo.ui, rctx.repo, req, res)
89 89 return
90 90
91 91 # Extra commands that we handle that aren't really wire protocol
92 92 # commands. Think extra hard before making this hackery available to
93 93 # extension.
94 94 extracommands = {'multirequest'}
95 95
96 96 if command not in COMMANDS and command not in extracommands:
97 97 res.status = b'404 Not Found'
98 98 res.headers[b'Content-Type'] = b'text/plain'
99 99 res.setbodybytes(_('unknown wire protocol command: %s\n') % command)
100 100 return
101 101
102 102 repo = rctx.repo
103 103 ui = repo.ui
104 104
105 105 proto = httpv2protocolhandler(req, ui)
106 106
107 107 if (not COMMANDS.commandavailable(command, proto)
108 108 and command not in extracommands):
109 109 res.status = b'404 Not Found'
110 110 res.headers[b'Content-Type'] = b'text/plain'
111 111 res.setbodybytes(_('invalid wire protocol command: %s') % command)
112 112 return
113 113
114 114 # TODO consider cases where proxies may add additional Accept headers.
115 115 if req.headers.get(b'Accept') != FRAMINGTYPE:
116 116 res.status = b'406 Not Acceptable'
117 117 res.headers[b'Content-Type'] = b'text/plain'
118 118 res.setbodybytes(_('client MUST specify Accept header with value: %s\n')
119 119 % FRAMINGTYPE)
120 120 return
121 121
122 122 if req.headers.get(b'Content-Type') != FRAMINGTYPE:
123 123 res.status = b'415 Unsupported Media Type'
124 124 # TODO we should send a response with appropriate media type,
125 125 # since client does Accept it.
126 126 res.headers[b'Content-Type'] = b'text/plain'
127 127 res.setbodybytes(_('client MUST send Content-Type header with '
128 128 'value: %s\n') % FRAMINGTYPE)
129 129 return
130 130
131 131 _processhttpv2request(ui, repo, req, res, permission, command, proto)
132 132
133 133 def _processhttpv2reflectrequest(ui, repo, req, res):
134 134 """Reads unified frame protocol request and dumps out state to client.
135 135
136 136 This special endpoint can be used to help debug the wire protocol.
137 137
138 138 Instead of routing the request through the normal dispatch mechanism,
139 139 we instead read all frames, decode them, and feed them into our state
140 140 tracker. We then dump the log of all that activity back out to the
141 141 client.
142 142 """
143 143 import json
144 144
145 145 # Reflection APIs have a history of being abused, accidentally disclosing
146 146 # sensitive data, etc. So we have a config knob.
147 147 if not ui.configbool('experimental', 'web.api.debugreflect'):
148 148 res.status = b'404 Not Found'
149 149 res.headers[b'Content-Type'] = b'text/plain'
150 150 res.setbodybytes(_('debugreflect service not available'))
151 151 return
152 152
153 153 # We assume we have a unified framing protocol request body.
154 154
155 155 reactor = wireprotoframing.serverreactor()
156 156 states = []
157 157
158 158 while True:
159 159 frame = wireprotoframing.readframe(req.bodyfh)
160 160
161 161 if not frame:
162 162 states.append(b'received: <no frame>')
163 163 break
164 164
165 165 states.append(b'received: %d %d %d %s' % (frame.typeid, frame.flags,
166 166 frame.requestid,
167 167 frame.payload))
168 168
169 169 action, meta = reactor.onframerecv(frame)
170 170 states.append(json.dumps((action, meta), sort_keys=True,
171 171 separators=(', ', ': ')))
172 172
173 173 action, meta = reactor.oninputeof()
174 174 meta['action'] = action
175 175 states.append(json.dumps(meta, sort_keys=True, separators=(', ',': ')))
176 176
177 177 res.status = b'200 OK'
178 178 res.headers[b'Content-Type'] = b'text/plain'
179 179 res.setbodybytes(b'\n'.join(states))
180 180
181 181 def _processhttpv2request(ui, repo, req, res, authedperm, reqcommand, proto):
182 182 """Post-validation handler for HTTPv2 requests.
183 183
184 184 Called when the HTTP request contains unified frame-based protocol
185 185 frames for evaluation.
186 186 """
187 187 # TODO Some HTTP clients are full duplex and can receive data before
188 188 # the entire request is transmitted. Figure out a way to indicate support
189 189 # for that so we can opt into full duplex mode.
190 190 reactor = wireprotoframing.serverreactor(deferoutput=True)
191 191 seencommand = False
192 192
193 193 outstream = reactor.makeoutputstream()
194 194
195 195 while True:
196 196 frame = wireprotoframing.readframe(req.bodyfh)
197 197 if not frame:
198 198 break
199 199
200 200 action, meta = reactor.onframerecv(frame)
201 201
202 202 if action == 'wantframe':
203 203 # Need more data before we can do anything.
204 204 continue
205 205 elif action == 'runcommand':
206 206 sentoutput = _httpv2runcommand(ui, repo, req, res, authedperm,
207 207 reqcommand, reactor, outstream,
208 208 meta, issubsequent=seencommand)
209 209
210 210 if sentoutput:
211 211 return
212 212
213 213 seencommand = True
214 214
215 215 elif action == 'error':
216 216 # TODO define proper error mechanism.
217 217 res.status = b'200 OK'
218 218 res.headers[b'Content-Type'] = b'text/plain'
219 219 res.setbodybytes(meta['message'] + b'\n')
220 220 return
221 221 else:
222 222 raise error.ProgrammingError(
223 223 'unhandled action from frame processor: %s' % action)
224 224
225 225 action, meta = reactor.oninputeof()
226 226 if action == 'sendframes':
227 227 # We assume we haven't started sending the response yet. If we're
228 228 # wrong, the response type will raise an exception.
229 229 res.status = b'200 OK'
230 230 res.headers[b'Content-Type'] = FRAMINGTYPE
231 231 res.setbodygen(meta['framegen'])
232 232 elif action == 'noop':
233 233 pass
234 234 else:
235 235 raise error.ProgrammingError('unhandled action from frame processor: %s'
236 236 % action)
237 237
238 238 def _httpv2runcommand(ui, repo, req, res, authedperm, reqcommand, reactor,
239 239 outstream, command, issubsequent):
240 240 """Dispatch a wire protocol command made from HTTPv2 requests.
241 241
242 242 The authenticated permission (``authedperm``) along with the original
243 243 command from the URL (``reqcommand``) are passed in.
244 244 """
245 245 # We already validated that the session has permissions to perform the
246 246 # actions in ``authedperm``. In the unified frame protocol, the canonical
247 247 # command to run is expressed in a frame. However, the URL also requested
248 248 # to run a specific command. We need to be careful that the command we
249 249 # run doesn't have permissions requirements greater than what was granted
250 250 # by ``authedperm``.
251 251 #
252 252 # Our rule for this is we only allow one command per HTTP request and
253 253 # that command must match the command in the URL. However, we make
254 254 # an exception for the ``multirequest`` URL. This URL is allowed to
255 255 # execute multiple commands. We double check permissions of each command
256 256 # as it is invoked to ensure there is no privilege escalation.
257 257 # TODO consider allowing multiple commands to regular command URLs
258 258 # iff each command is the same.
259 259
260 260 proto = httpv2protocolhandler(req, ui, args=command['args'])
261 261
262 262 if reqcommand == b'multirequest':
263 263 if not COMMANDS.commandavailable(command['command'], proto):
264 264 # TODO proper error mechanism
265 265 res.status = b'200 OK'
266 266 res.headers[b'Content-Type'] = b'text/plain'
267 267 res.setbodybytes(_('wire protocol command not available: %s') %
268 268 command['command'])
269 269 return True
270 270
271 271 # TODO don't use assert here, since it may be elided by -O.
272 272 assert authedperm in (b'ro', b'rw')
273 273 wirecommand = COMMANDS[command['command']]
274 274 assert wirecommand.permission in ('push', 'pull')
275 275
276 276 if authedperm == b'ro' and wirecommand.permission != 'pull':
277 277 # TODO proper error mechanism
278 278 res.status = b'403 Forbidden'
279 279 res.headers[b'Content-Type'] = b'text/plain'
280 280 res.setbodybytes(_('insufficient permissions to execute '
281 281 'command: %s') % command['command'])
282 282 return True
283 283
284 284 # TODO should we also call checkperm() here? Maybe not if we're going
285 285 # to overhaul that API. The granted scope from the URL check should
286 286 # be good enough.
287 287
288 288 else:
289 289 # Don't allow multiple commands outside of ``multirequest`` URL.
290 290 if issubsequent:
291 291 # TODO proper error mechanism
292 292 res.status = b'200 OK'
293 293 res.headers[b'Content-Type'] = b'text/plain'
294 294 res.setbodybytes(_('multiple commands cannot be issued to this '
295 295 'URL'))
296 296 return True
297 297
298 298 if reqcommand != command['command']:
299 299 # TODO define proper error mechanism
300 300 res.status = b'200 OK'
301 301 res.headers[b'Content-Type'] = b'text/plain'
302 302 res.setbodybytes(_('command in frame must match command in URL'))
303 303 return True
304 304
305 305 res.status = b'200 OK'
306 306 res.headers[b'Content-Type'] = FRAMINGTYPE
307 307
308 308 try:
309 309 objs = dispatch(repo, proto, command['command'])
310 310
311 311 action, meta = reactor.oncommandresponsereadyobjects(
312 312 outstream, command['requestid'], objs)
313 313
314 except error.WireprotoCommandError as e:
315 action, meta = reactor.oncommanderror(
316 outstream, command['requestid'], e.message, e.messageargs)
317
314 318 except Exception as e:
315 319 action, meta = reactor.onservererror(
316 320 outstream, command['requestid'],
317 321 _('exception when invoking command: %s') % e)
318 322
319 323 if action == 'sendframes':
320 324 res.setbodygen(meta['framegen'])
321 325 return True
322 326 elif action == 'noop':
323 327 return False
324 328 else:
325 329 raise error.ProgrammingError('unhandled event from reactor: %s' %
326 330 action)
327 331
328 332 def getdispatchrepo(repo, proto, command):
329 333 return repo.filtered('served')
330 334
331 335 def dispatch(repo, proto, command):
332 336 repo = getdispatchrepo(repo, proto, command)
333 337
334 338 func, spec = COMMANDS[command]
335 339 args = proto.getargs(spec)
336 340
337 341 return func(repo, proto, **args)
338 342
339 343 @interfaceutil.implementer(wireprototypes.baseprotocolhandler)
340 344 class httpv2protocolhandler(object):
341 345 def __init__(self, req, ui, args=None):
342 346 self._req = req
343 347 self._ui = ui
344 348 self._args = args
345 349
346 350 @property
347 351 def name(self):
348 352 return HTTP_WIREPROTO_V2
349 353
350 354 def getargs(self, args):
355 # First look for args that were passed but aren't registered on this
356 # command.
357 extra = set(self._args) - set(args)
358 if extra:
359 raise error.WireprotoCommandError(
360 'unsupported argument to command: %s' %
361 ', '.join(sorted(extra)))
362
363 # And look for required arguments that are missing.
364 missing = {a for a in args if args[a]['required']} - set(self._args)
365
366 if missing:
367 raise error.WireprotoCommandError(
368 'missing required arguments: %s' % ', '.join(sorted(missing)))
369
370 # Now derive the arguments to pass to the command, taking into
371 # account the arguments specified by the client.
351 372 data = {}
352 for k, typ in args.items():
353 if k == '*':
354 raise NotImplementedError('do not support * args')
355 elif k in self._args:
356 # TODO consider validating value types.
357 data[k] = self._args[k]
373 for k, meta in sorted(args.items()):
374 # This argument wasn't passed by the client.
375 if k not in self._args:
376 data[k] = meta['default']()
377 continue
378
379 v = self._args[k]
380
381 # Sets may be expressed as lists. Silently normalize.
382 if meta['type'] == 'set' and isinstance(v, list):
383 v = set(v)
384
385 # TODO consider more/stronger type validation.
386
387 data[k] = v
358 388
359 389 return data
360 390
361 391 def getprotocaps(self):
362 392 # Protocol capabilities are currently not implemented for HTTP V2.
363 393 return set()
364 394
365 395 def getpayload(self):
366 396 raise NotImplementedError
367 397
368 398 @contextlib.contextmanager
369 399 def mayberedirectstdio(self):
370 400 raise NotImplementedError
371 401
372 402 def client(self):
373 403 raise NotImplementedError
374 404
375 405 def addcapabilities(self, repo, caps):
376 406 return caps
377 407
378 408 def checkperm(self, perm):
379 409 raise NotImplementedError
380 410
381 411 def httpv2apidescriptor(req, repo):
382 412 proto = httpv2protocolhandler(req, repo.ui)
383 413
384 414 return _capabilitiesv2(repo, proto)
385 415
386 416 def _capabilitiesv2(repo, proto):
387 417 """Obtain the set of capabilities for version 2 transports.
388 418
389 419 These capabilities are distinct from the capabilities for version 1
390 420 transports.
391 421 """
392 422 compression = []
393 423 for engine in wireprototypes.supportedcompengines(repo.ui, util.SERVERROLE):
394 424 compression.append({
395 425 b'name': engine.wireprotosupport().name,
396 426 })
397 427
398 428 caps = {
399 429 'commands': {},
400 430 'compression': compression,
401 431 'framingmediatypes': [FRAMINGTYPE],
402 432 }
403 433
404 434 # TODO expose available changesetdata fields.
405 435
406 436 for command, entry in COMMANDS.items():
437 args = {arg: meta['example'] for arg, meta in entry.args.items()}
438
407 439 caps['commands'][command] = {
408 'args': entry.args,
440 'args': args,
409 441 'permissions': [entry.permission],
410 442 }
411 443
412 444 if streamclone.allowservergeneration(repo):
413 445 caps['rawrepoformats'] = sorted(repo.requirements &
414 446 repo.supportedformats)
415 447
416 448 return proto.addcapabilities(repo, caps)
417 449
418 450 def builddeltarequests(store, nodes, haveparents):
419 451 """Build a series of revision delta requests against a backend store.
420 452
421 453 Returns a list of revision numbers in the order they should be sent
422 454 and a list of ``irevisiondeltarequest`` instances to be made against
423 455 the backend store.
424 456 """
425 457 # We sort and send nodes in DAG order because this is optimal for
426 458 # storage emission.
427 459 # TODO we may want a better storage API here - one where we can throw
428 460 # a list of nodes and delta preconditions over a figurative wall and
429 461 # have the storage backend figure it out for us.
430 462 revs = dagop.linearize({store.rev(n) for n in nodes}, store.parentrevs)
431 463
432 464 requests = []
433 465 seenrevs = set()
434 466
435 467 for rev in revs:
436 468 node = store.node(rev)
437 469 parentnodes = store.parents(node)
438 470 parentrevs = [store.rev(n) for n in parentnodes]
439 471 deltabaserev = store.deltaparent(rev)
440 472 deltabasenode = store.node(deltabaserev)
441 473
442 474 # The choice of whether to send a fulltext revision or a delta and
443 475 # what delta to send is governed by a few factors.
444 476 #
445 477 # To send a delta, we need to ensure the receiver is capable of
446 478 # decoding it. And that requires the receiver to have the base
447 479 # revision the delta is against.
448 480 #
449 481 # We can only guarantee the receiver has the base revision if
450 482 # a) we've already sent the revision as part of this group
451 483 # b) the receiver has indicated they already have the revision.
452 484 # And the mechanism for "b" is the client indicating they have
453 485 # parent revisions. So this means we can only send the delta if
454 486 # it is sent before or it is against a delta and the receiver says
455 487 # they have a parent.
456 488
457 489 # We can send storage delta if it is against a revision we've sent
458 490 # in this group.
459 491 if deltabaserev != nullrev and deltabaserev in seenrevs:
460 492 basenode = deltabasenode
461 493
462 494 # We can send storage delta if it is against a parent revision and
463 495 # the receiver indicates they have the parents.
464 496 elif (deltabaserev != nullrev and deltabaserev in parentrevs
465 497 and haveparents):
466 498 basenode = deltabasenode
467 499
468 500 # Otherwise the storage delta isn't appropriate. Fall back to
469 501 # using another delta, if possible.
470 502
471 503 # Use p1 if we've emitted it or receiver says they have it.
472 504 elif parentrevs[0] != nullrev and (
473 505 parentrevs[0] in seenrevs or haveparents):
474 506 basenode = parentnodes[0]
475 507
476 508 # Use p2 if we've emitted it or receiver says they have it.
477 509 elif parentrevs[1] != nullrev and (
478 510 parentrevs[1] in seenrevs or haveparents):
479 511 basenode = parentnodes[1]
480 512
481 513 # Nothing appropriate to delta against. Send the full revision.
482 514 else:
483 515 basenode = nullid
484 516
485 517 requests.append(changegroup.revisiondeltarequest(
486 518 node=node,
487 519 p1node=parentnodes[0],
488 520 p2node=parentnodes[1],
489 521 # Receiver deals with linknode resolution.
490 522 linknode=nullid,
491 523 basenode=basenode,
492 524 ))
493 525
494 526 seenrevs.add(rev)
495 527
496 528 return revs, requests
497 529
498 530 def wireprotocommand(name, args=None, permission='push'):
499 531 """Decorator to declare a wire protocol command.
500 532
501 533 ``name`` is the name of the wire protocol command being provided.
502 534
503 ``args`` is a dict of argument names to example values.
535 ``args`` is a dict defining arguments accepted by the command. Keys are
536 the argument name. Values are dicts with the following keys:
537
538 ``type``
539 The argument data type. Must be one of the following string
540 literals: ``bytes``, ``int``, ``list``, ``dict``, ``set``,
541 or ``bool``.
542
543 ``default``
544 A callable returning the default value for this argument. If not
545 specified, ``None`` will be the default value.
546
547 ``required``
548 Bool indicating whether the argument is required.
549
550 ``example``
551 An example value for this argument.
504 552
505 553 ``permission`` defines the permission type needed to run this command.
506 554 Can be ``push`` or ``pull``. These roughly map to read-write and read-only,
507 555 respectively. Default is to assume command requires ``push`` permissions
508 556 because otherwise commands not declaring their permissions could modify
509 557 a repository that is supposed to be read-only.
510 558
511 559 Wire protocol commands are generators of objects to be serialized and
512 560 sent to the client.
513 561
514 562 If a command raises an uncaught exception, this will be translated into
515 563 a command error.
516 564 """
517 565 transports = {k for k, v in wireprototypes.TRANSPORTS.items()
518 566 if v['version'] == 2}
519 567
520 568 if permission not in ('push', 'pull'):
521 569 raise error.ProgrammingError('invalid wire protocol permission; '
522 570 'got %s; expected "push" or "pull"' %
523 571 permission)
524 572
525 573 if args is None:
526 574 args = {}
527 575
528 576 if not isinstance(args, dict):
529 577 raise error.ProgrammingError('arguments for version 2 commands '
530 578 'must be declared as dicts')
531 579
580 for arg, meta in args.items():
581 if arg == '*':
582 raise error.ProgrammingError('* argument name not allowed on '
583 'version 2 commands')
584
585 if not isinstance(meta, dict):
586 raise error.ProgrammingError('arguments for version 2 commands '
587 'must declare metadata as a dict')
588
589 if 'type' not in meta:
590 raise error.ProgrammingError('%s argument for command %s does not '
591 'declare type field' % (arg, name))
592
593 if meta['type'] not in ('bytes', 'int', 'list', 'dict', 'set', 'bool'):
594 raise error.ProgrammingError('%s argument for command %s has '
595 'illegal type: %s' % (arg, name,
596 meta['type']))
597
598 if 'example' not in meta:
599 raise error.ProgrammingError('%s argument for command %s does not '
600 'declare example field' % (arg, name))
601
602 if 'default' in meta and meta.get('required'):
603 raise error.ProgrammingError('%s argument for command %s is marked '
604 'as required but has a default value' %
605 (arg, name))
606
607 meta.setdefault('default', lambda: None)
608 meta.setdefault('required', False)
609
532 610 def register(func):
533 611 if name in COMMANDS:
534 612 raise error.ProgrammingError('%s command already registered '
535 613 'for version 2' % name)
536 614
537 615 COMMANDS[name] = wireprototypes.commandentry(
538 616 func, args=args, transports=transports, permission=permission)
539 617
540 618 return func
541 619
542 620 return register
543 621
544 622 @wireprotocommand('branchmap', permission='pull')
545 623 def branchmapv2(repo, proto):
546 624 yield {encoding.fromlocal(k): v
547 625 for k, v in repo.branchmap().iteritems()}
548 626
549 627 @wireprotocommand('capabilities', permission='pull')
550 628 def capabilitiesv2(repo, proto):
551 629 yield _capabilitiesv2(repo, proto)
552 630
553 @wireprotocommand('changesetdata',
554 args={
555 'noderange': [[b'0123456...'], [b'abcdef...']],
556 'nodes': [b'0123456...'],
557 'fields': {b'parents', b'revision'},
558 },
559 permission='pull')
560 def changesetdata(repo, proto, noderange=None, nodes=None, fields=None):
561 fields = fields or set()
562
631 @wireprotocommand(
632 'changesetdata',
633 args={
634 'noderange': {
635 'type': 'list',
636 'example': [[b'0123456...'], [b'abcdef...']],
637 },
638 'nodes': {
639 'type': 'list',
640 'example': [b'0123456...'],
641 },
642 'fields': {
643 'type': 'set',
644 'default': set,
645 'example': {b'parents', b'revision'},
646 },
647 },
648 permission='pull')
649 def changesetdata(repo, proto, noderange, nodes, fields):
563 650 # TODO look for unknown fields and abort when they can't be serviced.
564 651
565 652 if noderange is None and nodes is None:
566 653 raise error.WireprotoCommandError(
567 654 'noderange or nodes must be defined')
568 655
569 656 if noderange is not None:
570 657 if len(noderange) != 2:
571 658 raise error.WireprotoCommandError(
572 659 'noderange must consist of 2 elements')
573 660
574 661 if not noderange[1]:
575 662 raise error.WireprotoCommandError(
576 663 'heads in noderange request cannot be empty')
577 664
578 665 cl = repo.changelog
579 666 hasnode = cl.hasnode
580 667
581 668 seen = set()
582 669 outgoing = []
583 670
584 671 if nodes is not None:
585 672 outgoing.extend(n for n in nodes if hasnode(n))
586 673 seen |= set(outgoing)
587 674
588 675 if noderange is not None:
589 676 if noderange[0]:
590 677 common = [n for n in noderange[0] if hasnode(n)]
591 678 else:
592 679 common = [nullid]
593 680
594 681 for n in discovery.outgoing(repo, common, noderange[1]).missing:
595 682 if n not in seen:
596 683 outgoing.append(n)
597 684 # Don't need to add to seen here because this is the final
598 685 # source of nodes and there should be no duplicates in this
599 686 # list.
600 687
601 688 seen.clear()
602 689 publishing = repo.publishing()
603 690
604 691 if outgoing:
605 692 repo.hook('preoutgoing', throw=True, source='serve')
606 693
607 694 yield {
608 695 b'totalitems': len(outgoing),
609 696 }
610 697
611 698 # The phases of nodes already transferred to the client may have changed
612 699 # since the client last requested data. We send phase-only records
613 700 # for these revisions, if requested.
614 701 if b'phase' in fields and noderange is not None:
615 702 # TODO skip nodes whose phase will be reflected by a node in the
616 703 # outgoing set. This is purely an optimization to reduce data
617 704 # size.
618 705 for node in noderange[0]:
619 706 yield {
620 707 b'node': node,
621 708 b'phase': b'public' if publishing else repo[node].phasestr()
622 709 }
623 710
624 711 nodebookmarks = {}
625 712 for mark, node in repo._bookmarks.items():
626 713 nodebookmarks.setdefault(node, set()).add(mark)
627 714
628 715 # It is already topologically sorted by revision number.
629 716 for node in outgoing:
630 717 d = {
631 718 b'node': node,
632 719 }
633 720
634 721 if b'parents' in fields:
635 722 d[b'parents'] = cl.parents(node)
636 723
637 724 if b'phase' in fields:
638 725 if publishing:
639 726 d[b'phase'] = b'public'
640 727 else:
641 728 ctx = repo[node]
642 729 d[b'phase'] = ctx.phasestr()
643 730
644 731 if b'bookmarks' in fields and node in nodebookmarks:
645 732 d[b'bookmarks'] = sorted(nodebookmarks[node])
646 733 del nodebookmarks[node]
647 734
648 735 revisiondata = None
649 736
650 737 if b'revision' in fields:
651 738 revisiondata = cl.revision(node, raw=True)
652 739 d[b'revisionsize'] = len(revisiondata)
653 740
654 741 # TODO make it possible for extensions to wrap a function or register
655 742 # a handler to service custom fields.
656 743
657 744 yield d
658 745
659 746 if revisiondata is not None:
660 747 yield revisiondata
661 748
662 749 # If requested, send bookmarks from nodes that didn't have revision
663 750 # data sent so receiver is aware of any bookmark updates.
664 751 if b'bookmarks' in fields:
665 752 for node, marks in sorted(nodebookmarks.iteritems()):
666 753 yield {
667 754 b'node': node,
668 755 b'bookmarks': sorted(marks),
669 756 }
670 757
671 758 class FileAccessError(Exception):
672 759 """Represents an error accessing a specific file."""
673 760
674 761 def __init__(self, path, msg, args):
675 762 self.path = path
676 763 self.msg = msg
677 764 self.args = args
678 765
679 766 def getfilestore(repo, proto, path):
680 767 """Obtain a file storage object for use with wire protocol.
681 768
682 769 Exists as a standalone function so extensions can monkeypatch to add
683 770 access control.
684 771 """
685 772 # This seems to work even if the file doesn't exist. So catch
686 773 # "empty" files and return an error.
687 774 fl = repo.file(path)
688 775
689 776 if not len(fl):
690 777 raise FileAccessError(path, 'unknown file: %s', (path,))
691 778
692 779 return fl
693 780
694 @wireprotocommand('filedata',
695 args={
696 'haveparents': True,
697 'nodes': [b'0123456...'],
698 'fields': [b'parents', b'revision'],
699 'path': b'foo.txt',
700 },
701 permission='pull')
702 def filedata(repo, proto, haveparents=False, nodes=None, fields=None,
703 path=None):
704 fields = fields or set()
705
706 if nodes is None:
707 raise error.WireprotoCommandError('nodes argument must be defined')
708
709 if path is None:
710 raise error.WireprotoCommandError('path argument must be defined')
711
781 @wireprotocommand(
782 'filedata',
783 args={
784 'haveparents': {
785 'type': 'bool',
786 'default': lambda: False,
787 'example': True,
788 },
789 'nodes': {
790 'type': 'list',
791 'required': True,
792 'example': [b'0123456...'],
793 },
794 'fields': {
795 'type': 'set',
796 'default': set,
797 'example': {b'parents', b'revision'},
798 },
799 'path': {
800 'type': 'bytes',
801 'required': True,
802 'example': b'foo.txt',
803 }
804 },
805 permission='pull')
806 def filedata(repo, proto, haveparents, nodes, fields, path):
712 807 try:
713 808 # Extensions may wish to access the protocol handler.
714 809 store = getfilestore(repo, proto, path)
715 810 except FileAccessError as e:
716 811 raise error.WireprotoCommandError(e.msg, e.args)
717 812
718 813 # Validate requested nodes.
719 814 for node in nodes:
720 815 try:
721 816 store.rev(node)
722 817 except error.LookupError:
723 818 raise error.WireprotoCommandError('unknown file node: %s',
724 819 (hex(node),))
725 820
726 821 revs, requests = builddeltarequests(store, nodes, haveparents)
727 822
728 823 yield {
729 824 b'totalitems': len(revs),
730 825 }
731 826
732 827 if b'revision' in fields:
733 828 deltas = store.emitrevisiondeltas(requests)
734 829 else:
735 830 deltas = None
736 831
737 832 for rev in revs:
738 833 node = store.node(rev)
739 834
740 835 if deltas is not None:
741 836 delta = next(deltas)
742 837 else:
743 838 delta = None
744 839
745 840 d = {
746 841 b'node': node,
747 842 }
748 843
749 844 if b'parents' in fields:
750 845 d[b'parents'] = store.parents(node)
751 846
752 847 if b'revision' in fields:
753 848 assert delta is not None
754 849 assert delta.flags == 0
755 850 assert d[b'node'] == delta.node
756 851
757 852 if delta.revision is not None:
758 853 revisiondata = delta.revision
759 854 d[b'revisionsize'] = len(revisiondata)
760 855 else:
761 856 d[b'deltabasenode'] = delta.basenode
762 857 revisiondata = delta.delta
763 858 d[b'deltasize'] = len(revisiondata)
764 859 else:
765 860 revisiondata = None
766 861
767 862 yield d
768 863
769 864 if revisiondata is not None:
770 865 yield revisiondata
771 866
772 867 if deltas is not None:
773 868 try:
774 869 next(deltas)
775 870 raise error.ProgrammingError('should not have more deltas')
776 871 except GeneratorExit:
777 872 pass
778 873
779 @wireprotocommand('heads',
780 args={
781 'publiconly': False,
782 },
783 permission='pull')
784 def headsv2(repo, proto, publiconly=False):
874 @wireprotocommand(
875 'heads',
876 args={
877 'publiconly': {
878 'type': 'bool',
879 'default': lambda: False,
880 'example': False,
881 },
882 },
883 permission='pull')
884 def headsv2(repo, proto, publiconly):
785 885 if publiconly:
786 886 repo = repo.filtered('immutable')
787 887
788 888 yield repo.heads()
789 889
790 @wireprotocommand('known',
791 args={
792 'nodes': [b'deadbeef'],
793 },
794 permission='pull')
795 def knownv2(repo, proto, nodes=None):
796 nodes = nodes or []
890 @wireprotocommand(
891 'known',
892 args={
893 'nodes': {
894 'type': 'list',
895 'default': list,
896 'example': [b'deadbeef'],
897 },
898 },
899 permission='pull')
900 def knownv2(repo, proto, nodes):
797 901 result = b''.join(b'1' if n else b'0' for n in repo.known(nodes))
798 902 yield result
799 903
800 @wireprotocommand('listkeys',
801 args={
802 'namespace': b'ns',
803 },
804 permission='pull')
805 def listkeysv2(repo, proto, namespace=None):
904 @wireprotocommand(
905 'listkeys',
906 args={
907 'namespace': {
908 'type': 'bytes',
909 'required': True,
910 'example': b'ns',
911 },
912 },
913 permission='pull')
914 def listkeysv2(repo, proto, namespace):
806 915 keys = repo.listkeys(encoding.tolocal(namespace))
807 916 keys = {encoding.fromlocal(k): encoding.fromlocal(v)
808 917 for k, v in keys.iteritems()}
809 918
810 919 yield keys
811 920
812 @wireprotocommand('lookup',
813 args={
814 'key': b'foo',
815 },
816 permission='pull')
921 @wireprotocommand(
922 'lookup',
923 args={
924 'key': {
925 'type': 'bytes',
926 'required': True,
927 'example': b'foo',
928 },
929 },
930 permission='pull')
817 931 def lookupv2(repo, proto, key):
818 932 key = encoding.tolocal(key)
819 933
820 934 # TODO handle exception.
821 935 node = repo.lookup(key)
822 936
823 937 yield node
824 938
825 @wireprotocommand('manifestdata',
826 args={
827 'nodes': [b'0123456...'],
828 'haveparents': True,
829 'fields': [b'parents', b'revision'],
830 'tree': b'',
831 },
832 permission='pull')
833 def manifestdata(repo, proto, haveparents=False, nodes=None, fields=None,
834 tree=None):
835 fields = fields or set()
836
837 if nodes is None:
838 raise error.WireprotoCommandError(
839 'nodes argument must be defined')
840
841 if tree is None:
842 raise error.WireprotoCommandError(
843 'tree argument must be defined')
844
939 @wireprotocommand(
940 'manifestdata',
941 args={
942 'nodes': {
943 'type': 'list',
944 'required': True,
945 'example': [b'0123456...'],
946 },
947 'haveparents': {
948 'type': 'bool',
949 'default': lambda: False,
950 'example': True,
951 },
952 'fields': {
953 'type': 'set',
954 'default': set,
955 'example': {b'parents', b'revision'},
956 },
957 'tree': {
958 'type': 'bytes',
959 'required': True,
960 'example': b'',
961 },
962 },
963 permission='pull')
964 def manifestdata(repo, proto, haveparents, nodes, fields, tree):
845 965 store = repo.manifestlog.getstorage(tree)
846 966
847 967 # Validate the node is known and abort on unknown revisions.
848 968 for node in nodes:
849 969 try:
850 970 store.rev(node)
851 971 except error.LookupError:
852 972 raise error.WireprotoCommandError(
853 973 'unknown node: %s', (node,))
854 974
855 975 revs, requests = builddeltarequests(store, nodes, haveparents)
856 976
857 977 yield {
858 978 b'totalitems': len(revs),
859 979 }
860 980
861 981 if b'revision' in fields:
862 982 deltas = store.emitrevisiondeltas(requests)
863 983 else:
864 984 deltas = None
865 985
866 986 for rev in revs:
867 987 node = store.node(rev)
868 988
869 989 if deltas is not None:
870 990 delta = next(deltas)
871 991 else:
872 992 delta = None
873 993
874 994 d = {
875 995 b'node': node,
876 996 }
877 997
878 998 if b'parents' in fields:
879 999 d[b'parents'] = store.parents(node)
880 1000
881 1001 if b'revision' in fields:
882 1002 assert delta is not None
883 1003 assert delta.flags == 0
884 1004 assert d[b'node'] == delta.node
885 1005
886 1006 if delta.revision is not None:
887 1007 revisiondata = delta.revision
888 1008 d[b'revisionsize'] = len(revisiondata)
889 1009 else:
890 1010 d[b'deltabasenode'] = delta.basenode
891 1011 revisiondata = delta.delta
892 1012 d[b'deltasize'] = len(revisiondata)
893 1013 else:
894 1014 revisiondata = None
895 1015
896 1016 yield d
897 1017
898 1018 if revisiondata is not None:
899 1019 yield revisiondata
900 1020
901 1021 if deltas is not None:
902 1022 try:
903 1023 next(deltas)
904 1024 raise error.ProgrammingError('should not have more deltas')
905 1025 except GeneratorExit:
906 1026 pass
907 1027
908 @wireprotocommand('pushkey',
909 args={
910 'namespace': b'ns',
911 'key': b'key',
912 'old': b'old',
913 'new': b'new',
914 },
915 permission='push')
1028 @wireprotocommand(
1029 'pushkey',
1030 args={
1031 'namespace': {
1032 'type': 'bytes',
1033 'required': True,
1034 'example': b'ns',
1035 },
1036 'key': {
1037 'type': 'bytes',
1038 'required': True,
1039 'example': b'key',
1040 },
1041 'old': {
1042 'type': 'bytes',
1043 'required': True,
1044 'example': b'old',
1045 },
1046 'new': {
1047 'type': 'bytes',
1048 'required': True,
1049 'example': 'new',
1050 },
1051 },
1052 permission='push')
916 1053 def pushkeyv2(repo, proto, namespace, key, old, new):
917 1054 # TODO handle ui output redirection
918 1055 yield repo.pushkey(encoding.tolocal(namespace),
919 1056 encoding.tolocal(key),
920 1057 encoding.tolocal(old),
921 1058 encoding.tolocal(new))
@@ -1,749 +1,749
1 1 #require no-chg
2 2
3 3 $ . $TESTDIR/wireprotohelpers.sh
4 4
5 5 $ cat >> $HGRCPATH << EOF
6 6 > [web]
7 7 > push_ssl = false
8 8 > allow_push = *
9 9 > EOF
10 10
11 11 $ hg init server
12 12 $ cd server
13 13 $ touch a
14 14 $ hg -q commit -A -m initial
15 15 $ cd ..
16 16
17 17 $ hg serve -R server -p $HGPORT -d --pid-file hg.pid
18 18 $ cat hg.pid >> $DAEMON_PIDS
19 19
20 20 compression formats are advertised in compression capability
21 21
22 22 #if zstd
23 23 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=capabilities' | tr ' ' '\n' | grep '^compression=zstd,zlib$' > /dev/null
24 24 #else
25 25 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=capabilities' | tr ' ' '\n' | grep '^compression=zlib$' > /dev/null
26 26 #endif
27 27
28 28 $ killdaemons.py
29 29
30 30 server.compressionengines can replace engines list wholesale
31 31
32 32 $ hg serve --config server.compressionengines=none -R server -p $HGPORT -d --pid-file hg.pid
33 33 $ cat hg.pid > $DAEMON_PIDS
34 34 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=capabilities' | tr ' ' '\n' | grep '^compression=none$' > /dev/null
35 35
36 36 $ killdaemons.py
37 37
38 38 Order of engines can also change
39 39
40 40 $ hg serve --config server.compressionengines=none,zlib -R server -p $HGPORT -d --pid-file hg.pid
41 41 $ cat hg.pid > $DAEMON_PIDS
42 42 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=capabilities' | tr ' ' '\n' | grep '^compression=none,zlib$' > /dev/null
43 43
44 44 $ killdaemons.py
45 45
46 46 Start a default server again
47 47
48 48 $ hg serve -R server -p $HGPORT -d --pid-file hg.pid
49 49 $ cat hg.pid > $DAEMON_PIDS
50 50
51 51 Server should send application/mercurial-0.1 to clients if no Accept is used
52 52
53 53 $ get-with-headers.py --headeronly $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' -
54 54 200 Script output follows
55 55 content-type: application/mercurial-0.1
56 56 date: $HTTP_DATE$
57 57 server: testing stub value
58 58 transfer-encoding: chunked
59 59
60 60 Server should send application/mercurial-0.1 when client says it wants it
61 61
62 62 $ get-with-headers.py --hgproto '0.1' --headeronly $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' -
63 63 200 Script output follows
64 64 content-type: application/mercurial-0.1
65 65 date: $HTTP_DATE$
66 66 server: testing stub value
67 67 transfer-encoding: chunked
68 68
69 69 Server should send application/mercurial-0.2 when client says it wants it
70 70
71 71 $ get-with-headers.py --hgproto '0.2' --headeronly $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' -
72 72 200 Script output follows
73 73 content-type: application/mercurial-0.2
74 74 date: $HTTP_DATE$
75 75 server: testing stub value
76 76 transfer-encoding: chunked
77 77
78 78 $ get-with-headers.py --hgproto '0.1 0.2' --headeronly $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' -
79 79 200 Script output follows
80 80 content-type: application/mercurial-0.2
81 81 date: $HTTP_DATE$
82 82 server: testing stub value
83 83 transfer-encoding: chunked
84 84
85 85 Requesting a compression format that server doesn't support results will fall back to 0.1
86 86
87 87 $ get-with-headers.py --hgproto '0.2 comp=aa' --headeronly $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' -
88 88 200 Script output follows
89 89 content-type: application/mercurial-0.1
90 90 date: $HTTP_DATE$
91 91 server: testing stub value
92 92 transfer-encoding: chunked
93 93
94 94 #if zstd
95 95 zstd is used if available
96 96
97 97 $ get-with-headers.py --hgproto '0.2 comp=zstd' $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' > resp
98 98 $ f --size --hexdump --bytes 36 --sha1 resp
99 99 resp: size=248, sha1=4d8d8f87fb82bd542ce52881fdc94f850748
100 100 0000: 32 30 30 20 53 63 72 69 70 74 20 6f 75 74 70 75 |200 Script outpu|
101 101 0010: 74 20 66 6f 6c 6c 6f 77 73 0a 0a 04 7a 73 74 64 |t follows...zstd|
102 102 0020: 28 b5 2f fd |(./.|
103 103
104 104 #endif
105 105
106 106 application/mercurial-0.2 is not yet used on non-streaming responses
107 107
108 108 $ get-with-headers.py --hgproto '0.2' $LOCALIP:$HGPORT '?cmd=heads' -
109 109 200 Script output follows
110 110 content-length: 41
111 111 content-type: application/mercurial-0.1
112 112 date: $HTTP_DATE$
113 113 server: testing stub value
114 114
115 115 e93700bd72895c5addab234c56d4024b487a362f
116 116
117 117 Now test protocol preference usage
118 118
119 119 $ killdaemons.py
120 120 $ hg serve --config server.compressionengines=none,zlib -R server -p $HGPORT -d --pid-file hg.pid
121 121 $ cat hg.pid > $DAEMON_PIDS
122 122
123 123 No Accept will send 0.1+zlib, even though "none" is preferred b/c "none" isn't supported on 0.1
124 124
125 125 $ get-with-headers.py --headeronly $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' Content-Type
126 126 200 Script output follows
127 127 content-type: application/mercurial-0.1
128 128
129 129 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' > resp
130 130 $ f --size --hexdump --bytes 28 --sha1 resp
131 131 resp: size=227, sha1=35a4c074da74f32f5440da3cbf04
132 132 0000: 32 30 30 20 53 63 72 69 70 74 20 6f 75 74 70 75 |200 Script outpu|
133 133 0010: 74 20 66 6f 6c 6c 6f 77 73 0a 0a 78 |t follows..x|
134 134
135 135 Explicit 0.1 will send zlib because "none" isn't supported on 0.1
136 136
137 137 $ get-with-headers.py --hgproto '0.1' $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' > resp
138 138 $ f --size --hexdump --bytes 28 --sha1 resp
139 139 resp: size=227, sha1=35a4c074da74f32f5440da3cbf04
140 140 0000: 32 30 30 20 53 63 72 69 70 74 20 6f 75 74 70 75 |200 Script outpu|
141 141 0010: 74 20 66 6f 6c 6c 6f 77 73 0a 0a 78 |t follows..x|
142 142
143 143 0.2 with no compression will get "none" because that is server's preference
144 144 (spec says ZL and UN are implicitly supported)
145 145
146 146 $ get-with-headers.py --hgproto '0.2' $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' > resp
147 147 $ f --size --hexdump --bytes 32 --sha1 resp
148 148 resp: size=432, sha1=ac931b412ec185a02e0e5bcff98dac83
149 149 0000: 32 30 30 20 53 63 72 69 70 74 20 6f 75 74 70 75 |200 Script outpu|
150 150 0010: 74 20 66 6f 6c 6c 6f 77 73 0a 0a 04 6e 6f 6e 65 |t follows...none|
151 151
152 152 Client receives server preference even if local order doesn't match
153 153
154 154 $ get-with-headers.py --hgproto '0.2 comp=zlib,none' $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' > resp
155 155 $ f --size --hexdump --bytes 32 --sha1 resp
156 156 resp: size=432, sha1=ac931b412ec185a02e0e5bcff98dac83
157 157 0000: 32 30 30 20 53 63 72 69 70 74 20 6f 75 74 70 75 |200 Script outpu|
158 158 0010: 74 20 66 6f 6c 6c 6f 77 73 0a 0a 04 6e 6f 6e 65 |t follows...none|
159 159
160 160 Client receives only supported format even if not server preferred format
161 161
162 162 $ get-with-headers.py --hgproto '0.2 comp=zlib' $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' > resp
163 163 $ f --size --hexdump --bytes 33 --sha1 resp
164 164 resp: size=232, sha1=a1c727f0c9693ca15742a75c30419bc36
165 165 0000: 32 30 30 20 53 63 72 69 70 74 20 6f 75 74 70 75 |200 Script outpu|
166 166 0010: 74 20 66 6f 6c 6c 6f 77 73 0a 0a 04 7a 6c 69 62 |t follows...zlib|
167 167 0020: 78 |x|
168 168
169 169 $ killdaemons.py
170 170 $ cd ..
171 171
172 172 Test listkeys for listing namespaces
173 173
174 174 $ hg init empty
175 175 $ hg -R empty serve -p $HGPORT -d --pid-file hg.pid
176 176 $ cat hg.pid > $DAEMON_PIDS
177 177
178 178 $ hg --verbose debugwireproto http://$LOCALIP:$HGPORT << EOF
179 179 > command listkeys
180 180 > namespace namespaces
181 181 > EOF
182 182 s> GET /?cmd=capabilities HTTP/1.1\r\n
183 183 s> Accept-Encoding: identity\r\n
184 184 s> accept: application/mercurial-0.1\r\n
185 185 s> host: $LOCALIP:$HGPORT\r\n (glob)
186 186 s> user-agent: Mercurial debugwireproto\r\n
187 187 s> \r\n
188 188 s> makefile('rb', None)
189 189 s> HTTP/1.1 200 Script output follows\r\n
190 190 s> Server: testing stub value\r\n
191 191 s> Date: $HTTP_DATE$\r\n
192 192 s> Content-Type: application/mercurial-0.1\r\n
193 193 s> Content-Length: *\r\n (glob)
194 194 s> \r\n
195 195 s> batch 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
196 196 sending listkeys command
197 197 s> GET /?cmd=listkeys HTTP/1.1\r\n
198 198 s> Accept-Encoding: identity\r\n
199 199 s> vary: X-HgArg-1,X-HgProto-1\r\n
200 200 s> x-hgarg-1: namespace=namespaces\r\n
201 201 s> x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
202 202 s> accept: application/mercurial-0.1\r\n
203 203 s> host: $LOCALIP:$HGPORT\r\n (glob)
204 204 s> user-agent: Mercurial debugwireproto\r\n
205 205 s> \r\n
206 206 s> makefile('rb', None)
207 207 s> HTTP/1.1 200 Script output follows\r\n
208 208 s> Server: testing stub value\r\n
209 209 s> Date: $HTTP_DATE$\r\n
210 210 s> Content-Type: application/mercurial-0.1\r\n
211 211 s> Content-Length: 30\r\n
212 212 s> \r\n
213 213 s> bookmarks\t\n
214 214 s> namespaces\t\n
215 215 s> phases\t
216 216 response: {
217 217 b'bookmarks': b'',
218 218 b'namespaces': b'',
219 219 b'phases': b''
220 220 }
221 221
222 222 Same thing, but with "httprequest" command
223 223
224 224 $ hg --verbose debugwireproto --peer raw http://$LOCALIP:$HGPORT << EOF
225 225 > httprequest GET ?cmd=listkeys
226 226 > user-agent: test
227 227 > x-hgarg-1: namespace=namespaces
228 228 > EOF
229 229 using raw connection to peer
230 230 s> GET /?cmd=listkeys HTTP/1.1\r\n
231 231 s> Accept-Encoding: identity\r\n
232 232 s> user-agent: test\r\n
233 233 s> x-hgarg-1: namespace=namespaces\r\n
234 234 s> host: $LOCALIP:$HGPORT\r\n (glob)
235 235 s> \r\n
236 236 s> makefile('rb', None)
237 237 s> HTTP/1.1 200 Script output follows\r\n
238 238 s> Server: testing stub value\r\n
239 239 s> Date: $HTTP_DATE$\r\n
240 240 s> Content-Type: application/mercurial-0.1\r\n
241 241 s> Content-Length: 30\r\n
242 242 s> \r\n
243 243 s> bookmarks\t\n
244 244 s> namespaces\t\n
245 245 s> phases\t
246 246
247 247 Client with HTTPv2 enabled advertises that and gets old capabilities response from old server
248 248
249 249 $ hg --config experimental.httppeer.advertise-v2=true --verbose debugwireproto http://$LOCALIP:$HGPORT << EOF
250 250 > command heads
251 251 > EOF
252 252 s> GET /?cmd=capabilities HTTP/1.1\r\n
253 253 s> Accept-Encoding: identity\r\n
254 254 s> vary: X-HgProto-1,X-HgUpgrade-1\r\n
255 255 s> x-hgproto-1: cbor\r\n
256 256 s> x-hgupgrade-1: exp-http-v2-0001\r\n
257 257 s> accept: application/mercurial-0.1\r\n
258 258 s> host: $LOCALIP:$HGPORT\r\n (glob)
259 259 s> user-agent: Mercurial debugwireproto\r\n
260 260 s> \r\n
261 261 s> makefile('rb', None)
262 262 s> HTTP/1.1 200 Script output follows\r\n
263 263 s> Server: testing stub value\r\n
264 264 s> Date: $HTTP_DATE$\r\n
265 265 s> Content-Type: application/mercurial-0.1\r\n
266 266 s> Content-Length: *\r\n (glob)
267 267 s> \r\n
268 268 s> batch 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
269 269 sending heads command
270 270 s> GET /?cmd=heads HTTP/1.1\r\n
271 271 s> Accept-Encoding: identity\r\n
272 272 s> vary: X-HgProto-1\r\n
273 273 s> x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
274 274 s> accept: application/mercurial-0.1\r\n
275 275 s> host: $LOCALIP:$HGPORT\r\n (glob)
276 276 s> user-agent: Mercurial debugwireproto\r\n
277 277 s> \r\n
278 278 s> makefile('rb', None)
279 279 s> HTTP/1.1 200 Script output follows\r\n
280 280 s> Server: testing stub value\r\n
281 281 s> Date: $HTTP_DATE$\r\n
282 282 s> Content-Type: application/mercurial-0.1\r\n
283 283 s> Content-Length: 41\r\n
284 284 s> \r\n
285 285 s> 0000000000000000000000000000000000000000\n
286 286 response: [
287 287 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
288 288 ]
289 289
290 290 $ killdaemons.py
291 291 $ enablehttpv2 empty
292 292 $ hg --config server.compressionengines=zlib -R empty serve -p $HGPORT -d --pid-file hg.pid
293 293 $ cat hg.pid > $DAEMON_PIDS
294 294
295 295 Client with HTTPv2 enabled automatically upgrades if the server supports it
296 296
297 297 $ hg --config experimental.httppeer.advertise-v2=true --verbose debugwireproto http://$LOCALIP:$HGPORT << EOF
298 298 > command heads
299 299 > EOF
300 300 s> GET /?cmd=capabilities HTTP/1.1\r\n
301 301 s> Accept-Encoding: identity\r\n
302 302 s> vary: X-HgProto-1,X-HgUpgrade-1\r\n
303 303 s> x-hgproto-1: cbor\r\n
304 304 s> x-hgupgrade-1: exp-http-v2-0001\r\n
305 305 s> accept: application/mercurial-0.1\r\n
306 306 s> host: $LOCALIP:$HGPORT\r\n (glob)
307 307 s> user-agent: Mercurial debugwireproto\r\n
308 308 s> \r\n
309 309 s> makefile('rb', None)
310 310 s> HTTP/1.1 200 OK\r\n
311 311 s> Server: testing stub value\r\n
312 312 s> Date: $HTTP_DATE$\r\n
313 313 s> Content-Type: application/mercurial-cbor\r\n
314 314 s> Content-Length: *\r\n (glob)
315 315 s> \r\n
316 s> \xa3GapibaseDapi/Dapis\xa1Pexp-http-v2-0001\xa4Hcommands\xaaIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa3Ffields\xd9\x01\x02\x82GparentsHrevisionInoderange\x82\x81J0123456...\x81Iabcdef...Enodes\x81J0123456...Kpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\x82GparentsHrevisionKhaveparents\xf5Enodes\x81J0123456...DpathGfoo.txtKpermissions\x81DpullEheads\xa2Dargs\xa1Jpubliconly\xf4Kpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\x81HdeadbeefKpermissions\x81DpullHlistkeys\xa2Dargs\xa1InamespaceBnsKpermissions\x81DpullFlookup\xa2Dargs\xa1CkeyCfooKpermissions\x81DpullLmanifestdata\xa2Dargs\xa4Ffields\x82GparentsHrevisionKhaveparents\xf5Enodes\x81J0123456...Dtree@Kpermissions\x81DpullGpushkey\xa2Dargs\xa4CkeyCkeyInamespaceBnsCnewCnewColdColdKpermissions\x81DpushKcompression\x81\xa1DnameDzlibQframingmediatypes\x81X&application/mercurial-exp-framing-0005Nrawrepoformats\x82LgeneraldeltaHrevlogv1Nv1capabilitiesY\x01\xd3batch 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
316 s> \xa3GapibaseDapi/Dapis\xa1Pexp-http-v2-0001\xa4Hcommands\xaaIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa3Ffields\xd9\x01\x02\x82GparentsHrevisionInoderange\x82\x81J0123456...\x81Iabcdef...Enodes\x81J0123456...Kpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xf5Enodes\x81J0123456...DpathGfoo.txtKpermissions\x81DpullEheads\xa2Dargs\xa1Jpubliconly\xf4Kpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\x81HdeadbeefKpermissions\x81DpullHlistkeys\xa2Dargs\xa1InamespaceBnsKpermissions\x81DpullFlookup\xa2Dargs\xa1CkeyCfooKpermissions\x81DpullLmanifestdata\xa2Dargs\xa4Ffields\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xf5Enodes\x81J0123456...Dtree@Kpermissions\x81DpullGpushkey\xa2Dargs\xa4CkeyCkeyInamespaceBnsCnewCnewColdColdKpermissions\x81DpushKcompression\x81\xa1DnameDzlibQframingmediatypes\x81X&application/mercurial-exp-framing-0005Nrawrepoformats\x82LgeneraldeltaHrevlogv1Nv1capabilitiesY\x01\xd3batch 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
317 317 sending heads command
318 318 s> POST /api/exp-http-v2-0001/ro/heads HTTP/1.1\r\n
319 319 s> Accept-Encoding: identity\r\n
320 320 s> accept: application/mercurial-exp-framing-0005\r\n
321 321 s> content-type: application/mercurial-exp-framing-0005\r\n
322 322 s> content-length: 20\r\n
323 323 s> host: $LOCALIP:$HGPORT\r\n (glob)
324 324 s> user-agent: Mercurial debugwireproto\r\n
325 325 s> \r\n
326 326 s> \x0c\x00\x00\x01\x00\x01\x01\x11\xa1DnameEheads
327 327 s> makefile('rb', None)
328 328 s> HTTP/1.1 200 OK\r\n
329 329 s> Server: testing stub value\r\n
330 330 s> Date: $HTTP_DATE$\r\n
331 331 s> Content-Type: application/mercurial-exp-framing-0005\r\n
332 332 s> Transfer-Encoding: chunked\r\n
333 333 s> \r\n
334 334 s> 13\r\n
335 335 s> \x0b\x00\x00\x01\x00\x02\x011
336 336 s> \xa1FstatusBok
337 337 s> \r\n
338 338 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
339 339 s> 1e\r\n
340 340 s> \x16\x00\x00\x01\x00\x02\x001
341 341 s> \x81T\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
342 342 s> \r\n
343 343 received frame(size=22; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
344 344 s> 8\r\n
345 345 s> \x00\x00\x00\x01\x00\x02\x002
346 346 s> \r\n
347 347 s> 0\r\n
348 348 s> \r\n
349 349 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
350 350 response: [
351 351 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
352 352 ]
353 353
354 354 $ killdaemons.py
355 355
356 356 HTTP client follows HTTP redirect on handshake to new repo
357 357
358 358 $ cd $TESTTMP
359 359
360 360 $ hg init redirector
361 361 $ hg init redirected
362 362 $ cd redirected
363 363 $ touch foo
364 364 $ hg -q commit -A -m initial
365 365 $ cd ..
366 366
367 367 $ cat > paths.conf << EOF
368 368 > [paths]
369 369 > / = $TESTTMP/*
370 370 > EOF
371 371
372 372 $ cat > redirectext.py << EOF
373 373 > from mercurial import extensions, wireprotoserver
374 374 > def wrappedcallhttp(orig, repo, req, res, proto, cmd):
375 375 > path = req.advertisedurl[len(req.advertisedbaseurl):]
376 376 > if not path.startswith(b'/redirector'):
377 377 > return orig(repo, req, res, proto, cmd)
378 378 > relpath = path[len(b'/redirector'):]
379 379 > res.status = b'301 Redirect'
380 380 > newurl = b'%s/redirected%s' % (req.baseurl, relpath)
381 381 > if not repo.ui.configbool('testing', 'redirectqs', True) and b'?' in newurl:
382 382 > newurl = newurl[0:newurl.index(b'?')]
383 383 > res.headers[b'Location'] = newurl
384 384 > res.headers[b'Content-Type'] = b'text/plain'
385 385 > res.setbodybytes(b'redirected')
386 386 > return True
387 387 >
388 388 > extensions.wrapfunction(wireprotoserver, '_callhttp', wrappedcallhttp)
389 389 > EOF
390 390
391 391 $ hg --config extensions.redirect=$TESTTMP/redirectext.py \
392 392 > --config server.compressionengines=zlib \
393 393 > serve --web-conf paths.conf --pid-file hg.pid -p $HGPORT -d
394 394 $ cat hg.pid > $DAEMON_PIDS
395 395
396 396 Verify our HTTP 301 is served properly
397 397
398 398 $ hg --verbose debugwireproto --peer raw http://$LOCALIP:$HGPORT << EOF
399 399 > httprequest GET /redirector?cmd=capabilities
400 400 > user-agent: test
401 401 > EOF
402 402 using raw connection to peer
403 403 s> GET /redirector?cmd=capabilities HTTP/1.1\r\n
404 404 s> Accept-Encoding: identity\r\n
405 405 s> user-agent: test\r\n
406 406 s> host: $LOCALIP:$HGPORT\r\n (glob)
407 407 s> \r\n
408 408 s> makefile('rb', None)
409 409 s> HTTP/1.1 301 Redirect\r\n
410 410 s> Server: testing stub value\r\n
411 411 s> Date: $HTTP_DATE$\r\n
412 412 s> Location: http://$LOCALIP:$HGPORT/redirected?cmd=capabilities\r\n (glob)
413 413 s> Content-Type: text/plain\r\n
414 414 s> Content-Length: 10\r\n
415 415 s> \r\n
416 416 s> redirected
417 417 s> GET /redirected?cmd=capabilities HTTP/1.1\r\n
418 418 s> Accept-Encoding: identity\r\n
419 419 s> user-agent: test\r\n
420 420 s> host: $LOCALIP:$HGPORT\r\n (glob)
421 421 s> \r\n
422 422 s> makefile('rb', None)
423 423 s> HTTP/1.1 200 Script output follows\r\n
424 424 s> Server: testing stub value\r\n
425 425 s> Date: $HTTP_DATE$\r\n
426 426 s> Content-Type: application/mercurial-0.1\r\n
427 427 s> Content-Length: 467\r\n
428 428 s> \r\n
429 429 s> batch 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
430 430
431 431 Test with the HTTP peer
432 432
433 433 $ hg --verbose debugwireproto http://$LOCALIP:$HGPORT/redirector << EOF
434 434 > command heads
435 435 > EOF
436 436 s> GET /redirector?cmd=capabilities HTTP/1.1\r\n
437 437 s> Accept-Encoding: identity\r\n
438 438 s> accept: application/mercurial-0.1\r\n
439 439 s> host: $LOCALIP:$HGPORT\r\n (glob)
440 440 s> user-agent: Mercurial debugwireproto\r\n
441 441 s> \r\n
442 442 s> makefile('rb', None)
443 443 s> HTTP/1.1 301 Redirect\r\n
444 444 s> Server: testing stub value\r\n
445 445 s> Date: $HTTP_DATE$\r\n
446 446 s> Location: http://$LOCALIP:$HGPORT/redirected?cmd=capabilities\r\n (glob)
447 447 s> Content-Type: text/plain\r\n
448 448 s> Content-Length: 10\r\n
449 449 s> \r\n
450 450 s> redirected
451 451 s> GET /redirected?cmd=capabilities HTTP/1.1\r\n
452 452 s> Accept-Encoding: identity\r\n
453 453 s> accept: application/mercurial-0.1\r\n
454 454 s> host: $LOCALIP:$HGPORT\r\n (glob)
455 455 s> user-agent: Mercurial debugwireproto\r\n
456 456 s> \r\n
457 457 s> makefile('rb', None)
458 458 s> HTTP/1.1 200 Script output follows\r\n
459 459 s> Server: testing stub value\r\n
460 460 s> Date: $HTTP_DATE$\r\n
461 461 s> Content-Type: application/mercurial-0.1\r\n
462 462 s> Content-Length: 467\r\n
463 463 s> \r\n
464 464 real URL is http://$LOCALIP:$HGPORT/redirected (glob)
465 465 s> batch 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
466 466 sending heads command
467 467 s> GET /redirected?cmd=heads HTTP/1.1\r\n
468 468 s> Accept-Encoding: identity\r\n
469 469 s> vary: X-HgProto-1\r\n
470 470 s> x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
471 471 s> accept: application/mercurial-0.1\r\n
472 472 s> host: $LOCALIP:$HGPORT\r\n (glob)
473 473 s> user-agent: Mercurial debugwireproto\r\n
474 474 s> \r\n
475 475 s> makefile('rb', None)
476 476 s> HTTP/1.1 200 Script output follows\r\n
477 477 s> Server: testing stub value\r\n
478 478 s> Date: $HTTP_DATE$\r\n
479 479 s> Content-Type: application/mercurial-0.1\r\n
480 480 s> Content-Length: 41\r\n
481 481 s> \r\n
482 482 s> 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n
483 483 response: [
484 484 b'\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL'
485 485 ]
486 486
487 487 $ killdaemons.py
488 488
489 489 Now test a variation where we strip the query string from the redirect URL.
490 490 (SCM Manager apparently did this and clients would recover from it)
491 491
492 492 $ hg --config extensions.redirect=$TESTTMP/redirectext.py \
493 493 > --config server.compressionengines=zlib \
494 494 > --config testing.redirectqs=false \
495 495 > serve --web-conf paths.conf --pid-file hg.pid -p $HGPORT -d
496 496 $ cat hg.pid > $DAEMON_PIDS
497 497
498 498 $ hg --verbose debugwireproto --peer raw http://$LOCALIP:$HGPORT << EOF
499 499 > httprequest GET /redirector?cmd=capabilities
500 500 > user-agent: test
501 501 > EOF
502 502 using raw connection to peer
503 503 s> GET /redirector?cmd=capabilities HTTP/1.1\r\n
504 504 s> Accept-Encoding: identity\r\n
505 505 s> user-agent: test\r\n
506 506 s> host: $LOCALIP:$HGPORT\r\n (glob)
507 507 s> \r\n
508 508 s> makefile('rb', None)
509 509 s> HTTP/1.1 301 Redirect\r\n
510 510 s> Server: testing stub value\r\n
511 511 s> Date: $HTTP_DATE$\r\n
512 512 s> Location: http://$LOCALIP:$HGPORT/redirected\r\n (glob)
513 513 s> Content-Type: text/plain\r\n
514 514 s> Content-Length: 10\r\n
515 515 s> \r\n
516 516 s> redirected
517 517 s> GET /redirected HTTP/1.1\r\n
518 518 s> Accept-Encoding: identity\r\n
519 519 s> user-agent: test\r\n
520 520 s> host: $LOCALIP:$HGPORT\r\n (glob)
521 521 s> \r\n
522 522 s> makefile('rb', None)
523 523 s> HTTP/1.1 200 Script output follows\r\n
524 524 s> Server: testing stub value\r\n
525 525 s> Date: $HTTP_DATE$\r\n
526 526 s> ETag: W/"*"\r\n (glob)
527 527 s> Content-Type: text/html; charset=ascii\r\n
528 528 s> Transfer-Encoding: chunked\r\n
529 529 s> \r\n
530 530 s> 414\r\n
531 531 s> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">\n
532 532 s> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">\n
533 533 s> <head>\n
534 534 s> <link rel="icon" href="/redirected/static/hgicon.png" type="image/png" />\n
535 535 s> <meta name="robots" content="index, nofollow" />\n
536 536 s> <link rel="stylesheet" href="/redirected/static/style-paper.css" type="text/css" />\n
537 537 s> <script type="text/javascript" src="/redirected/static/mercurial.js"></script>\n
538 538 s> \n
539 539 s> <title>redirected: log</title>\n
540 540 s> <link rel="alternate" type="application/atom+xml"\n
541 541 s> href="/redirected/atom-log" title="Atom feed for redirected" />\n
542 542 s> <link rel="alternate" type="application/rss+xml"\n
543 543 s> href="/redirected/rss-log" title="RSS feed for redirected" />\n
544 544 s> </head>\n
545 545 s> <body>\n
546 546 s> \n
547 547 s> <div class="container">\n
548 548 s> <div class="menu">\n
549 549 s> <div class="logo">\n
550 550 s> <a href="https://mercurial-scm.org/">\n
551 551 s> <img src="/redirected/static/hglogo.png" alt="mercurial" /></a>\n
552 552 s> </div>\n
553 553 s> <ul>\n
554 554 s> <li class="active">log</li>\n
555 555 s> <li><a href="/redirected/graph/tip">graph</a></li>\n
556 556 s> <li><a href="/redirected/tags">tags</a></li>\n
557 557 s> <li><a href="
558 558 s> \r\n
559 559 s> 810\r\n
560 560 s> /redirected/bookmarks">bookmarks</a></li>\n
561 561 s> <li><a href="/redirected/branches">branches</a></li>\n
562 562 s> </ul>\n
563 563 s> <ul>\n
564 564 s> <li><a href="/redirected/rev/tip">changeset</a></li>\n
565 565 s> <li><a href="/redirected/file/tip">browse</a></li>\n
566 566 s> </ul>\n
567 567 s> <ul>\n
568 568 s> \n
569 569 s> </ul>\n
570 570 s> <ul>\n
571 571 s> <li><a href="/redirected/help">help</a></li>\n
572 572 s> </ul>\n
573 573 s> <div class="atom-logo">\n
574 574 s> <a href="/redirected/atom-log" title="subscribe to atom feed">\n
575 575 s> <img class="atom-logo" src="/redirected/static/feed-icon-14x14.png" alt="atom feed" />\n
576 576 s> </a>\n
577 577 s> </div>\n
578 578 s> </div>\n
579 579 s> \n
580 580 s> <div class="main">\n
581 581 s> <h2 class="breadcrumb"><a href="/">Mercurial</a> &gt; <a href="/redirected">redirected</a> </h2>\n
582 582 s> <h3>log</h3>\n
583 583 s> \n
584 584 s> \n
585 585 s> <form class="search" action="/redirected/log">\n
586 586 s> \n
587 587 s> <p><input name="rev" id="search1" type="text" size="30" value="" /></p>\n
588 588 s> <div id="hint">Find changesets by keywords (author, files, the commit message), revision\n
589 589 s> number or hash, or <a href="/redirected/help/revsets">revset expression</a>.</div>\n
590 590 s> </form>\n
591 591 s> \n
592 592 s> <div class="navigate">\n
593 593 s> <a href="/redirected/shortlog/tip?revcount=30">less</a>\n
594 594 s> <a href="/redirected/shortlog/tip?revcount=120">more</a>\n
595 595 s> | rev 0: <a href="/redirected/shortlog/96ee1d7354c4">(0)</a> <a href="/redirected/shortlog/tip">tip</a> \n
596 596 s> </div>\n
597 597 s> \n
598 598 s> <table class="bigtable">\n
599 599 s> <thead>\n
600 600 s> <tr>\n
601 601 s> <th class="age">age</th>\n
602 602 s> <th class="author">author</th>\n
603 603 s> <th class="description">description</th>\n
604 604 s> </tr>\n
605 605 s> </thead>\n
606 606 s> <tbody class="stripes2">\n
607 607 s> <tr>\n
608 608 s> <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>\n
609 609 s> <td class="author">test</td>\n
610 610 s> <td class="description">\n
611 611 s> <a href="/redirected/rev/96ee1d7354c4">initial</a>\n
612 612 s> <span class="phase">draft</span> <span class="branchhead">default</span> <span class="tag">tip</span> \n
613 613 s> </td>\n
614 614 s> </tr>\n
615 615 s> \n
616 616 s> </tbody>\n
617 617 s> </table>\n
618 618 s> \n
619 619 s> <div class="navigate">\n
620 620 s> <a href="/redirected/shortlog/tip?revcount=30">less</a>\n
621 621 s> <a href="/redirected/shortlog/tip?revcount=120">more</a>\n
622 622 s> | rev 0: <a href="/redirected/shortlog/96ee1d7354c4">(0)</a> <a href="/redirected/shortlog/tip">tip</a> \n
623 623 s> </div>\n
624 624 s> \n
625 625 s> <script type="text/javascript">\n
626 626 s> ajaxScrollInit(\n
627 627 s> \'/redirected/shortlog/%next%\',\n
628 628 s> \'\', <!-- NEXTHASH\n
629 629 s> function (htmlText) {
630 630 s> \r\n
631 631 s> 14a\r\n
632 632 s> \n
633 633 s> var m = htmlText.match(/\'(\\w+)\', <!-- NEXTHASH/);\n
634 634 s> return m ? m[1] : null;\n
635 635 s> },\n
636 636 s> \'.bigtable > tbody\',\n
637 637 s> \'<tr class="%class%">\\\n
638 638 s> <td colspan="3" style="text-align: center;">%text%</td>\\\n
639 639 s> </tr>\'\n
640 640 s> );\n
641 641 s> </script>\n
642 642 s> \n
643 643 s> </div>\n
644 644 s> </div>\n
645 645 s> \n
646 646 s> \n
647 647 s> \n
648 648 s> </body>\n
649 649 s> </html>\n
650 650 s> \n
651 651 s> \r\n
652 652 s> 0\r\n
653 653 s> \r\n
654 654
655 655 $ hg --verbose debugwireproto http://$LOCALIP:$HGPORT/redirector << EOF
656 656 > command heads
657 657 > EOF
658 658 s> GET /redirector?cmd=capabilities HTTP/1.1\r\n
659 659 s> Accept-Encoding: identity\r\n
660 660 s> accept: application/mercurial-0.1\r\n
661 661 s> host: $LOCALIP:$HGPORT\r\n (glob)
662 662 s> user-agent: Mercurial debugwireproto\r\n
663 663 s> \r\n
664 664 s> makefile('rb', None)
665 665 s> HTTP/1.1 301 Redirect\r\n
666 666 s> Server: testing stub value\r\n
667 667 s> Date: $HTTP_DATE$\r\n
668 668 s> Location: http://$LOCALIP:$HGPORT/redirected\r\n (glob)
669 669 s> Content-Type: text/plain\r\n
670 670 s> Content-Length: 10\r\n
671 671 s> \r\n
672 672 s> redirected
673 673 s> GET /redirected HTTP/1.1\r\n
674 674 s> Accept-Encoding: identity\r\n
675 675 s> accept: application/mercurial-0.1\r\n
676 676 s> host: $LOCALIP:$HGPORT\r\n (glob)
677 677 s> user-agent: Mercurial debugwireproto\r\n
678 678 s> \r\n
679 679 s> makefile('rb', None)
680 680 s> HTTP/1.1 200 Script output follows\r\n
681 681 s> Server: testing stub value\r\n
682 682 s> Date: $HTTP_DATE$\r\n
683 683 s> ETag: W/"*"\r\n (glob)
684 684 s> Content-Type: text/html; charset=ascii\r\n
685 685 s> Transfer-Encoding: chunked\r\n
686 686 s> \r\n
687 687 real URL is http://$LOCALIP:$HGPORT/redirected (glob)
688 688 s> 414\r\n
689 689 s> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">\n
690 690 s> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">\n
691 691 s> <head>\n
692 692 s> <link rel="icon" href="/redirected/static/hgicon.png" type="image/png" />\n
693 693 s> <meta name="robots" content="index, nofollow" />\n
694 694 s> <link rel="stylesheet" href="/redirected/static/style-paper.css" type="text/css" />\n
695 695 s> <script type="text/javascript" src="/redirected/static/mercurial.js"></script>\n
696 696 s> \n
697 697 s> <title>redirected: log</title>\n
698 698 s> <link rel="alternate" type="application/atom+xml"\n
699 699 s> href="/redirected/atom-log" title="Atom feed for redirected" />\n
700 700 s> <link rel="alternate" type="application/rss+xml"\n
701 701 s> href="/redirected/rss-log" title="RSS feed for redirected" />\n
702 702 s> </head>\n
703 703 s> <body>\n
704 704 s> \n
705 705 s> <div class="container">\n
706 706 s> <div class="menu">\n
707 707 s> <div class="logo">\n
708 708 s> <a href="https://mercurial-scm.org/">\n
709 709 s> <img src="/redirected/static/hglogo.png" alt="mercurial" /></a>\n
710 710 s> </div>\n
711 711 s> <ul>\n
712 712 s> <li class="active">log</li>\n
713 713 s> <li><a href="/redirected/graph/tip">graph</a></li>\n
714 714 s> <li><a href="/redirected/tags">tags</a
715 715 s> GET /redirected?cmd=capabilities HTTP/1.1\r\n
716 716 s> Accept-Encoding: identity\r\n
717 717 s> accept: application/mercurial-0.1\r\n
718 718 s> host: $LOCALIP:$HGPORT\r\n (glob)
719 719 s> user-agent: Mercurial debugwireproto\r\n
720 720 s> \r\n
721 721 s> makefile('rb', None)
722 722 s> HTTP/1.1 200 Script output follows\r\n
723 723 s> Server: testing stub value\r\n
724 724 s> Date: $HTTP_DATE$\r\n
725 725 s> Content-Type: application/mercurial-0.1\r\n
726 726 s> Content-Length: 467\r\n
727 727 s> \r\n
728 728 real URL is http://$LOCALIP:$HGPORT/redirected (glob)
729 729 s> batch 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
730 730 sending heads command
731 731 s> GET /redirected?cmd=heads HTTP/1.1\r\n
732 732 s> Accept-Encoding: identity\r\n
733 733 s> vary: X-HgProto-1\r\n
734 734 s> x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
735 735 s> accept: application/mercurial-0.1\r\n
736 736 s> host: $LOCALIP:$HGPORT\r\n (glob)
737 737 s> user-agent: Mercurial debugwireproto\r\n
738 738 s> \r\n
739 739 s> makefile('rb', None)
740 740 s> HTTP/1.1 200 Script output follows\r\n
741 741 s> Server: testing stub value\r\n
742 742 s> Date: $HTTP_DATE$\r\n
743 743 s> Content-Type: application/mercurial-0.1\r\n
744 744 s> Content-Length: 41\r\n
745 745 s> \r\n
746 746 s> 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n
747 747 response: [
748 748 b'\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL'
749 749 ]
@@ -1,536 +1,536
1 1 #require no-chg
2 2
3 3 $ . $TESTDIR/wireprotohelpers.sh
4 4
5 5 $ hg init server
6 6
7 7 zstd isn't present in plain builds. Make tests easier by removing
8 8 zstd from the equation.
9 9
10 10 $ cat >> server/.hg/hgrc << EOF
11 11 > [server]
12 12 > compressionengines = zlib
13 13 > EOF
14 14
15 15 $ hg -R server serve -p $HGPORT -d --pid-file hg.pid -E error.log
16 16 $ cat hg.pid > $DAEMON_PIDS
17 17
18 18 A normal capabilities request is serviced for version 1
19 19
20 20 $ sendhttpraw << EOF
21 21 > httprequest GET ?cmd=capabilities
22 22 > user-agent: test
23 23 > EOF
24 24 using raw connection to peer
25 25 s> GET /?cmd=capabilities HTTP/1.1\r\n
26 26 s> Accept-Encoding: identity\r\n
27 27 s> user-agent: test\r\n
28 28 s> host: $LOCALIP:$HGPORT\r\n (glob)
29 29 s> \r\n
30 30 s> makefile('rb', None)
31 31 s> HTTP/1.1 200 Script output follows\r\n
32 32 s> Server: testing stub value\r\n
33 33 s> Date: $HTTP_DATE$\r\n
34 34 s> Content-Type: application/mercurial-0.1\r\n
35 35 s> Content-Length: *\r\n (glob)
36 36 s> \r\n
37 37 s> batch 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
38 38
39 39 A proper request without the API server enabled returns the legacy response
40 40
41 41 $ sendhttpraw << EOF
42 42 > httprequest GET ?cmd=capabilities
43 43 > user-agent: test
44 44 > x-hgupgrade-1: foo
45 45 > x-hgproto-1: cbor
46 46 > EOF
47 47 using raw connection to peer
48 48 s> GET /?cmd=capabilities HTTP/1.1\r\n
49 49 s> Accept-Encoding: identity\r\n
50 50 s> user-agent: test\r\n
51 51 s> x-hgproto-1: cbor\r\n
52 52 s> x-hgupgrade-1: foo\r\n
53 53 s> host: $LOCALIP:$HGPORT\r\n (glob)
54 54 s> \r\n
55 55 s> makefile('rb', None)
56 56 s> HTTP/1.1 200 Script output follows\r\n
57 57 s> Server: testing stub value\r\n
58 58 s> Date: $HTTP_DATE$\r\n
59 59 s> Content-Type: application/mercurial-0.1\r\n
60 60 s> Content-Length: *\r\n (glob)
61 61 s> \r\n
62 62 s> batch 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
63 63
64 64 Restart with just API server enabled. This enables serving the new format.
65 65
66 66 $ killdaemons.py
67 67 $ cat error.log
68 68
69 69 $ cat >> server/.hg/hgrc << EOF
70 70 > [experimental]
71 71 > web.apiserver = true
72 72 > EOF
73 73
74 74 $ hg -R server serve -p $HGPORT -d --pid-file hg.pid -E error.log
75 75 $ cat hg.pid > $DAEMON_PIDS
76 76
77 77 X-HgUpgrade-<N> without CBOR advertisement uses legacy response
78 78
79 79 $ sendhttpraw << EOF
80 80 > httprequest GET ?cmd=capabilities
81 81 > user-agent: test
82 82 > x-hgupgrade-1: foo bar
83 83 > EOF
84 84 using raw connection to peer
85 85 s> GET /?cmd=capabilities HTTP/1.1\r\n
86 86 s> Accept-Encoding: identity\r\n
87 87 s> user-agent: test\r\n
88 88 s> x-hgupgrade-1: foo bar\r\n
89 89 s> host: $LOCALIP:$HGPORT\r\n (glob)
90 90 s> \r\n
91 91 s> makefile('rb', None)
92 92 s> HTTP/1.1 200 Script output follows\r\n
93 93 s> Server: testing stub value\r\n
94 94 s> Date: $HTTP_DATE$\r\n
95 95 s> Content-Type: application/mercurial-0.1\r\n
96 96 s> Content-Length: *\r\n (glob)
97 97 s> \r\n
98 98 s> batch 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
99 99
100 100 X-HgUpgrade-<N> without known serialization in X-HgProto-<N> uses legacy response
101 101
102 102 $ sendhttpraw << EOF
103 103 > httprequest GET ?cmd=capabilities
104 104 > user-agent: test
105 105 > x-hgupgrade-1: foo bar
106 106 > x-hgproto-1: some value
107 107 > EOF
108 108 using raw connection to peer
109 109 s> GET /?cmd=capabilities HTTP/1.1\r\n
110 110 s> Accept-Encoding: identity\r\n
111 111 s> user-agent: test\r\n
112 112 s> x-hgproto-1: some value\r\n
113 113 s> x-hgupgrade-1: foo bar\r\n
114 114 s> host: $LOCALIP:$HGPORT\r\n (glob)
115 115 s> \r\n
116 116 s> makefile('rb', None)
117 117 s> HTTP/1.1 200 Script output follows\r\n
118 118 s> Server: testing stub value\r\n
119 119 s> Date: $HTTP_DATE$\r\n
120 120 s> Content-Type: application/mercurial-0.1\r\n
121 121 s> Content-Length: *\r\n (glob)
122 122 s> \r\n
123 123 s> batch 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
124 124
125 125 X-HgUpgrade-<N> + X-HgProto-<N> headers trigger new response format
126 126
127 127 $ sendhttpraw << EOF
128 128 > httprequest GET ?cmd=capabilities
129 129 > user-agent: test
130 130 > x-hgupgrade-1: foo bar
131 131 > x-hgproto-1: cbor
132 132 > EOF
133 133 using raw connection to peer
134 134 s> GET /?cmd=capabilities HTTP/1.1\r\n
135 135 s> Accept-Encoding: identity\r\n
136 136 s> user-agent: test\r\n
137 137 s> x-hgproto-1: cbor\r\n
138 138 s> x-hgupgrade-1: foo bar\r\n
139 139 s> host: $LOCALIP:$HGPORT\r\n (glob)
140 140 s> \r\n
141 141 s> makefile('rb', None)
142 142 s> HTTP/1.1 200 OK\r\n
143 143 s> Server: testing stub value\r\n
144 144 s> Date: $HTTP_DATE$\r\n
145 145 s> Content-Type: application/mercurial-cbor\r\n
146 146 s> Content-Length: *\r\n (glob)
147 147 s> \r\n
148 148 s> \xa3GapibaseDapi/Dapis\xa0Nv1capabilitiesY\x01\xd3batch 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
149 149 cbor> {
150 150 b'apibase': b'api/',
151 151 b'apis': {},
152 152 b'v1capabilities': b'batch 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'
153 153 }
154 154
155 155 Restart server to enable HTTPv2
156 156
157 157 $ killdaemons.py
158 158 $ enablehttpv2 server
159 159 $ hg -R server serve -p $HGPORT -d --pid-file hg.pid -E error.log
160 160 $ cat hg.pid > $DAEMON_PIDS
161 161
162 162 Only requested API services are returned
163 163
164 164 $ sendhttpraw << EOF
165 165 > httprequest GET ?cmd=capabilities
166 166 > user-agent: test
167 167 > x-hgupgrade-1: foo bar
168 168 > x-hgproto-1: cbor
169 169 > EOF
170 170 using raw connection to peer
171 171 s> GET /?cmd=capabilities HTTP/1.1\r\n
172 172 s> Accept-Encoding: identity\r\n
173 173 s> user-agent: test\r\n
174 174 s> x-hgproto-1: cbor\r\n
175 175 s> x-hgupgrade-1: foo bar\r\n
176 176 s> host: $LOCALIP:$HGPORT\r\n (glob)
177 177 s> \r\n
178 178 s> makefile('rb', None)
179 179 s> HTTP/1.1 200 OK\r\n
180 180 s> Server: testing stub value\r\n
181 181 s> Date: $HTTP_DATE$\r\n
182 182 s> Content-Type: application/mercurial-cbor\r\n
183 183 s> Content-Length: *\r\n (glob)
184 184 s> \r\n
185 185 s> \xa3GapibaseDapi/Dapis\xa0Nv1capabilitiesY\x01\xd3batch 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
186 186 cbor> {
187 187 b'apibase': b'api/',
188 188 b'apis': {},
189 189 b'v1capabilities': b'batch 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'
190 190 }
191 191
192 192 Request for HTTPv2 service returns information about it
193 193
194 194 $ sendhttpraw << EOF
195 195 > httprequest GET ?cmd=capabilities
196 196 > user-agent: test
197 197 > x-hgupgrade-1: exp-http-v2-0001 foo bar
198 198 > x-hgproto-1: cbor
199 199 > EOF
200 200 using raw connection to peer
201 201 s> GET /?cmd=capabilities HTTP/1.1\r\n
202 202 s> Accept-Encoding: identity\r\n
203 203 s> user-agent: test\r\n
204 204 s> x-hgproto-1: cbor\r\n
205 205 s> x-hgupgrade-1: exp-http-v2-0001 foo bar\r\n
206 206 s> host: $LOCALIP:$HGPORT\r\n (glob)
207 207 s> \r\n
208 208 s> makefile('rb', None)
209 209 s> HTTP/1.1 200 OK\r\n
210 210 s> Server: testing stub value\r\n
211 211 s> Date: $HTTP_DATE$\r\n
212 212 s> Content-Type: application/mercurial-cbor\r\n
213 213 s> Content-Length: *\r\n (glob)
214 214 s> \r\n
215 s> \xa3GapibaseDapi/Dapis\xa1Pexp-http-v2-0001\xa4Hcommands\xaaIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa3Ffields\xd9\x01\x02\x82GparentsHrevisionInoderange\x82\x81J0123456...\x81Iabcdef...Enodes\x81J0123456...Kpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\x82GparentsHrevisionKhaveparents\xf5Enodes\x81J0123456...DpathGfoo.txtKpermissions\x81DpullEheads\xa2Dargs\xa1Jpubliconly\xf4Kpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\x81HdeadbeefKpermissions\x81DpullHlistkeys\xa2Dargs\xa1InamespaceBnsKpermissions\x81DpullFlookup\xa2Dargs\xa1CkeyCfooKpermissions\x81DpullLmanifestdata\xa2Dargs\xa4Ffields\x82GparentsHrevisionKhaveparents\xf5Enodes\x81J0123456...Dtree@Kpermissions\x81DpullGpushkey\xa2Dargs\xa4CkeyCkeyInamespaceBnsCnewCnewColdColdKpermissions\x81DpushKcompression\x81\xa1DnameDzlibQframingmediatypes\x81X&application/mercurial-exp-framing-0005Nrawrepoformats\x82LgeneraldeltaHrevlogv1Nv1capabilitiesY\x01\xd3batch 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
215 s> \xa3GapibaseDapi/Dapis\xa1Pexp-http-v2-0001\xa4Hcommands\xaaIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa3Ffields\xd9\x01\x02\x82GparentsHrevisionInoderange\x82\x81J0123456...\x81Iabcdef...Enodes\x81J0123456...Kpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xf5Enodes\x81J0123456...DpathGfoo.txtKpermissions\x81DpullEheads\xa2Dargs\xa1Jpubliconly\xf4Kpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\x81HdeadbeefKpermissions\x81DpullHlistkeys\xa2Dargs\xa1InamespaceBnsKpermissions\x81DpullFlookup\xa2Dargs\xa1CkeyCfooKpermissions\x81DpullLmanifestdata\xa2Dargs\xa4Ffields\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xf5Enodes\x81J0123456...Dtree@Kpermissions\x81DpullGpushkey\xa2Dargs\xa4CkeyCkeyInamespaceBnsCnewCnewColdColdKpermissions\x81DpushKcompression\x81\xa1DnameDzlibQframingmediatypes\x81X&application/mercurial-exp-framing-0005Nrawrepoformats\x82LgeneraldeltaHrevlogv1Nv1capabilitiesY\x01\xd3batch 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
216 216 cbor> {
217 217 b'apibase': b'api/',
218 218 b'apis': {
219 219 b'exp-http-v2-0001': {
220 220 b'commands': {
221 221 b'branchmap': {
222 222 b'args': {},
223 223 b'permissions': [
224 224 b'pull'
225 225 ]
226 226 },
227 227 b'capabilities': {
228 228 b'args': {},
229 229 b'permissions': [
230 230 b'pull'
231 231 ]
232 232 },
233 233 b'changesetdata': {
234 234 b'args': {
235 235 b'fields': set([
236 236 b'parents',
237 237 b'revision'
238 238 ]),
239 239 b'noderange': [
240 240 [
241 241 b'0123456...'
242 242 ],
243 243 [
244 244 b'abcdef...'
245 245 ]
246 246 ],
247 247 b'nodes': [
248 248 b'0123456...'
249 249 ]
250 250 },
251 251 b'permissions': [
252 252 b'pull'
253 253 ]
254 254 },
255 255 b'filedata': {
256 256 b'args': {
257 b'fields': [
257 b'fields': set([
258 258 b'parents',
259 259 b'revision'
260 ],
260 ]),
261 261 b'haveparents': True,
262 262 b'nodes': [
263 263 b'0123456...'
264 264 ],
265 265 b'path': b'foo.txt'
266 266 },
267 267 b'permissions': [
268 268 b'pull'
269 269 ]
270 270 },
271 271 b'heads': {
272 272 b'args': {
273 273 b'publiconly': False
274 274 },
275 275 b'permissions': [
276 276 b'pull'
277 277 ]
278 278 },
279 279 b'known': {
280 280 b'args': {
281 281 b'nodes': [
282 282 b'deadbeef'
283 283 ]
284 284 },
285 285 b'permissions': [
286 286 b'pull'
287 287 ]
288 288 },
289 289 b'listkeys': {
290 290 b'args': {
291 291 b'namespace': b'ns'
292 292 },
293 293 b'permissions': [
294 294 b'pull'
295 295 ]
296 296 },
297 297 b'lookup': {
298 298 b'args': {
299 299 b'key': b'foo'
300 300 },
301 301 b'permissions': [
302 302 b'pull'
303 303 ]
304 304 },
305 305 b'manifestdata': {
306 306 b'args': {
307 b'fields': [
307 b'fields': set([
308 308 b'parents',
309 309 b'revision'
310 ],
310 ]),
311 311 b'haveparents': True,
312 312 b'nodes': [
313 313 b'0123456...'
314 314 ],
315 315 b'tree': b''
316 316 },
317 317 b'permissions': [
318 318 b'pull'
319 319 ]
320 320 },
321 321 b'pushkey': {
322 322 b'args': {
323 323 b'key': b'key',
324 324 b'namespace': b'ns',
325 325 b'new': b'new',
326 326 b'old': b'old'
327 327 },
328 328 b'permissions': [
329 329 b'push'
330 330 ]
331 331 }
332 332 },
333 333 b'compression': [
334 334 {
335 335 b'name': b'zlib'
336 336 }
337 337 ],
338 338 b'framingmediatypes': [
339 339 b'application/mercurial-exp-framing-0005'
340 340 ],
341 341 b'rawrepoformats': [
342 342 b'generaldelta',
343 343 b'revlogv1'
344 344 ]
345 345 }
346 346 },
347 347 b'v1capabilities': b'batch 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'
348 348 }
349 349
350 350 capabilities command returns expected info
351 351
352 352 $ sendhttpv2peerhandshake << EOF
353 353 > command capabilities
354 354 > EOF
355 355 creating http peer for wire protocol version 2
356 356 s> GET /?cmd=capabilities HTTP/1.1\r\n
357 357 s> Accept-Encoding: identity\r\n
358 358 s> vary: X-HgProto-1,X-HgUpgrade-1\r\n
359 359 s> x-hgproto-1: cbor\r\n
360 360 s> x-hgupgrade-1: exp-http-v2-0001\r\n
361 361 s> accept: application/mercurial-0.1\r\n
362 362 s> host: $LOCALIP:$HGPORT\r\n (glob)
363 363 s> user-agent: Mercurial debugwireproto\r\n
364 364 s> \r\n
365 365 s> makefile('rb', None)
366 366 s> HTTP/1.1 200 OK\r\n
367 367 s> Server: testing stub value\r\n
368 368 s> Date: $HTTP_DATE$\r\n
369 369 s> Content-Type: application/mercurial-cbor\r\n
370 370 s> Content-Length: *\r\n (glob)
371 371 s> \r\n
372 s> \xa3GapibaseDapi/Dapis\xa1Pexp-http-v2-0001\xa4Hcommands\xaaIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa3Ffields\xd9\x01\x02\x82GparentsHrevisionInoderange\x82\x81J0123456...\x81Iabcdef...Enodes\x81J0123456...Kpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\x82GparentsHrevisionKhaveparents\xf5Enodes\x81J0123456...DpathGfoo.txtKpermissions\x81DpullEheads\xa2Dargs\xa1Jpubliconly\xf4Kpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\x81HdeadbeefKpermissions\x81DpullHlistkeys\xa2Dargs\xa1InamespaceBnsKpermissions\x81DpullFlookup\xa2Dargs\xa1CkeyCfooKpermissions\x81DpullLmanifestdata\xa2Dargs\xa4Ffields\x82GparentsHrevisionKhaveparents\xf5Enodes\x81J0123456...Dtree@Kpermissions\x81DpullGpushkey\xa2Dargs\xa4CkeyCkeyInamespaceBnsCnewCnewColdColdKpermissions\x81DpushKcompression\x81\xa1DnameDzlibQframingmediatypes\x81X&application/mercurial-exp-framing-0005Nrawrepoformats\x82LgeneraldeltaHrevlogv1Nv1capabilitiesY\x01\xd3batch 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
372 s> \xa3GapibaseDapi/Dapis\xa1Pexp-http-v2-0001\xa4Hcommands\xaaIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa3Ffields\xd9\x01\x02\x82GparentsHrevisionInoderange\x82\x81J0123456...\x81Iabcdef...Enodes\x81J0123456...Kpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xf5Enodes\x81J0123456...DpathGfoo.txtKpermissions\x81DpullEheads\xa2Dargs\xa1Jpubliconly\xf4Kpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\x81HdeadbeefKpermissions\x81DpullHlistkeys\xa2Dargs\xa1InamespaceBnsKpermissions\x81DpullFlookup\xa2Dargs\xa1CkeyCfooKpermissions\x81DpullLmanifestdata\xa2Dargs\xa4Ffields\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xf5Enodes\x81J0123456...Dtree@Kpermissions\x81DpullGpushkey\xa2Dargs\xa4CkeyCkeyInamespaceBnsCnewCnewColdColdKpermissions\x81DpushKcompression\x81\xa1DnameDzlibQframingmediatypes\x81X&application/mercurial-exp-framing-0005Nrawrepoformats\x82LgeneraldeltaHrevlogv1Nv1capabilitiesY\x01\xd3batch 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
373 373 sending capabilities command
374 374 s> POST /api/exp-http-v2-0001/ro/capabilities HTTP/1.1\r\n
375 375 s> Accept-Encoding: identity\r\n
376 376 s> accept: application/mercurial-exp-framing-0005\r\n
377 377 s> content-type: application/mercurial-exp-framing-0005\r\n
378 378 s> content-length: 27\r\n
379 379 s> host: $LOCALIP:$HGPORT\r\n (glob)
380 380 s> user-agent: Mercurial debugwireproto\r\n
381 381 s> \r\n
382 382 s> \x13\x00\x00\x01\x00\x01\x01\x11\xa1DnameLcapabilities
383 383 s> makefile('rb', None)
384 384 s> HTTP/1.1 200 OK\r\n
385 385 s> Server: testing stub value\r\n
386 386 s> Date: $HTTP_DATE$\r\n
387 387 s> Content-Type: application/mercurial-exp-framing-0005\r\n
388 388 s> Transfer-Encoding: chunked\r\n
389 389 s> \r\n
390 390 s> 13\r\n
391 391 s> \x0b\x00\x00\x01\x00\x02\x011
392 392 s> \xa1FstatusBok
393 393 s> \r\n
394 394 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
395 s> 30e\r\n
396 s> \x06\x03\x00\x01\x00\x02\x001
397 s> \xa4Hcommands\xaaIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa3Ffields\xd9\x01\x02\x82GparentsHrevisionInoderange\x82\x81J0123456...\x81Iabcdef...Enodes\x81J0123456...Kpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\x82GparentsHrevisionKhaveparents\xf5Enodes\x81J0123456...DpathGfoo.txtKpermissions\x81DpullEheads\xa2Dargs\xa1Jpubliconly\xf4Kpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\x81HdeadbeefKpermissions\x81DpullHlistkeys\xa2Dargs\xa1InamespaceBnsKpermissions\x81DpullFlookup\xa2Dargs\xa1CkeyCfooKpermissions\x81DpullLmanifestdata\xa2Dargs\xa4Ffields\x82GparentsHrevisionKhaveparents\xf5Enodes\x81J0123456...Dtree@Kpermissions\x81DpullGpushkey\xa2Dargs\xa4CkeyCkeyInamespaceBnsCnewCnewColdColdKpermissions\x81DpushKcompression\x81\xa1DnameDzlibQframingmediatypes\x81X&application/mercurial-exp-framing-0005Nrawrepoformats\x82LgeneraldeltaHrevlogv1
395 s> 314\r\n
396 s> \x0c\x03\x00\x01\x00\x02\x001
397 s> \xa4Hcommands\xaaIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa3Ffields\xd9\x01\x02\x82GparentsHrevisionInoderange\x82\x81J0123456...\x81Iabcdef...Enodes\x81J0123456...Kpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xf5Enodes\x81J0123456...DpathGfoo.txtKpermissions\x81DpullEheads\xa2Dargs\xa1Jpubliconly\xf4Kpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\x81HdeadbeefKpermissions\x81DpullHlistkeys\xa2Dargs\xa1InamespaceBnsKpermissions\x81DpullFlookup\xa2Dargs\xa1CkeyCfooKpermissions\x81DpullLmanifestdata\xa2Dargs\xa4Ffields\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xf5Enodes\x81J0123456...Dtree@Kpermissions\x81DpullGpushkey\xa2Dargs\xa4CkeyCkeyInamespaceBnsCnewCnewColdColdKpermissions\x81DpushKcompression\x81\xa1DnameDzlibQframingmediatypes\x81X&application/mercurial-exp-framing-0005Nrawrepoformats\x82LgeneraldeltaHrevlogv1
398 398 s> \r\n
399 received frame(size=774; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
399 received frame(size=780; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
400 400 s> 8\r\n
401 401 s> \x00\x00\x00\x01\x00\x02\x002
402 402 s> \r\n
403 403 s> 0\r\n
404 404 s> \r\n
405 405 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
406 406 response: gen[
407 407 {
408 408 b'commands': {
409 409 b'branchmap': {
410 410 b'args': {},
411 411 b'permissions': [
412 412 b'pull'
413 413 ]
414 414 },
415 415 b'capabilities': {
416 416 b'args': {},
417 417 b'permissions': [
418 418 b'pull'
419 419 ]
420 420 },
421 421 b'changesetdata': {
422 422 b'args': {
423 423 b'fields': set([
424 424 b'parents',
425 425 b'revision'
426 426 ]),
427 427 b'noderange': [
428 428 [
429 429 b'0123456...'
430 430 ],
431 431 [
432 432 b'abcdef...'
433 433 ]
434 434 ],
435 435 b'nodes': [
436 436 b'0123456...'
437 437 ]
438 438 },
439 439 b'permissions': [
440 440 b'pull'
441 441 ]
442 442 },
443 443 b'filedata': {
444 444 b'args': {
445 b'fields': [
445 b'fields': set([
446 446 b'parents',
447 447 b'revision'
448 ],
448 ]),
449 449 b'haveparents': True,
450 450 b'nodes': [
451 451 b'0123456...'
452 452 ],
453 453 b'path': b'foo.txt'
454 454 },
455 455 b'permissions': [
456 456 b'pull'
457 457 ]
458 458 },
459 459 b'heads': {
460 460 b'args': {
461 461 b'publiconly': False
462 462 },
463 463 b'permissions': [
464 464 b'pull'
465 465 ]
466 466 },
467 467 b'known': {
468 468 b'args': {
469 469 b'nodes': [
470 470 b'deadbeef'
471 471 ]
472 472 },
473 473 b'permissions': [
474 474 b'pull'
475 475 ]
476 476 },
477 477 b'listkeys': {
478 478 b'args': {
479 479 b'namespace': b'ns'
480 480 },
481 481 b'permissions': [
482 482 b'pull'
483 483 ]
484 484 },
485 485 b'lookup': {
486 486 b'args': {
487 487 b'key': b'foo'
488 488 },
489 489 b'permissions': [
490 490 b'pull'
491 491 ]
492 492 },
493 493 b'manifestdata': {
494 494 b'args': {
495 b'fields': [
495 b'fields': set([
496 496 b'parents',
497 497 b'revision'
498 ],
498 ]),
499 499 b'haveparents': True,
500 500 b'nodes': [
501 501 b'0123456...'
502 502 ],
503 503 b'tree': b''
504 504 },
505 505 b'permissions': [
506 506 b'pull'
507 507 ]
508 508 },
509 509 b'pushkey': {
510 510 b'args': {
511 511 b'key': b'key',
512 512 b'namespace': b'ns',
513 513 b'new': b'new',
514 514 b'old': b'old'
515 515 },
516 516 b'permissions': [
517 517 b'push'
518 518 ]
519 519 }
520 520 },
521 521 b'compression': [
522 522 {
523 523 b'name': b'zlib'
524 524 }
525 525 ],
526 526 b'framingmediatypes': [
527 527 b'application/mercurial-exp-framing-0005'
528 528 ],
529 529 b'rawrepoformats': [
530 530 b'generaldelta',
531 531 b'revlogv1'
532 532 ]
533 533 }
534 534 ]
535 535
536 536 $ cat error.log
@@ -1,604 +1,604
1 1 $ . $TESTDIR/wireprotohelpers.sh
2 2
3 3 $ hg init server
4 4 $ enablehttpv2 server
5 5 $ cd server
6 6 $ echo a0 > a
7 7 $ echo b0 > b
8 8 $ mkdir -p dir0/child0 dir0/child1 dir1
9 9 $ echo c0 > dir0/c
10 10 $ echo d0 > dir0/d
11 11 $ echo e0 > dir0/child0/e
12 12 $ echo f0 > dir0/child1/f
13 13 $ hg -q commit -A -m 'commit 0'
14 14
15 15 $ echo a1 > a
16 16 $ echo d1 > dir0/d
17 17 $ hg commit -m 'commit 1'
18 18 $ echo f0 > dir0/child1/f
19 19 $ hg commit -m 'commit 2'
20 20 nothing changed
21 21 [1]
22 22
23 23 $ hg -q up -r 0
24 24 $ echo a2 > a
25 25 $ hg commit -m 'commit 3'
26 26 created new head
27 27
28 28 $ hg log -G -T '{rev}:{node} {desc}\n'
29 29 @ 2:c8757a2ffe552850d1e0dfe60d295ebf64c196d9 commit 3
30 30 |
31 31 | o 1:650165e803375748a94df471e5b58d85763e0b29 commit 1
32 32 |/
33 33 o 0:6d85ca1270b377d320098556ba5bfad34a9ee12d commit 0
34 34
35 35
36 36 $ hg --debug debugindex a
37 37 rev linkrev nodeid p1 p2
38 38 0 0 2b4eb07319bfa077a40a2f04913659aef0da42da 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
39 39 1 1 9a38122997b3ac97be2a9aa2e556838341fdf2cc 2b4eb07319bfa077a40a2f04913659aef0da42da 0000000000000000000000000000000000000000
40 40 2 2 0879345e39377229634b420c639454156726c6b6 2b4eb07319bfa077a40a2f04913659aef0da42da 0000000000000000000000000000000000000000
41 41
42 42 $ hg --debug debugindex dir0/child0/e
43 43 rev linkrev nodeid p1 p2
44 44 0 0 bbba6c06b30f443d34ff841bc985c4d0827c6be4 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
45 45
46 46 $ hg serve -p $HGPORT -d --pid-file hg.pid -E error.log
47 47 $ cat hg.pid > $DAEMON_PIDS
48 48
49 49 Missing arguments is an error
50 50
51 51 $ sendhttpv2peer << EOF
52 52 > command filedata
53 53 > EOF
54 54 creating http peer for wire protocol version 2
55 55 sending filedata command
56 56 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
57 57 s> Accept-Encoding: identity\r\n
58 58 s> accept: application/mercurial-exp-framing-0005\r\n
59 59 s> content-type: application/mercurial-exp-framing-0005\r\n
60 60 s> content-length: 23\r\n
61 61 s> host: $LOCALIP:$HGPORT\r\n (glob)
62 62 s> user-agent: Mercurial debugwireproto\r\n
63 63 s> \r\n
64 64 s> \x0f\x00\x00\x01\x00\x01\x01\x11\xa1DnameHfiledata
65 65 s> makefile('rb', None)
66 66 s> HTTP/1.1 200 OK\r\n
67 67 s> Server: testing stub value\r\n
68 68 s> Date: $HTTP_DATE$\r\n
69 69 s> Content-Type: application/mercurial-exp-framing-0005\r\n
70 70 s> Transfer-Encoding: chunked\r\n
71 71 s> \r\n
72 s> 45\r\n
73 s> =\x00\x00\x01\x00\x02\x012
74 s> \xa2Eerror\xa1GmessageX\x1enodes argument must be definedFstatusEerror
72 s> 4e\r\n
73 s> F\x00\x00\x01\x00\x02\x012
74 s> \xa2Eerror\xa1GmessageX\'missing required arguments: nodes, pathFstatusEerror
75 75 s> \r\n
76 received frame(size=61; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=eos)
76 received frame(size=70; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=eos)
77 77 s> 0\r\n
78 78 s> \r\n
79 abort: nodes argument must be defined!
79 abort: missing required arguments: nodes, path!
80 80 [255]
81 81
82 82 $ sendhttpv2peer << EOF
83 83 > command filedata
84 84 > nodes eval:[]
85 85 > EOF
86 86 creating http peer for wire protocol version 2
87 87 sending filedata command
88 88 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
89 89 s> Accept-Encoding: identity\r\n
90 90 s> accept: application/mercurial-exp-framing-0005\r\n
91 91 s> content-type: application/mercurial-exp-framing-0005\r\n
92 92 s> content-length: 36\r\n
93 93 s> host: $LOCALIP:$HGPORT\r\n (glob)
94 94 s> user-agent: Mercurial debugwireproto\r\n
95 95 s> \r\n
96 96 s> \x1c\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa1Enodes\x80DnameHfiledata
97 97 s> makefile('rb', None)
98 98 s> HTTP/1.1 200 OK\r\n
99 99 s> Server: testing stub value\r\n
100 100 s> Date: $HTTP_DATE$\r\n
101 101 s> Content-Type: application/mercurial-exp-framing-0005\r\n
102 102 s> Transfer-Encoding: chunked\r\n
103 103 s> \r\n
104 s> 44\r\n
105 s> <\x00\x00\x01\x00\x02\x012
106 s> \xa2Eerror\xa1GmessageX\x1dpath argument must be definedFstatusEerror
104 s> 47\r\n
105 s> ?\x00\x00\x01\x00\x02\x012
106 s> \xa2Eerror\xa1GmessageX missing required arguments: pathFstatusEerror
107 107 s> \r\n
108 received frame(size=60; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=eos)
108 received frame(size=63; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=eos)
109 109 s> 0\r\n
110 110 s> \r\n
111 abort: path argument must be defined!
111 abort: missing required arguments: path!
112 112 [255]
113 113
114 114 Unknown node is an error
115 115
116 116 $ sendhttpv2peer << EOF
117 117 > command filedata
118 118 > nodes eval:[b'\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa']
119 119 > path eval:b'a'
120 120 > EOF
121 121 creating http peer for wire protocol version 2
122 122 sending filedata command
123 123 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
124 124 s> Accept-Encoding: identity\r\n
125 125 s> accept: application/mercurial-exp-framing-0005\r\n
126 126 s> content-type: application/mercurial-exp-framing-0005\r\n
127 127 s> content-length: 64\r\n
128 128 s> host: $LOCALIP:$HGPORT\r\n (glob)
129 129 s> user-agent: Mercurial debugwireproto\r\n
130 130 s> \r\n
131 131 s> 8\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa2Enodes\x81T\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaaDpathAaDnameHfiledata
132 132 s> makefile('rb', None)
133 133 s> HTTP/1.1 200 OK\r\n
134 134 s> Server: testing stub value\r\n
135 135 s> Date: $HTTP_DATE$\r\n
136 136 s> Content-Type: application/mercurial-exp-framing-0005\r\n
137 137 s> Transfer-Encoding: chunked\r\n
138 138 s> \r\n
139 139 s> 6b\r\n
140 140 s> c\x00\x00\x01\x00\x02\x012
141 141 s> \xa2Eerror\xa2Dargs\x81X(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGmessageUunknown file node: %sFstatusEerror
142 142 s> \r\n
143 143 received frame(size=99; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=eos)
144 144 s> 0\r\n
145 145 s> \r\n
146 146 abort: unknown file node: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!
147 147 [255]
148 148
149 149 Fetching a single revision returns just metadata by default
150 150
151 151 $ sendhttpv2peer << EOF
152 152 > command filedata
153 153 > nodes eval:[b'\x9a\x38\x12\x29\x97\xb3\xac\x97\xbe\x2a\x9a\xa2\xe5\x56\x83\x83\x41\xfd\xf2\xcc']
154 154 > path eval:b'a'
155 155 > EOF
156 156 creating http peer for wire protocol version 2
157 157 sending filedata command
158 158 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
159 159 s> Accept-Encoding: identity\r\n
160 160 s> accept: application/mercurial-exp-framing-0005\r\n
161 161 s> content-type: application/mercurial-exp-framing-0005\r\n
162 162 s> content-length: 64\r\n
163 163 s> host: $LOCALIP:$HGPORT\r\n (glob)
164 164 s> user-agent: Mercurial debugwireproto\r\n
165 165 s> \r\n
166 166 s> 8\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa2Enodes\x81T\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccDpathAaDnameHfiledata
167 167 s> makefile('rb', None)
168 168 s> HTTP/1.1 200 OK\r\n
169 169 s> Server: testing stub value\r\n
170 170 s> Date: $HTTP_DATE$\r\n
171 171 s> Content-Type: application/mercurial-exp-framing-0005\r\n
172 172 s> Transfer-Encoding: chunked\r\n
173 173 s> \r\n
174 174 s> 13\r\n
175 175 s> \x0b\x00\x00\x01\x00\x02\x011
176 176 s> \xa1FstatusBok
177 177 s> \r\n
178 178 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
179 179 s> 30\r\n
180 180 s> (\x00\x00\x01\x00\x02\x001
181 181 s> \xa1Jtotalitems\x01\xa1DnodeT\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xcc
182 182 s> \r\n
183 183 received frame(size=40; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
184 184 s> 8\r\n
185 185 s> \x00\x00\x00\x01\x00\x02\x002
186 186 s> \r\n
187 187 s> 0\r\n
188 188 s> \r\n
189 189 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
190 190 response: gen[
191 191 {
192 192 b'totalitems': 1
193 193 },
194 194 {
195 195 b'node': b'\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xcc'
196 196 }
197 197 ]
198 198
199 199 Requesting parents works
200 200
201 201 $ sendhttpv2peer << EOF
202 202 > command filedata
203 203 > nodes eval:[b'\x9a\x38\x12\x29\x97\xb3\xac\x97\xbe\x2a\x9a\xa2\xe5\x56\x83\x83\x41\xfd\xf2\xcc']
204 204 > path eval:b'a'
205 205 > fields eval:[b'parents']
206 206 > EOF
207 207 creating http peer for wire protocol version 2
208 208 sending filedata command
209 209 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
210 210 s> Accept-Encoding: identity\r\n
211 211 s> accept: application/mercurial-exp-framing-0005\r\n
212 212 s> content-type: application/mercurial-exp-framing-0005\r\n
213 213 s> content-length: 80\r\n
214 214 s> host: $LOCALIP:$HGPORT\r\n (glob)
215 215 s> user-agent: Mercurial debugwireproto\r\n
216 216 s> \r\n
217 217 s> H\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa3Ffields\x81GparentsEnodes\x81T\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccDpathAaDnameHfiledata
218 218 s> makefile('rb', None)
219 219 s> HTTP/1.1 200 OK\r\n
220 220 s> Server: testing stub value\r\n
221 221 s> Date: $HTTP_DATE$\r\n
222 222 s> Content-Type: application/mercurial-exp-framing-0005\r\n
223 223 s> Transfer-Encoding: chunked\r\n
224 224 s> \r\n
225 225 s> 13\r\n
226 226 s> \x0b\x00\x00\x01\x00\x02\x011
227 227 s> \xa1FstatusBok
228 228 s> \r\n
229 229 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
230 230 s> 63\r\n
231 231 s> [\x00\x00\x01\x00\x02\x001
232 232 s> \xa1Jtotalitems\x01\xa2DnodeT\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccGparents\x82T+N\xb0s\x19\xbf\xa0w\xa4\n
233 233 s> /\x04\x916Y\xae\xf0\xdaB\xdaT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
234 234 s> \r\n
235 235 received frame(size=91; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
236 236 s> 8\r\n
237 237 s> \x00\x00\x00\x01\x00\x02\x002
238 238 s> \r\n
239 239 s> 0\r\n
240 240 s> \r\n
241 241 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
242 242 response: gen[
243 243 {
244 244 b'totalitems': 1
245 245 },
246 246 {
247 247 b'node': b'\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xcc',
248 248 b'parents': [
249 249 b'+N\xb0s\x19\xbf\xa0w\xa4\n/\x04\x916Y\xae\xf0\xdaB\xda',
250 250 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
251 251 ]
252 252 }
253 253 ]
254 254
255 255 Requesting revision data works
256 256 (haveparents defaults to False, so fulltext is emitted)
257 257
258 258 $ sendhttpv2peer << EOF
259 259 > command filedata
260 260 > nodes eval:[b'\x9a\x38\x12\x29\x97\xb3\xac\x97\xbe\x2a\x9a\xa2\xe5\x56\x83\x83\x41\xfd\xf2\xcc']
261 261 > path eval:b'a'
262 262 > fields eval:[b'revision']
263 263 > EOF
264 264 creating http peer for wire protocol version 2
265 265 sending filedata command
266 266 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
267 267 s> Accept-Encoding: identity\r\n
268 268 s> accept: application/mercurial-exp-framing-0005\r\n
269 269 s> content-type: application/mercurial-exp-framing-0005\r\n
270 270 s> content-length: 81\r\n
271 271 s> host: $LOCALIP:$HGPORT\r\n (glob)
272 272 s> user-agent: Mercurial debugwireproto\r\n
273 273 s> \r\n
274 274 s> I\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa3Ffields\x81HrevisionEnodes\x81T\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccDpathAaDnameHfiledata
275 275 s> makefile('rb', None)
276 276 s> HTTP/1.1 200 OK\r\n
277 277 s> Server: testing stub value\r\n
278 278 s> Date: $HTTP_DATE$\r\n
279 279 s> Content-Type: application/mercurial-exp-framing-0005\r\n
280 280 s> Transfer-Encoding: chunked\r\n
281 281 s> \r\n
282 282 s> 13\r\n
283 283 s> \x0b\x00\x00\x01\x00\x02\x011
284 284 s> \xa1FstatusBok
285 285 s> \r\n
286 286 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
287 287 s> 42\r\n
288 288 s> :\x00\x00\x01\x00\x02\x001
289 289 s> \xa1Jtotalitems\x01\xa2DnodeT\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccLrevisionsize\x03Ca1\n
290 290 s> \r\n
291 291 received frame(size=58; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
292 292 s> 8\r\n
293 293 s> \x00\x00\x00\x01\x00\x02\x002
294 294 s> \r\n
295 295 s> 0\r\n
296 296 s> \r\n
297 297 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
298 298 response: gen[
299 299 {
300 300 b'totalitems': 1
301 301 },
302 302 {
303 303 b'node': b'\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xcc',
304 304 b'revisionsize': 3
305 305 },
306 306 b'a1\n'
307 307 ]
308 308
309 309 haveparents=False should be same as above
310 310
311 311 $ sendhttpv2peer << EOF
312 312 > command filedata
313 313 > nodes eval:[b'\x9a\x38\x12\x29\x97\xb3\xac\x97\xbe\x2a\x9a\xa2\xe5\x56\x83\x83\x41\xfd\xf2\xcc']
314 314 > path eval:b'a'
315 315 > fields eval:[b'revision']
316 316 > haveparents eval:False
317 317 > EOF
318 318 creating http peer for wire protocol version 2
319 319 sending filedata command
320 320 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
321 321 s> Accept-Encoding: identity\r\n
322 322 s> accept: application/mercurial-exp-framing-0005\r\n
323 323 s> content-type: application/mercurial-exp-framing-0005\r\n
324 324 s> content-length: 94\r\n
325 325 s> host: $LOCALIP:$HGPORT\r\n (glob)
326 326 s> user-agent: Mercurial debugwireproto\r\n
327 327 s> \r\n
328 328 s> V\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa4Ffields\x81HrevisionKhaveparents\xf4Enodes\x81T\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccDpathAaDnameHfiledata
329 329 s> makefile('rb', None)
330 330 s> HTTP/1.1 200 OK\r\n
331 331 s> Server: testing stub value\r\n
332 332 s> Date: $HTTP_DATE$\r\n
333 333 s> Content-Type: application/mercurial-exp-framing-0005\r\n
334 334 s> Transfer-Encoding: chunked\r\n
335 335 s> \r\n
336 336 s> 13\r\n
337 337 s> \x0b\x00\x00\x01\x00\x02\x011
338 338 s> \xa1FstatusBok
339 339 s> \r\n
340 340 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
341 341 s> 42\r\n
342 342 s> :\x00\x00\x01\x00\x02\x001
343 343 s> \xa1Jtotalitems\x01\xa2DnodeT\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccLrevisionsize\x03Ca1\n
344 344 s> \r\n
345 345 received frame(size=58; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
346 346 s> 8\r\n
347 347 s> \x00\x00\x00\x01\x00\x02\x002
348 348 s> \r\n
349 349 s> 0\r\n
350 350 s> \r\n
351 351 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
352 352 response: gen[
353 353 {
354 354 b'totalitems': 1
355 355 },
356 356 {
357 357 b'node': b'\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xcc',
358 358 b'revisionsize': 3
359 359 },
360 360 b'a1\n'
361 361 ]
362 362
363 363 haveparents=True should emit a delta
364 364
365 365 $ sendhttpv2peer << EOF
366 366 > command filedata
367 367 > nodes eval:[b'\x9a\x38\x12\x29\x97\xb3\xac\x97\xbe\x2a\x9a\xa2\xe5\x56\x83\x83\x41\xfd\xf2\xcc']
368 368 > path eval:b'a'
369 369 > fields eval:[b'revision']
370 370 > haveparents eval:True
371 371 > EOF
372 372 creating http peer for wire protocol version 2
373 373 sending filedata command
374 374 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
375 375 s> Accept-Encoding: identity\r\n
376 376 s> accept: application/mercurial-exp-framing-0005\r\n
377 377 s> content-type: application/mercurial-exp-framing-0005\r\n
378 378 s> content-length: 94\r\n
379 379 s> host: $LOCALIP:$HGPORT\r\n (glob)
380 380 s> user-agent: Mercurial debugwireproto\r\n
381 381 s> \r\n
382 382 s> V\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa4Ffields\x81HrevisionKhaveparents\xf5Enodes\x81T\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccDpathAaDnameHfiledata
383 383 s> makefile('rb', None)
384 384 s> HTTP/1.1 200 OK\r\n
385 385 s> Server: testing stub value\r\n
386 386 s> Date: $HTTP_DATE$\r\n
387 387 s> Content-Type: application/mercurial-exp-framing-0005\r\n
388 388 s> Transfer-Encoding: chunked\r\n
389 389 s> \r\n
390 390 s> 13\r\n
391 391 s> \x0b\x00\x00\x01\x00\x02\x011
392 392 s> \xa1FstatusBok
393 393 s> \r\n
394 394 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
395 395 s> 6e\r\n
396 396 s> f\x00\x00\x01\x00\x02\x001
397 397 s> \xa1Jtotalitems\x01\xa3MdeltabasenodeT+N\xb0s\x19\xbf\xa0w\xa4\n
398 398 s> /\x04\x916Y\xae\xf0\xdaB\xdaIdeltasize\x0fDnodeT\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccO\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03a1\n
399 399 s> \r\n
400 400 received frame(size=102; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
401 401 s> 8\r\n
402 402 s> \x00\x00\x00\x01\x00\x02\x002
403 403 s> \r\n
404 404 s> 0\r\n
405 405 s> \r\n
406 406 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
407 407 response: gen[
408 408 {
409 409 b'totalitems': 1
410 410 },
411 411 {
412 412 b'deltabasenode': b'+N\xb0s\x19\xbf\xa0w\xa4\n/\x04\x916Y\xae\xf0\xdaB\xda',
413 413 b'deltasize': 15,
414 414 b'node': b'\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xcc'
415 415 },
416 416 b'\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03a1\n'
417 417 ]
418 418
419 419 Requesting multiple revisions works
420 420 (first revision is a fulltext since haveparents=False by default)
421 421
422 422 $ sendhttpv2peer << EOF
423 423 > command filedata
424 424 > nodes eval:['\x2b\x4e\xb0\x73\x19\xbf\xa0\x77\xa4\x0a\x2f\x04\x91\x36\x59\xae\xf0\xda\x42\xda', '\x9a\x38\x12\x29\x97\xb3\xac\x97\xbe\x2a\x9a\xa2\xe5\x56\x83\x83\x41\xfd\xf2\xcc']
425 425 > path eval:b'a'
426 426 > fields eval:[b'revision']
427 427 > EOF
428 428 creating http peer for wire protocol version 2
429 429 sending filedata command
430 430 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
431 431 s> Accept-Encoding: identity\r\n
432 432 s> accept: application/mercurial-exp-framing-0005\r\n
433 433 s> content-type: application/mercurial-exp-framing-0005\r\n
434 434 s> content-length: 102\r\n
435 435 s> host: $LOCALIP:$HGPORT\r\n (glob)
436 436 s> user-agent: Mercurial debugwireproto\r\n
437 437 s> \r\n
438 438 s> ^\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa3Ffields\x81HrevisionEnodes\x82T+N\xb0s\x19\xbf\xa0w\xa4\n
439 439 s> /\x04\x916Y\xae\xf0\xdaB\xdaT\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccDpathAaDnameHfiledata
440 440 s> makefile('rb', None)
441 441 s> HTTP/1.1 200 OK\r\n
442 442 s> Server: testing stub value\r\n
443 443 s> Date: $HTTP_DATE$\r\n
444 444 s> Content-Type: application/mercurial-exp-framing-0005\r\n
445 445 s> Transfer-Encoding: chunked\r\n
446 446 s> \r\n
447 447 s> 13\r\n
448 448 s> \x0b\x00\x00\x01\x00\x02\x011
449 449 s> \xa1FstatusBok
450 450 s> \r\n
451 451 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
452 452 s> 9b\r\n
453 453 s> \x93\x00\x00\x01\x00\x02\x001
454 454 s> \xa1Jtotalitems\x02\xa2DnodeT+N\xb0s\x19\xbf\xa0w\xa4\n
455 455 s> /\x04\x916Y\xae\xf0\xdaB\xdaLrevisionsize\x03Ca0\n
456 456 s> \xa3MdeltabasenodeT+N\xb0s\x19\xbf\xa0w\xa4\n
457 457 s> /\x04\x916Y\xae\xf0\xdaB\xdaIdeltasize\x0fDnodeT\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccO\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03a1\n
458 458 s> \r\n
459 459 received frame(size=147; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
460 460 s> 8\r\n
461 461 s> \x00\x00\x00\x01\x00\x02\x002
462 462 s> \r\n
463 463 s> 0\r\n
464 464 s> \r\n
465 465 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
466 466 response: gen[
467 467 {
468 468 b'totalitems': 2
469 469 },
470 470 {
471 471 b'node': b'+N\xb0s\x19\xbf\xa0w\xa4\n/\x04\x916Y\xae\xf0\xdaB\xda',
472 472 b'revisionsize': 3
473 473 },
474 474 b'a0\n',
475 475 {
476 476 b'deltabasenode': b'+N\xb0s\x19\xbf\xa0w\xa4\n/\x04\x916Y\xae\xf0\xdaB\xda',
477 477 b'deltasize': 15,
478 478 b'node': b'\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xcc'
479 479 },
480 480 b'\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03a1\n'
481 481 ]
482 482
483 483 Revisions are sorted by DAG order, parents first
484 484
485 485 $ sendhttpv2peer << EOF
486 486 > command filedata
487 487 > nodes eval:['\x9a\x38\x12\x29\x97\xb3\xac\x97\xbe\x2a\x9a\xa2\xe5\x56\x83\x83\x41\xfd\xf2\xcc', '\x2b\x4e\xb0\x73\x19\xbf\xa0\x77\xa4\x0a\x2f\x04\x91\x36\x59\xae\xf0\xda\x42\xda']
488 488 > path eval:b'a'
489 489 > fields eval:[b'revision']
490 490 > EOF
491 491 creating http peer for wire protocol version 2
492 492 sending filedata command
493 493 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
494 494 s> Accept-Encoding: identity\r\n
495 495 s> accept: application/mercurial-exp-framing-0005\r\n
496 496 s> content-type: application/mercurial-exp-framing-0005\r\n
497 497 s> content-length: 102\r\n
498 498 s> host: $LOCALIP:$HGPORT\r\n (glob)
499 499 s> user-agent: Mercurial debugwireproto\r\n
500 500 s> \r\n
501 501 s> ^\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa3Ffields\x81HrevisionEnodes\x82T\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccT+N\xb0s\x19\xbf\xa0w\xa4\n
502 502 s> /\x04\x916Y\xae\xf0\xdaB\xdaDpathAaDnameHfiledata
503 503 s> makefile('rb', None)
504 504 s> HTTP/1.1 200 OK\r\n
505 505 s> Server: testing stub value\r\n
506 506 s> Date: $HTTP_DATE$\r\n
507 507 s> Content-Type: application/mercurial-exp-framing-0005\r\n
508 508 s> Transfer-Encoding: chunked\r\n
509 509 s> \r\n
510 510 s> 13\r\n
511 511 s> \x0b\x00\x00\x01\x00\x02\x011
512 512 s> \xa1FstatusBok
513 513 s> \r\n
514 514 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
515 515 s> 9b\r\n
516 516 s> \x93\x00\x00\x01\x00\x02\x001
517 517 s> \xa1Jtotalitems\x02\xa2DnodeT+N\xb0s\x19\xbf\xa0w\xa4\n
518 518 s> /\x04\x916Y\xae\xf0\xdaB\xdaLrevisionsize\x03Ca0\n
519 519 s> \xa3MdeltabasenodeT+N\xb0s\x19\xbf\xa0w\xa4\n
520 520 s> /\x04\x916Y\xae\xf0\xdaB\xdaIdeltasize\x0fDnodeT\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccO\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03a1\n
521 521 s> \r\n
522 522 received frame(size=147; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
523 523 s> 8\r\n
524 524 s> \x00\x00\x00\x01\x00\x02\x002
525 525 s> \r\n
526 526 s> 0\r\n
527 527 s> \r\n
528 528 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
529 529 response: gen[
530 530 {
531 531 b'totalitems': 2
532 532 },
533 533 {
534 534 b'node': b'+N\xb0s\x19\xbf\xa0w\xa4\n/\x04\x916Y\xae\xf0\xdaB\xda',
535 535 b'revisionsize': 3
536 536 },
537 537 b'a0\n',
538 538 {
539 539 b'deltabasenode': b'+N\xb0s\x19\xbf\xa0w\xa4\n/\x04\x916Y\xae\xf0\xdaB\xda',
540 540 b'deltasize': 15,
541 541 b'node': b'\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xcc'
542 542 },
543 543 b'\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03a1\n'
544 544 ]
545 545
546 546 Requesting parents and revision data works
547 547
548 548 $ sendhttpv2peer << EOF
549 549 > command filedata
550 550 > nodes eval:['\x08\x79\x34\x5e\x39\x37\x72\x29\x63\x4b\x42\x0c\x63\x94\x54\x15\x67\x26\xc6\xb6']
551 551 > path eval:b'a'
552 552 > fields eval:[b'parents', b'revision']
553 553 > EOF
554 554 creating http peer for wire protocol version 2
555 555 sending filedata command
556 556 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
557 557 s> Accept-Encoding: identity\r\n
558 558 s> accept: application/mercurial-exp-framing-0005\r\n
559 559 s> content-type: application/mercurial-exp-framing-0005\r\n
560 560 s> content-length: 89\r\n
561 561 s> host: $LOCALIP:$HGPORT\r\n (glob)
562 562 s> user-agent: Mercurial debugwireproto\r\n
563 563 s> \r\n
564 564 s> Q\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa3Ffields\x82GparentsHrevisionEnodes\x81T\x08y4^97r)cKB\x0cc\x94T\x15g&\xc6\xb6DpathAaDnameHfiledata
565 565 s> makefile('rb', None)
566 566 s> HTTP/1.1 200 OK\r\n
567 567 s> Server: testing stub value\r\n
568 568 s> Date: $HTTP_DATE$\r\n
569 569 s> Content-Type: application/mercurial-exp-framing-0005\r\n
570 570 s> Transfer-Encoding: chunked\r\n
571 571 s> \r\n
572 572 s> 13\r\n
573 573 s> \x0b\x00\x00\x01\x00\x02\x011
574 574 s> \xa1FstatusBok
575 575 s> \r\n
576 576 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
577 577 s> 75\r\n
578 578 s> m\x00\x00\x01\x00\x02\x001
579 579 s> \xa1Jtotalitems\x01\xa3DnodeT\x08y4^97r)cKB\x0cc\x94T\x15g&\xc6\xb6Gparents\x82T+N\xb0s\x19\xbf\xa0w\xa4\n
580 580 s> /\x04\x916Y\xae\xf0\xdaB\xdaT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Lrevisionsize\x03Ca2\n
581 581 s> \r\n
582 582 received frame(size=109; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
583 583 s> 8\r\n
584 584 s> \x00\x00\x00\x01\x00\x02\x002
585 585 s> \r\n
586 586 s> 0\r\n
587 587 s> \r\n
588 588 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
589 589 response: gen[
590 590 {
591 591 b'totalitems': 1
592 592 },
593 593 {
594 594 b'node': b'\x08y4^97r)cKB\x0cc\x94T\x15g&\xc6\xb6',
595 595 b'parents': [
596 596 b'+N\xb0s\x19\xbf\xa0w\xa4\n/\x04\x916Y\xae\xf0\xdaB\xda',
597 597 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
598 598 ],
599 599 b'revisionsize': 3
600 600 },
601 601 b'a2\n'
602 602 ]
603 603
604 604 $ cat error.log
@@ -1,694 +1,694
1 1 $ . $TESTDIR/wireprotohelpers.sh
2 2
3 3 $ hg init server
4 4 $ enablehttpv2 server
5 5 $ cd server
6 6 $ echo a0 > a
7 7 $ echo b0 > b
8 8 $ mkdir -p dir0/child0 dir0/child1 dir1
9 9 $ echo c0 > dir0/c
10 10 $ echo d0 > dir0/d
11 11 $ echo e0 > dir0/child0/e
12 12 $ echo f0 > dir0/child1/f
13 13 $ hg -q commit -A -m 'commit 0'
14 14
15 15 $ echo a1 > a
16 16 $ echo d1 > dir0/d
17 17 $ hg commit -m 'commit 1'
18 18 $ echo f0 > dir0/child1/f
19 19 $ hg commit -m 'commit 2'
20 20 nothing changed
21 21 [1]
22 22
23 23 $ hg -q up -r 0
24 24 $ echo a2 > a
25 25 $ hg commit -m 'commit 3'
26 26 created new head
27 27
28 28 $ hg log -G -T '{rev}:{node} {desc}\n'
29 29 @ 2:c8757a2ffe552850d1e0dfe60d295ebf64c196d9 commit 3
30 30 |
31 31 | o 1:650165e803375748a94df471e5b58d85763e0b29 commit 1
32 32 |/
33 33 o 0:6d85ca1270b377d320098556ba5bfad34a9ee12d commit 0
34 34
35 35
36 36 $ hg --debug debugindex -m
37 37 rev linkrev nodeid p1 p2
38 38 0 0 1b175b595f022cfab5b809cc0ed551bd0b3ff5e4 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
39 39 1 1 91e0bdbfb0dde0023fa063edc1445f207a22eac7 1b175b595f022cfab5b809cc0ed551bd0b3ff5e4 0000000000000000000000000000000000000000
40 40 2 2 46a6721b5edaf0ea04b79a5cb3218854a4d2aba0 1b175b595f022cfab5b809cc0ed551bd0b3ff5e4 0000000000000000000000000000000000000000
41 41
42 42 $ hg serve -p $HGPORT -d --pid-file hg.pid -E error.log
43 43 $ cat hg.pid > $DAEMON_PIDS
44 44
45 45 Missing arguments is an error
46 46
47 47 $ sendhttpv2peer << EOF
48 48 > command manifestdata
49 49 > EOF
50 50 creating http peer for wire protocol version 2
51 51 sending manifestdata command
52 52 s> POST /api/exp-http-v2-0001/ro/manifestdata HTTP/1.1\r\n
53 53 s> Accept-Encoding: identity\r\n
54 54 s> accept: application/mercurial-exp-framing-0005\r\n
55 55 s> content-type: application/mercurial-exp-framing-0005\r\n
56 56 s> content-length: 27\r\n
57 57 s> host: $LOCALIP:$HGPORT\r\n (glob)
58 58 s> user-agent: Mercurial debugwireproto\r\n
59 59 s> \r\n
60 60 s> \x13\x00\x00\x01\x00\x01\x01\x11\xa1DnameLmanifestdata
61 61 s> makefile('rb', None)
62 62 s> HTTP/1.1 200 OK\r\n
63 63 s> Server: testing stub value\r\n
64 64 s> Date: $HTTP_DATE$\r\n
65 65 s> Content-Type: application/mercurial-exp-framing-0005\r\n
66 66 s> Transfer-Encoding: chunked\r\n
67 67 s> \r\n
68 s> 45\r\n
69 s> =\x00\x00\x01\x00\x02\x012
70 s> \xa2Eerror\xa1GmessageX\x1enodes argument must be definedFstatusEerror
68 s> 4e\r\n
69 s> F\x00\x00\x01\x00\x02\x012
70 s> \xa2Eerror\xa1GmessageX\'missing required arguments: nodes, treeFstatusEerror
71 71 s> \r\n
72 received frame(size=61; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=eos)
72 received frame(size=70; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=eos)
73 73 s> 0\r\n
74 74 s> \r\n
75 abort: nodes argument must be defined!
75 abort: missing required arguments: nodes, tree!
76 76 [255]
77 77
78 78 $ sendhttpv2peer << EOF
79 79 > command manifestdata
80 80 > nodes eval:[]
81 81 > EOF
82 82 creating http peer for wire protocol version 2
83 83 sending manifestdata command
84 84 s> POST /api/exp-http-v2-0001/ro/manifestdata HTTP/1.1\r\n
85 85 s> Accept-Encoding: identity\r\n
86 86 s> accept: application/mercurial-exp-framing-0005\r\n
87 87 s> content-type: application/mercurial-exp-framing-0005\r\n
88 88 s> content-length: 40\r\n
89 89 s> host: $LOCALIP:$HGPORT\r\n (glob)
90 90 s> user-agent: Mercurial debugwireproto\r\n
91 91 s> \r\n
92 92 s> \x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa1Enodes\x80DnameLmanifestdata
93 93 s> makefile('rb', None)
94 94 s> HTTP/1.1 200 OK\r\n
95 95 s> Server: testing stub value\r\n
96 96 s> Date: $HTTP_DATE$\r\n
97 97 s> Content-Type: application/mercurial-exp-framing-0005\r\n
98 98 s> Transfer-Encoding: chunked\r\n
99 99 s> \r\n
100 s> 44\r\n
101 s> <\x00\x00\x01\x00\x02\x012
102 s> \xa2Eerror\xa1GmessageX\x1dtree argument must be definedFstatusEerror
100 s> 47\r\n
101 s> ?\x00\x00\x01\x00\x02\x012
102 s> \xa2Eerror\xa1GmessageX missing required arguments: treeFstatusEerror
103 103 s> \r\n
104 received frame(size=60; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=eos)
104 received frame(size=63; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=eos)
105 105 s> 0\r\n
106 106 s> \r\n
107 abort: tree argument must be defined!
107 abort: missing required arguments: tree!
108 108 [255]
109 109
110 110 Unknown node is an error
111 111
112 112 $ sendhttpv2peer << EOF
113 113 > command manifestdata
114 114 > nodes eval:[b'\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa']
115 115 > tree eval:b''
116 116 > EOF
117 117 creating http peer for wire protocol version 2
118 118 sending manifestdata command
119 119 s> POST /api/exp-http-v2-0001/ro/manifestdata HTTP/1.1\r\n
120 120 s> Accept-Encoding: identity\r\n
121 121 s> accept: application/mercurial-exp-framing-0005\r\n
122 122 s> content-type: application/mercurial-exp-framing-0005\r\n
123 123 s> content-length: 67\r\n
124 124 s> host: $LOCALIP:$HGPORT\r\n (glob)
125 125 s> user-agent: Mercurial debugwireproto\r\n
126 126 s> \r\n
127 127 s> ;\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa2Enodes\x81T\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaaDtree@DnameLmanifestdata
128 128 s> makefile('rb', None)
129 129 s> HTTP/1.1 200 OK\r\n
130 130 s> Server: testing stub value\r\n
131 131 s> Date: $HTTP_DATE$\r\n
132 132 s> Content-Type: application/mercurial-exp-framing-0005\r\n
133 133 s> Transfer-Encoding: chunked\r\n
134 134 s> \r\n
135 135 s> 51\r\n
136 136 s> I\x00\x00\x01\x00\x02\x012
137 137 s> \xa2Eerror\xa2Dargs\x81T\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaaGmessagePunknown node: %sFstatusEerror
138 138 s> \r\n
139 139 received frame(size=73; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=eos)
140 140 s> 0\r\n
141 141 s> \r\n
142 142 abort: unknown node: \xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa! (esc)
143 143 [255]
144 144
145 145 Fetching a single revision returns just metadata by default
146 146
147 147 $ sendhttpv2peer << EOF
148 148 > command manifestdata
149 149 > nodes eval:[b'\x46\xa6\x72\x1b\x5e\xda\xf0\xea\x04\xb7\x9a\x5c\xb3\x21\x88\x54\xa4\xd2\xab\xa0']
150 150 > tree eval:b''
151 151 > EOF
152 152 creating http peer for wire protocol version 2
153 153 sending manifestdata command
154 154 s> POST /api/exp-http-v2-0001/ro/manifestdata HTTP/1.1\r\n
155 155 s> Accept-Encoding: identity\r\n
156 156 s> accept: application/mercurial-exp-framing-0005\r\n
157 157 s> content-type: application/mercurial-exp-framing-0005\r\n
158 158 s> content-length: 67\r\n
159 159 s> host: $LOCALIP:$HGPORT\r\n (glob)
160 160 s> user-agent: Mercurial debugwireproto\r\n
161 161 s> \r\n
162 162 s> ;\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa2Enodes\x81TF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0Dtree@DnameLmanifestdata
163 163 s> makefile('rb', None)
164 164 s> HTTP/1.1 200 OK\r\n
165 165 s> Server: testing stub value\r\n
166 166 s> Date: $HTTP_DATE$\r\n
167 167 s> Content-Type: application/mercurial-exp-framing-0005\r\n
168 168 s> Transfer-Encoding: chunked\r\n
169 169 s> \r\n
170 170 s> 13\r\n
171 171 s> \x0b\x00\x00\x01\x00\x02\x011
172 172 s> \xa1FstatusBok
173 173 s> \r\n
174 174 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
175 175 s> 30\r\n
176 176 s> (\x00\x00\x01\x00\x02\x001
177 177 s> \xa1Jtotalitems\x01\xa1DnodeTF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0
178 178 s> \r\n
179 179 received frame(size=40; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
180 180 s> 8\r\n
181 181 s> \x00\x00\x00\x01\x00\x02\x002
182 182 s> \r\n
183 183 s> 0\r\n
184 184 s> \r\n
185 185 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
186 186 response: gen[
187 187 {
188 188 b'totalitems': 1
189 189 },
190 190 {
191 191 b'node': b'F\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0'
192 192 }
193 193 ]
194 194
195 195 Requesting parents works
196 196
197 197 $ sendhttpv2peer << EOF
198 198 > command manifestdata
199 199 > nodes eval:[b'\x46\xa6\x72\x1b\x5e\xda\xf0\xea\x04\xb7\x9a\x5c\xb3\x21\x88\x54\xa4\xd2\xab\xa0']
200 200 > tree eval:b''
201 201 > fields eval:[b'parents']
202 202 > EOF
203 203 creating http peer for wire protocol version 2
204 204 sending manifestdata command
205 205 s> POST /api/exp-http-v2-0001/ro/manifestdata HTTP/1.1\r\n
206 206 s> Accept-Encoding: identity\r\n
207 207 s> accept: application/mercurial-exp-framing-0005\r\n
208 208 s> content-type: application/mercurial-exp-framing-0005\r\n
209 209 s> content-length: 83\r\n
210 210 s> host: $LOCALIP:$HGPORT\r\n (glob)
211 211 s> user-agent: Mercurial debugwireproto\r\n
212 212 s> \r\n
213 213 s> K\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa3Ffields\x81GparentsEnodes\x81TF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0Dtree@DnameLmanifestdata
214 214 s> makefile('rb', None)
215 215 s> HTTP/1.1 200 OK\r\n
216 216 s> Server: testing stub value\r\n
217 217 s> Date: $HTTP_DATE$\r\n
218 218 s> Content-Type: application/mercurial-exp-framing-0005\r\n
219 219 s> Transfer-Encoding: chunked\r\n
220 220 s> \r\n
221 221 s> 13\r\n
222 222 s> \x0b\x00\x00\x01\x00\x02\x011
223 223 s> \xa1FstatusBok
224 224 s> \r\n
225 225 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
226 226 s> 63\r\n
227 227 s> [\x00\x00\x01\x00\x02\x001
228 228 s> \xa1Jtotalitems\x01\xa2DnodeTF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0Gparents\x82T\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4T\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
229 229 s> \r\n
230 230 received frame(size=91; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
231 231 s> 8\r\n
232 232 s> \x00\x00\x00\x01\x00\x02\x002
233 233 s> \r\n
234 234 s> 0\r\n
235 235 s> \r\n
236 236 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
237 237 response: gen[
238 238 {
239 239 b'totalitems': 1
240 240 },
241 241 {
242 242 b'node': b'F\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0',
243 243 b'parents': [
244 244 b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4',
245 245 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
246 246 ]
247 247 }
248 248 ]
249 249
250 250 Requesting revision data works
251 251 (haveparents defaults to false, so fulltext is emitted)
252 252
253 253 $ sendhttpv2peer << EOF
254 254 > command manifestdata
255 255 > nodes eval:[b'\x46\xa6\x72\x1b\x5e\xda\xf0\xea\x04\xb7\x9a\x5c\xb3\x21\x88\x54\xa4\xd2\xab\xa0']
256 256 > tree eval:b''
257 257 > fields eval:[b'revision']
258 258 > EOF
259 259 creating http peer for wire protocol version 2
260 260 sending manifestdata command
261 261 s> POST /api/exp-http-v2-0001/ro/manifestdata HTTP/1.1\r\n
262 262 s> Accept-Encoding: identity\r\n
263 263 s> accept: application/mercurial-exp-framing-0005\r\n
264 264 s> content-type: application/mercurial-exp-framing-0005\r\n
265 265 s> content-length: 84\r\n
266 266 s> host: $LOCALIP:$HGPORT\r\n (glob)
267 267 s> user-agent: Mercurial debugwireproto\r\n
268 268 s> \r\n
269 269 s> L\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa3Ffields\x81HrevisionEnodes\x81TF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0Dtree@DnameLmanifestdata
270 270 s> makefile('rb', None)
271 271 s> HTTP/1.1 200 OK\r\n
272 272 s> Server: testing stub value\r\n
273 273 s> Date: $HTTP_DATE$\r\n
274 274 s> Content-Type: application/mercurial-exp-framing-0005\r\n
275 275 s> Transfer-Encoding: chunked\r\n
276 276 s> \r\n
277 277 s> 13\r\n
278 278 s> \x0b\x00\x00\x01\x00\x02\x011
279 279 s> \xa1FstatusBok
280 280 s> \r\n
281 281 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
282 282 s> 167\r\n
283 283 s> _\x01\x00\x01\x00\x02\x001
284 284 s> \xa1Jtotalitems\x01\xa2DnodeTF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0Lrevisionsize\x19\x01$Y\x01$a\x000879345e39377229634b420c639454156726c6b6\n
285 285 s> b\x00819e258d31a5e1606629f365bb902a1b21ee4216\n
286 286 s> dir0/c\x00914445346a0ca0629bd47ceb5dfe07e4d4cf2501\n
287 287 s> dir0/child0/e\x00bbba6c06b30f443d34ff841bc985c4d0827c6be4\n
288 288 s> dir0/child1/f\x0012fc7dcd773b5a0a929ce195228083c6ddc9cec4\n
289 289 s> dir0/d\x00538206dc971e521540d6843abfe6d16032f6d426\n
290 290 s> \r\n
291 291 received frame(size=351; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
292 292 s> 8\r\n
293 293 s> \x00\x00\x00\x01\x00\x02\x002
294 294 s> \r\n
295 295 s> 0\r\n
296 296 s> \r\n
297 297 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
298 298 response: gen[
299 299 {
300 300 b'totalitems': 1
301 301 },
302 302 {
303 303 b'node': b'F\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0',
304 304 b'revisionsize': 292
305 305 },
306 306 b'a\x000879345e39377229634b420c639454156726c6b6\nb\x00819e258d31a5e1606629f365bb902a1b21ee4216\ndir0/c\x00914445346a0ca0629bd47ceb5dfe07e4d4cf2501\ndir0/child0/e\x00bbba6c06b30f443d34ff841bc985c4d0827c6be4\ndir0/child1/f\x0012fc7dcd773b5a0a929ce195228083c6ddc9cec4\ndir0/d\x00538206dc971e521540d6843abfe6d16032f6d426\n'
307 307 ]
308 308
309 309 haveparents=False yields same output
310 310
311 311 $ sendhttpv2peer << EOF
312 312 > command manifestdata
313 313 > nodes eval:[b'\x46\xa6\x72\x1b\x5e\xda\xf0\xea\x04\xb7\x9a\x5c\xb3\x21\x88\x54\xa4\xd2\xab\xa0']
314 314 > tree eval:b''
315 315 > fields eval:[b'revision']
316 316 > haveparents eval:False
317 317 > EOF
318 318 creating http peer for wire protocol version 2
319 319 sending manifestdata command
320 320 s> POST /api/exp-http-v2-0001/ro/manifestdata HTTP/1.1\r\n
321 321 s> Accept-Encoding: identity\r\n
322 322 s> accept: application/mercurial-exp-framing-0005\r\n
323 323 s> content-type: application/mercurial-exp-framing-0005\r\n
324 324 s> content-length: 97\r\n
325 325 s> host: $LOCALIP:$HGPORT\r\n (glob)
326 326 s> user-agent: Mercurial debugwireproto\r\n
327 327 s> \r\n
328 328 s> Y\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa4Ffields\x81HrevisionKhaveparents\xf4Enodes\x81TF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0Dtree@DnameLmanifestdata
329 329 s> makefile('rb', None)
330 330 s> HTTP/1.1 200 OK\r\n
331 331 s> Server: testing stub value\r\n
332 332 s> Date: $HTTP_DATE$\r\n
333 333 s> Content-Type: application/mercurial-exp-framing-0005\r\n
334 334 s> Transfer-Encoding: chunked\r\n
335 335 s> \r\n
336 336 s> 13\r\n
337 337 s> \x0b\x00\x00\x01\x00\x02\x011
338 338 s> \xa1FstatusBok
339 339 s> \r\n
340 340 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
341 341 s> 167\r\n
342 342 s> _\x01\x00\x01\x00\x02\x001
343 343 s> \xa1Jtotalitems\x01\xa2DnodeTF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0Lrevisionsize\x19\x01$Y\x01$a\x000879345e39377229634b420c639454156726c6b6\n
344 344 s> b\x00819e258d31a5e1606629f365bb902a1b21ee4216\n
345 345 s> dir0/c\x00914445346a0ca0629bd47ceb5dfe07e4d4cf2501\n
346 346 s> dir0/child0/e\x00bbba6c06b30f443d34ff841bc985c4d0827c6be4\n
347 347 s> dir0/child1/f\x0012fc7dcd773b5a0a929ce195228083c6ddc9cec4\n
348 348 s> dir0/d\x00538206dc971e521540d6843abfe6d16032f6d426\n
349 349 s> \r\n
350 350 received frame(size=351; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
351 351 s> 8\r\n
352 352 s> \x00\x00\x00\x01\x00\x02\x002
353 353 s> \r\n
354 354 s> 0\r\n
355 355 s> \r\n
356 356 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
357 357 response: gen[
358 358 {
359 359 b'totalitems': 1
360 360 },
361 361 {
362 362 b'node': b'F\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0',
363 363 b'revisionsize': 292
364 364 },
365 365 b'a\x000879345e39377229634b420c639454156726c6b6\nb\x00819e258d31a5e1606629f365bb902a1b21ee4216\ndir0/c\x00914445346a0ca0629bd47ceb5dfe07e4d4cf2501\ndir0/child0/e\x00bbba6c06b30f443d34ff841bc985c4d0827c6be4\ndir0/child1/f\x0012fc7dcd773b5a0a929ce195228083c6ddc9cec4\ndir0/d\x00538206dc971e521540d6843abfe6d16032f6d426\n'
366 366 ]
367 367
368 368 haveparents=True will emit delta
369 369
370 370 $ sendhttpv2peer << EOF
371 371 > command manifestdata
372 372 > nodes eval:[b'\x46\xa6\x72\x1b\x5e\xda\xf0\xea\x04\xb7\x9a\x5c\xb3\x21\x88\x54\xa4\xd2\xab\xa0']
373 373 > tree eval:b''
374 374 > fields eval:[b'revision']
375 375 > haveparents eval:True
376 376 > EOF
377 377 creating http peer for wire protocol version 2
378 378 sending manifestdata command
379 379 s> POST /api/exp-http-v2-0001/ro/manifestdata HTTP/1.1\r\n
380 380 s> Accept-Encoding: identity\r\n
381 381 s> accept: application/mercurial-exp-framing-0005\r\n
382 382 s> content-type: application/mercurial-exp-framing-0005\r\n
383 383 s> content-length: 97\r\n
384 384 s> host: $LOCALIP:$HGPORT\r\n (glob)
385 385 s> user-agent: Mercurial debugwireproto\r\n
386 386 s> \r\n
387 387 s> Y\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa4Ffields\x81HrevisionKhaveparents\xf5Enodes\x81TF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0Dtree@DnameLmanifestdata
388 388 s> makefile('rb', None)
389 389 s> HTTP/1.1 200 OK\r\n
390 390 s> Server: testing stub value\r\n
391 391 s> Date: $HTTP_DATE$\r\n
392 392 s> Content-Type: application/mercurial-exp-framing-0005\r\n
393 393 s> Transfer-Encoding: chunked\r\n
394 394 s> \r\n
395 395 s> 13\r\n
396 396 s> \x0b\x00\x00\x01\x00\x02\x011
397 397 s> \xa1FstatusBok
398 398 s> \r\n
399 399 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
400 400 s> 98\r\n
401 401 s> \x90\x00\x00\x01\x00\x02\x001
402 402 s> \xa1Jtotalitems\x01\xa3MdeltabasenodeT\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4Ideltasize\x187DnodeTF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0X7\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00+a\x000879345e39377229634b420c639454156726c6b6\n
403 403 s> \r\n
404 404 received frame(size=144; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
405 405 s> 8\r\n
406 406 s> \x00\x00\x00\x01\x00\x02\x002
407 407 s> \r\n
408 408 s> 0\r\n
409 409 s> \r\n
410 410 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
411 411 response: gen[
412 412 {
413 413 b'totalitems': 1
414 414 },
415 415 {
416 416 b'deltabasenode': b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4',
417 417 b'deltasize': 55,
418 418 b'node': b'F\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0'
419 419 },
420 420 b'\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00+a\x000879345e39377229634b420c639454156726c6b6\n'
421 421 ]
422 422
423 423 Requesting multiple revisions works
424 424 (haveparents defaults to false, so fulltext is emitted unless a parent
425 425 has been emitted)
426 426
427 427 $ sendhttpv2peer << EOF
428 428 > command manifestdata
429 429 > nodes eval:[b'\x1b\x17\x5b\x59\x5f\x02\x2c\xfa\xb5\xb8\x09\xcc\x0e\xd5\x51\xbd\x0b\x3f\xf5\xe4', b'\x46\xa6\x72\x1b\x5e\xda\xf0\xea\x04\xb7\x9a\x5c\xb3\x21\x88\x54\xa4\xd2\xab\xa0']
430 430 > tree eval:b''
431 431 > fields eval:[b'revision']
432 432 > EOF
433 433 creating http peer for wire protocol version 2
434 434 sending manifestdata command
435 435 s> POST /api/exp-http-v2-0001/ro/manifestdata HTTP/1.1\r\n
436 436 s> Accept-Encoding: identity\r\n
437 437 s> accept: application/mercurial-exp-framing-0005\r\n
438 438 s> content-type: application/mercurial-exp-framing-0005\r\n
439 439 s> content-length: 105\r\n
440 440 s> host: $LOCALIP:$HGPORT\r\n (glob)
441 441 s> user-agent: Mercurial debugwireproto\r\n
442 442 s> \r\n
443 443 s> a\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa3Ffields\x81HrevisionEnodes\x82T\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4TF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0Dtree@DnameLmanifestdata
444 444 s> makefile('rb', None)
445 445 s> HTTP/1.1 200 OK\r\n
446 446 s> Server: testing stub value\r\n
447 447 s> Date: $HTTP_DATE$\r\n
448 448 s> Content-Type: application/mercurial-exp-framing-0005\r\n
449 449 s> Transfer-Encoding: chunked\r\n
450 450 s> \r\n
451 451 s> 13\r\n
452 452 s> \x0b\x00\x00\x01\x00\x02\x011
453 453 s> \xa1FstatusBok
454 454 s> \r\n
455 455 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
456 456 s> 1ea\r\n
457 457 s> \xe2\x01\x00\x01\x00\x02\x001
458 458 s> \xa1Jtotalitems\x02\xa2DnodeT\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4Lrevisionsize\x19\x01$Y\x01$a\x002b4eb07319bfa077a40a2f04913659aef0da42da\n
459 459 s> b\x00819e258d31a5e1606629f365bb902a1b21ee4216\n
460 460 s> dir0/c\x00914445346a0ca0629bd47ceb5dfe07e4d4cf2501\n
461 461 s> dir0/child0/e\x00bbba6c06b30f443d34ff841bc985c4d0827c6be4\n
462 462 s> dir0/child1/f\x0012fc7dcd773b5a0a929ce195228083c6ddc9cec4\n
463 463 s> dir0/d\x00538206dc971e521540d6843abfe6d16032f6d426\n
464 464 s> \xa3MdeltabasenodeT\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4Ideltasize\x187DnodeTF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0X7\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00+a\x000879345e39377229634b420c639454156726c6b6\n
465 465 s> \r\n
466 466 received frame(size=482; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
467 467 s> 8\r\n
468 468 s> \x00\x00\x00\x01\x00\x02\x002
469 469 s> \r\n
470 470 s> 0\r\n
471 471 s> \r\n
472 472 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
473 473 response: gen[
474 474 {
475 475 b'totalitems': 2
476 476 },
477 477 {
478 478 b'node': b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4',
479 479 b'revisionsize': 292
480 480 },
481 481 b'a\x002b4eb07319bfa077a40a2f04913659aef0da42da\nb\x00819e258d31a5e1606629f365bb902a1b21ee4216\ndir0/c\x00914445346a0ca0629bd47ceb5dfe07e4d4cf2501\ndir0/child0/e\x00bbba6c06b30f443d34ff841bc985c4d0827c6be4\ndir0/child1/f\x0012fc7dcd773b5a0a929ce195228083c6ddc9cec4\ndir0/d\x00538206dc971e521540d6843abfe6d16032f6d426\n',
482 482 {
483 483 b'deltabasenode': b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4',
484 484 b'deltasize': 55,
485 485 b'node': b'F\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0'
486 486 },
487 487 b'\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00+a\x000879345e39377229634b420c639454156726c6b6\n'
488 488 ]
489 489
490 490 With haveparents=True, first revision is a delta instead of fulltext
491 491
492 492 $ sendhttpv2peer << EOF
493 493 > command manifestdata
494 494 > nodes eval:[b'\x1b\x17\x5b\x59\x5f\x02\x2c\xfa\xb5\xb8\x09\xcc\x0e\xd5\x51\xbd\x0b\x3f\xf5\xe4', b'\x46\xa6\x72\x1b\x5e\xda\xf0\xea\x04\xb7\x9a\x5c\xb3\x21\x88\x54\xa4\xd2\xab\xa0']
495 495 > tree eval:b''
496 496 > fields eval:[b'revision']
497 497 > haveparents eval:True
498 498 > EOF
499 499 creating http peer for wire protocol version 2
500 500 sending manifestdata command
501 501 s> POST /api/exp-http-v2-0001/ro/manifestdata HTTP/1.1\r\n
502 502 s> Accept-Encoding: identity\r\n
503 503 s> accept: application/mercurial-exp-framing-0005\r\n
504 504 s> content-type: application/mercurial-exp-framing-0005\r\n
505 505 s> content-length: 118\r\n
506 506 s> host: $LOCALIP:$HGPORT\r\n (glob)
507 507 s> user-agent: Mercurial debugwireproto\r\n
508 508 s> \r\n
509 509 s> n\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa4Ffields\x81HrevisionKhaveparents\xf5Enodes\x82T\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4TF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0Dtree@DnameLmanifestdata
510 510 s> makefile('rb', None)
511 511 s> HTTP/1.1 200 OK\r\n
512 512 s> Server: testing stub value\r\n
513 513 s> Date: $HTTP_DATE$\r\n
514 514 s> Content-Type: application/mercurial-exp-framing-0005\r\n
515 515 s> Transfer-Encoding: chunked\r\n
516 516 s> \r\n
517 517 s> 13\r\n
518 518 s> \x0b\x00\x00\x01\x00\x02\x011
519 519 s> \xa1FstatusBok
520 520 s> \r\n
521 521 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
522 522 s> 1ea\r\n
523 523 s> \xe2\x01\x00\x01\x00\x02\x001
524 524 s> \xa1Jtotalitems\x02\xa2DnodeT\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4Lrevisionsize\x19\x01$Y\x01$a\x002b4eb07319bfa077a40a2f04913659aef0da42da\n
525 525 s> b\x00819e258d31a5e1606629f365bb902a1b21ee4216\n
526 526 s> dir0/c\x00914445346a0ca0629bd47ceb5dfe07e4d4cf2501\n
527 527 s> dir0/child0/e\x00bbba6c06b30f443d34ff841bc985c4d0827c6be4\n
528 528 s> dir0/child1/f\x0012fc7dcd773b5a0a929ce195228083c6ddc9cec4\n
529 529 s> dir0/d\x00538206dc971e521540d6843abfe6d16032f6d426\n
530 530 s> \xa3MdeltabasenodeT\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4Ideltasize\x187DnodeTF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0X7\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00+a\x000879345e39377229634b420c639454156726c6b6\n
531 531 s> \r\n
532 532 received frame(size=482; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
533 533 s> 8\r\n
534 534 s> \x00\x00\x00\x01\x00\x02\x002
535 535 s> \r\n
536 536 s> 0\r\n
537 537 s> \r\n
538 538 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
539 539 response: gen[
540 540 {
541 541 b'totalitems': 2
542 542 },
543 543 {
544 544 b'node': b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4',
545 545 b'revisionsize': 292
546 546 },
547 547 b'a\x002b4eb07319bfa077a40a2f04913659aef0da42da\nb\x00819e258d31a5e1606629f365bb902a1b21ee4216\ndir0/c\x00914445346a0ca0629bd47ceb5dfe07e4d4cf2501\ndir0/child0/e\x00bbba6c06b30f443d34ff841bc985c4d0827c6be4\ndir0/child1/f\x0012fc7dcd773b5a0a929ce195228083c6ddc9cec4\ndir0/d\x00538206dc971e521540d6843abfe6d16032f6d426\n',
548 548 {
549 549 b'deltabasenode': b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4',
550 550 b'deltasize': 55,
551 551 b'node': b'F\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0'
552 552 },
553 553 b'\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00+a\x000879345e39377229634b420c639454156726c6b6\n'
554 554 ]
555 555
556 556 Revisions are sorted by DAG order, parents first
557 557
558 558 $ sendhttpv2peer << EOF
559 559 > command manifestdata
560 560 > nodes eval:[b'\x46\xa6\x72\x1b\x5e\xda\xf0\xea\x04\xb7\x9a\x5c\xb3\x21\x88\x54\xa4\xd2\xab\xa0', b'\x1b\x17\x5b\x59\x5f\x02\x2c\xfa\xb5\xb8\x09\xcc\x0e\xd5\x51\xbd\x0b\x3f\xf5\xe4']
561 561 > tree eval:b''
562 562 > fields eval:[b'revision']
563 563 > EOF
564 564 creating http peer for wire protocol version 2
565 565 sending manifestdata command
566 566 s> POST /api/exp-http-v2-0001/ro/manifestdata HTTP/1.1\r\n
567 567 s> Accept-Encoding: identity\r\n
568 568 s> accept: application/mercurial-exp-framing-0005\r\n
569 569 s> content-type: application/mercurial-exp-framing-0005\r\n
570 570 s> content-length: 105\r\n
571 571 s> host: $LOCALIP:$HGPORT\r\n (glob)
572 572 s> user-agent: Mercurial debugwireproto\r\n
573 573 s> \r\n
574 574 s> a\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa3Ffields\x81HrevisionEnodes\x82TF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0T\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4Dtree@DnameLmanifestdata
575 575 s> makefile('rb', None)
576 576 s> HTTP/1.1 200 OK\r\n
577 577 s> Server: testing stub value\r\n
578 578 s> Date: $HTTP_DATE$\r\n
579 579 s> Content-Type: application/mercurial-exp-framing-0005\r\n
580 580 s> Transfer-Encoding: chunked\r\n
581 581 s> \r\n
582 582 s> 13\r\n
583 583 s> \x0b\x00\x00\x01\x00\x02\x011
584 584 s> \xa1FstatusBok
585 585 s> \r\n
586 586 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
587 587 s> 1ea\r\n
588 588 s> \xe2\x01\x00\x01\x00\x02\x001
589 589 s> \xa1Jtotalitems\x02\xa2DnodeT\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4Lrevisionsize\x19\x01$Y\x01$a\x002b4eb07319bfa077a40a2f04913659aef0da42da\n
590 590 s> b\x00819e258d31a5e1606629f365bb902a1b21ee4216\n
591 591 s> dir0/c\x00914445346a0ca0629bd47ceb5dfe07e4d4cf2501\n
592 592 s> dir0/child0/e\x00bbba6c06b30f443d34ff841bc985c4d0827c6be4\n
593 593 s> dir0/child1/f\x0012fc7dcd773b5a0a929ce195228083c6ddc9cec4\n
594 594 s> dir0/d\x00538206dc971e521540d6843abfe6d16032f6d426\n
595 595 s> \xa3MdeltabasenodeT\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4Ideltasize\x187DnodeTF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0X7\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00+a\x000879345e39377229634b420c639454156726c6b6\n
596 596 s> \r\n
597 597 received frame(size=482; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
598 598 s> 8\r\n
599 599 s> \x00\x00\x00\x01\x00\x02\x002
600 600 s> \r\n
601 601 s> 0\r\n
602 602 s> \r\n
603 603 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
604 604 response: gen[
605 605 {
606 606 b'totalitems': 2
607 607 },
608 608 {
609 609 b'node': b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4',
610 610 b'revisionsize': 292
611 611 },
612 612 b'a\x002b4eb07319bfa077a40a2f04913659aef0da42da\nb\x00819e258d31a5e1606629f365bb902a1b21ee4216\ndir0/c\x00914445346a0ca0629bd47ceb5dfe07e4d4cf2501\ndir0/child0/e\x00bbba6c06b30f443d34ff841bc985c4d0827c6be4\ndir0/child1/f\x0012fc7dcd773b5a0a929ce195228083c6ddc9cec4\ndir0/d\x00538206dc971e521540d6843abfe6d16032f6d426\n',
613 613 {
614 614 b'deltabasenode': b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4',
615 615 b'deltasize': 55,
616 616 b'node': b'F\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0'
617 617 },
618 618 b'\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00+a\x000879345e39377229634b420c639454156726c6b6\n'
619 619 ]
620 620
621 621 Requesting parents and revision data works
622 622
623 623 $ sendhttpv2peer << EOF
624 624 > command manifestdata
625 625 > nodes eval:[b'\x1b\x17\x5b\x59\x5f\x02\x2c\xfa\xb5\xb8\x09\xcc\x0e\xd5\x51\xbd\x0b\x3f\xf5\xe4', b'\x46\xa6\x72\x1b\x5e\xda\xf0\xea\x04\xb7\x9a\x5c\xb3\x21\x88\x54\xa4\xd2\xab\xa0']
626 626 > tree eval:b''
627 627 > fields eval:[b'parents', b'revision']
628 628 > EOF
629 629 creating http peer for wire protocol version 2
630 630 sending manifestdata command
631 631 s> POST /api/exp-http-v2-0001/ro/manifestdata HTTP/1.1\r\n
632 632 s> Accept-Encoding: identity\r\n
633 633 s> accept: application/mercurial-exp-framing-0005\r\n
634 634 s> content-type: application/mercurial-exp-framing-0005\r\n
635 635 s> content-length: 113\r\n
636 636 s> host: $LOCALIP:$HGPORT\r\n (glob)
637 637 s> user-agent: Mercurial debugwireproto\r\n
638 638 s> \r\n
639 639 s> i\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa3Ffields\x82GparentsHrevisionEnodes\x82T\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4TF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0Dtree@DnameLmanifestdata
640 640 s> makefile('rb', None)
641 641 s> HTTP/1.1 200 OK\r\n
642 642 s> Server: testing stub value\r\n
643 643 s> Date: $HTTP_DATE$\r\n
644 644 s> Content-Type: application/mercurial-exp-framing-0005\r\n
645 645 s> Transfer-Encoding: chunked\r\n
646 646 s> \r\n
647 647 s> 13\r\n
648 648 s> \x0b\x00\x00\x01\x00\x02\x011
649 649 s> \xa1FstatusBok
650 650 s> \r\n
651 651 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
652 652 s> 250\r\n
653 653 s> H\x02\x00\x01\x00\x02\x001
654 654 s> \xa1Jtotalitems\x02\xa3DnodeT\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4Gparents\x82T\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00T\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Lrevisionsize\x19\x01$Y\x01$a\x002b4eb07319bfa077a40a2f04913659aef0da42da\n
655 655 s> b\x00819e258d31a5e1606629f365bb902a1b21ee4216\n
656 656 s> dir0/c\x00914445346a0ca0629bd47ceb5dfe07e4d4cf2501\n
657 657 s> dir0/child0/e\x00bbba6c06b30f443d34ff841bc985c4d0827c6be4\n
658 658 s> dir0/child1/f\x0012fc7dcd773b5a0a929ce195228083c6ddc9cec4\n
659 659 s> dir0/d\x00538206dc971e521540d6843abfe6d16032f6d426\n
660 660 s> \xa4MdeltabasenodeT\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4Ideltasize\x187DnodeTF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0Gparents\x82T\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4T\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00X7\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00+a\x000879345e39377229634b420c639454156726c6b6\n
661 661 s> \r\n
662 662 received frame(size=584; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
663 663 s> 8\r\n
664 664 s> \x00\x00\x00\x01\x00\x02\x002
665 665 s> \r\n
666 666 s> 0\r\n
667 667 s> \r\n
668 668 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
669 669 response: gen[
670 670 {
671 671 b'totalitems': 2
672 672 },
673 673 {
674 674 b'node': b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4',
675 675 b'parents': [
676 676 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
677 677 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
678 678 ],
679 679 b'revisionsize': 292
680 680 },
681 681 b'a\x002b4eb07319bfa077a40a2f04913659aef0da42da\nb\x00819e258d31a5e1606629f365bb902a1b21ee4216\ndir0/c\x00914445346a0ca0629bd47ceb5dfe07e4d4cf2501\ndir0/child0/e\x00bbba6c06b30f443d34ff841bc985c4d0827c6be4\ndir0/child1/f\x0012fc7dcd773b5a0a929ce195228083c6ddc9cec4\ndir0/d\x00538206dc971e521540d6843abfe6d16032f6d426\n',
682 682 {
683 683 b'deltabasenode': b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4',
684 684 b'deltasize': 55,
685 685 b'node': b'F\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0',
686 686 b'parents': [
687 687 b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4',
688 688 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
689 689 ]
690 690 },
691 691 b'\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00+a\x000879345e39377229634b420c639454156726c6b6\n'
692 692 ]
693 693
694 694 $ cat error.log
General Comments 0
You need to be logged in to leave comments. Login now