Show More
@@ -311,6 +311,10 b' def _httpv2runcommand(ui, repo, req, res' | |||||
311 | action, meta = reactor.oncommandresponsereadyobjects( |
|
311 | action, meta = reactor.oncommandresponsereadyobjects( | |
312 | outstream, command['requestid'], objs) |
|
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 | except Exception as e: |
|
318 | except Exception as e: | |
315 | action, meta = reactor.onservererror( |
|
319 | action, meta = reactor.onservererror( | |
316 | outstream, command['requestid'], |
|
320 | outstream, command['requestid'], | |
@@ -348,13 +352,39 b' class httpv2protocolhandler(object):' | |||||
348 | return HTTP_WIREPROTO_V2 |
|
352 | return HTTP_WIREPROTO_V2 | |
349 |
|
353 | |||
350 | def getargs(self, args): |
|
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 | data = {} |
|
372 | data = {} | |
352 |
for k, |
|
373 | for k, meta in sorted(args.items()): | |
353 | if k == '*': |
|
374 | # This argument wasn't passed by the client. | |
354 | raise NotImplementedError('do not support * args') |
|
375 | if k not in self._args: | |
355 | elif k in self._args: |
|
376 | data[k] = meta['default']() | |
356 |
|
|
377 | continue | |
357 | data[k] = self._args[k] |
|
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 | return data |
|
389 | return data | |
360 |
|
390 | |||
@@ -404,8 +434,10 b' def _capabilitiesv2(repo, proto):' | |||||
404 | # TODO expose available changesetdata fields. |
|
434 | # TODO expose available changesetdata fields. | |
405 |
|
435 | |||
406 | for command, entry in COMMANDS.items(): |
|
436 | for command, entry in COMMANDS.items(): | |
|
437 | args = {arg: meta['example'] for arg, meta in entry.args.items()} | |||
|
438 | ||||
407 | caps['commands'][command] = { |
|
439 | caps['commands'][command] = { | |
408 |
'args': |
|
440 | 'args': args, | |
409 | 'permissions': [entry.permission], |
|
441 | 'permissions': [entry.permission], | |
410 | } |
|
442 | } | |
411 |
|
443 | |||
@@ -500,7 +532,23 b' def wireprotocommand(name, args=None, pe' | |||||
500 |
|
532 | |||
501 | ``name`` is the name of the wire protocol command being provided. |
|
533 | ``name`` is the name of the wire protocol command being provided. | |
502 |
|
534 | |||
503 |
``args`` is a dict |
|
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 | ``permission`` defines the permission type needed to run this command. |
|
553 | ``permission`` defines the permission type needed to run this command. | |
506 | Can be ``push`` or ``pull``. These roughly map to read-write and read-only, |
|
554 | Can be ``push`` or ``pull``. These roughly map to read-write and read-only, | |
@@ -529,6 +577,36 b' def wireprotocommand(name, args=None, pe' | |||||
529 | raise error.ProgrammingError('arguments for version 2 commands ' |
|
577 | raise error.ProgrammingError('arguments for version 2 commands ' | |
530 | 'must be declared as dicts') |
|
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 | def register(func): |
|
610 | def register(func): | |
533 | if name in COMMANDS: |
|
611 | if name in COMMANDS: | |
534 | raise error.ProgrammingError('%s command already registered ' |
|
612 | raise error.ProgrammingError('%s command already registered ' | |
@@ -550,16 +628,25 b' def branchmapv2(repo, proto):' | |||||
550 | def capabilitiesv2(repo, proto): |
|
628 | def capabilitiesv2(repo, proto): | |
551 | yield _capabilitiesv2(repo, proto) |
|
629 | yield _capabilitiesv2(repo, proto) | |
552 |
|
630 | |||
553 |
@wireprotocommand( |
|
631 | @wireprotocommand( | |
554 | args={ |
|
632 | 'changesetdata', | |
555 | 'noderange': [[b'0123456...'], [b'abcdef...']], |
|
633 | args={ | |
556 | 'nodes': [b'0123456...'], |
|
634 | 'noderange': { | |
557 | 'fields': {b'parents', b'revision'}, |
|
635 | 'type': 'list', | |
558 | }, |
|
636 | 'example': [[b'0123456...'], [b'abcdef...']], | |
559 | permission='pull') |
|
637 | }, | |
560 | def changesetdata(repo, proto, noderange=None, nodes=None, fields=None): |
|
638 | 'nodes': { | |
561 | fields = fields or set() |
|
639 | 'type': 'list', | |
562 |
|
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 | # TODO look for unknown fields and abort when they can't be serviced. |
|
650 | # TODO look for unknown fields and abort when they can't be serviced. | |
564 |
|
651 | |||
565 | if noderange is None and nodes is None: |
|
652 | if noderange is None and nodes is None: | |
@@ -691,24 +778,32 b' def getfilestore(repo, proto, path):' | |||||
691 |
|
778 | |||
692 | return fl |
|
779 | return fl | |
693 |
|
780 | |||
694 |
@wireprotocommand( |
|
781 | @wireprotocommand( | |
695 | args={ |
|
782 | 'filedata', | |
696 | 'haveparents': True, |
|
783 | args={ | |
697 | 'nodes': [b'0123456...'], |
|
784 | 'haveparents': { | |
698 | 'fields': [b'parents', b'revision'], |
|
785 | 'type': 'bool', | |
699 | 'path': b'foo.txt', |
|
786 | 'default': lambda: False, | |
700 | }, |
|
787 | 'example': True, | |
701 | permission='pull') |
|
788 | }, | |
702 | def filedata(repo, proto, haveparents=False, nodes=None, fields=None, |
|
789 | 'nodes': { | |
703 | path=None): |
|
790 | 'type': 'list', | |
704 | fields = fields or set() |
|
791 | 'required': True, | |
705 |
|
792 | 'example': [b'0123456...'], | ||
706 | if nodes is None: |
|
793 | }, | |
707 | raise error.WireprotoCommandError('nodes argument must be defined') |
|
794 | 'fields': { | |
708 |
|
795 | 'type': 'set', | ||
709 | if path is None: |
|
796 | 'default': set, | |
710 | raise error.WireprotoCommandError('path argument must be defined') |
|
797 | 'example': {b'parents', b'revision'}, | |
711 |
|
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 | try: |
|
807 | try: | |
713 | # Extensions may wish to access the protocol handler. |
|
808 | # Extensions may wish to access the protocol handler. | |
714 | store = getfilestore(repo, proto, path) |
|
809 | store = getfilestore(repo, proto, path) | |
@@ -776,44 +871,63 b' def filedata(repo, proto, haveparents=Fa' | |||||
776 | except GeneratorExit: |
|
871 | except GeneratorExit: | |
777 | pass |
|
872 | pass | |
778 |
|
873 | |||
779 |
@wireprotocommand( |
|
874 | @wireprotocommand( | |
780 | args={ |
|
875 | 'heads', | |
781 | 'publiconly': False, |
|
876 | args={ | |
782 | }, |
|
877 | 'publiconly': { | |
783 | permission='pull') |
|
878 | 'type': 'bool', | |
784 | def headsv2(repo, proto, publiconly=False): |
|
879 | 'default': lambda: False, | |
|
880 | 'example': False, | |||
|
881 | }, | |||
|
882 | }, | |||
|
883 | permission='pull') | |||
|
884 | def headsv2(repo, proto, publiconly): | |||
785 | if publiconly: |
|
885 | if publiconly: | |
786 | repo = repo.filtered('immutable') |
|
886 | repo = repo.filtered('immutable') | |
787 |
|
887 | |||
788 | yield repo.heads() |
|
888 | yield repo.heads() | |
789 |
|
889 | |||
790 |
@wireprotocommand( |
|
890 | @wireprotocommand( | |
791 | args={ |
|
891 | 'known', | |
792 | 'nodes': [b'deadbeef'], |
|
892 | args={ | |
793 | }, |
|
893 | 'nodes': { | |
794 | permission='pull') |
|
894 | 'type': 'list', | |
795 | def knownv2(repo, proto, nodes=None): |
|
895 | 'default': list, | |
796 | nodes = nodes or [] |
|
896 | 'example': [b'deadbeef'], | |
|
897 | }, | |||
|
898 | }, | |||
|
899 | permission='pull') | |||
|
900 | def knownv2(repo, proto, nodes): | |||
797 | result = b''.join(b'1' if n else b'0' for n in repo.known(nodes)) |
|
901 | result = b''.join(b'1' if n else b'0' for n in repo.known(nodes)) | |
798 | yield result |
|
902 | yield result | |
799 |
|
903 | |||
800 |
@wireprotocommand( |
|
904 | @wireprotocommand( | |
801 | args={ |
|
905 | 'listkeys', | |
802 | 'namespace': b'ns', |
|
906 | args={ | |
803 | }, |
|
907 | 'namespace': { | |
804 | permission='pull') |
|
908 | 'type': 'bytes', | |
805 | def listkeysv2(repo, proto, namespace=None): |
|
909 | 'required': True, | |
|
910 | 'example': b'ns', | |||
|
911 | }, | |||
|
912 | }, | |||
|
913 | permission='pull') | |||
|
914 | def listkeysv2(repo, proto, namespace): | |||
806 | keys = repo.listkeys(encoding.tolocal(namespace)) |
|
915 | keys = repo.listkeys(encoding.tolocal(namespace)) | |
807 | keys = {encoding.fromlocal(k): encoding.fromlocal(v) |
|
916 | keys = {encoding.fromlocal(k): encoding.fromlocal(v) | |
808 | for k, v in keys.iteritems()} |
|
917 | for k, v in keys.iteritems()} | |
809 |
|
918 | |||
810 | yield keys |
|
919 | yield keys | |
811 |
|
920 | |||
812 |
@wireprotocommand( |
|
921 | @wireprotocommand( | |
813 | args={ |
|
922 | 'lookup', | |
814 | 'key': b'foo', |
|
923 | args={ | |
815 | }, |
|
924 | 'key': { | |
816 | permission='pull') |
|
925 | 'type': 'bytes', | |
|
926 | 'required': True, | |||
|
927 | 'example': b'foo', | |||
|
928 | }, | |||
|
929 | }, | |||
|
930 | permission='pull') | |||
817 | def lookupv2(repo, proto, key): |
|
931 | def lookupv2(repo, proto, key): | |
818 | key = encoding.tolocal(key) |
|
932 | key = encoding.tolocal(key) | |
819 |
|
933 | |||
@@ -822,26 +936,32 b' def lookupv2(repo, proto, key):' | |||||
822 |
|
936 | |||
823 | yield node |
|
937 | yield node | |
824 |
|
938 | |||
825 |
@wireprotocommand( |
|
939 | @wireprotocommand( | |
826 | args={ |
|
940 | 'manifestdata', | |
827 | 'nodes': [b'0123456...'], |
|
941 | args={ | |
828 | 'haveparents': True, |
|
942 | 'nodes': { | |
829 | 'fields': [b'parents', b'revision'], |
|
943 | 'type': 'list', | |
830 |
|
|
944 | 'required': True, | |
831 | }, |
|
945 | 'example': [b'0123456...'], | |
832 | permission='pull') |
|
946 | }, | |
833 | def manifestdata(repo, proto, haveparents=False, nodes=None, fields=None, |
|
947 | 'haveparents': { | |
834 | tree=None): |
|
948 | 'type': 'bool', | |
835 | fields = fields or set() |
|
949 | 'default': lambda: False, | |
836 |
|
950 | 'example': True, | ||
837 | if nodes is None: |
|
951 | }, | |
838 | raise error.WireprotoCommandError( |
|
952 | 'fields': { | |
839 | 'nodes argument must be defined') |
|
953 | 'type': 'set', | |
840 |
|
954 | 'default': set, | ||
841 | if tree is None: |
|
955 | 'example': {b'parents', b'revision'}, | |
842 | raise error.WireprotoCommandError( |
|
956 | }, | |
843 | 'tree argument must be defined') |
|
957 | 'tree': { | |
844 |
|
958 | 'type': 'bytes', | ||
|
959 | 'required': True, | |||
|
960 | 'example': b'', | |||
|
961 | }, | |||
|
962 | }, | |||
|
963 | permission='pull') | |||
|
964 | def manifestdata(repo, proto, haveparents, nodes, fields, tree): | |||
845 | store = repo.manifestlog.getstorage(tree) |
|
965 | store = repo.manifestlog.getstorage(tree) | |
846 |
|
966 | |||
847 | # Validate the node is known and abort on unknown revisions. |
|
967 | # Validate the node is known and abort on unknown revisions. | |
@@ -905,14 +1025,31 b' def manifestdata(repo, proto, haveparent' | |||||
905 | except GeneratorExit: |
|
1025 | except GeneratorExit: | |
906 | pass |
|
1026 | pass | |
907 |
|
1027 | |||
908 |
@wireprotocommand( |
|
1028 | @wireprotocommand( | |
909 | args={ |
|
1029 | 'pushkey', | |
910 | 'namespace': b'ns', |
|
1030 | args={ | |
911 | 'key': b'key', |
|
1031 | 'namespace': { | |
912 | 'old': b'old', |
|
1032 | 'type': 'bytes', | |
913 | 'new': b'new', |
|
1033 | 'required': True, | |
914 | }, |
|
1034 | 'example': b'ns', | |
915 | permission='push') |
|
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 | def pushkeyv2(repo, proto, namespace, key, old, new): |
|
1053 | def pushkeyv2(repo, proto, namespace, key, old, new): | |
917 | # TODO handle ui output redirection |
|
1054 | # TODO handle ui output redirection | |
918 | yield repo.pushkey(encoding.tolocal(namespace), |
|
1055 | yield repo.pushkey(encoding.tolocal(namespace), |
@@ -313,7 +313,7 b' Client with HTTPv2 enabled automatically' | |||||
313 | s> Content-Type: application/mercurial-cbor\r\n |
|
313 | s> Content-Type: application/mercurial-cbor\r\n | |
314 | s> Content-Length: *\r\n (glob) |
|
314 | s> Content-Length: *\r\n (glob) | |
315 | s> \r\n |
|
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 | sending heads command |
|
317 | sending heads command | |
318 | s> POST /api/exp-http-v2-0001/ro/heads HTTP/1.1\r\n |
|
318 | s> POST /api/exp-http-v2-0001/ro/heads HTTP/1.1\r\n | |
319 | s> Accept-Encoding: identity\r\n |
|
319 | s> Accept-Encoding: identity\r\n |
@@ -212,7 +212,7 b' Request for HTTPv2 service returns infor' | |||||
212 | s> Content-Type: application/mercurial-cbor\r\n |
|
212 | s> Content-Type: application/mercurial-cbor\r\n | |
213 | s> Content-Length: *\r\n (glob) |
|
213 | s> Content-Length: *\r\n (glob) | |
214 | s> \r\n |
|
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 | cbor> { |
|
216 | cbor> { | |
217 | b'apibase': b'api/', |
|
217 | b'apibase': b'api/', | |
218 | b'apis': { |
|
218 | b'apis': { | |
@@ -254,10 +254,10 b' Request for HTTPv2 service returns infor' | |||||
254 | }, |
|
254 | }, | |
255 | b'filedata': { |
|
255 | b'filedata': { | |
256 | b'args': { |
|
256 | b'args': { | |
257 | b'fields': [ |
|
257 | b'fields': set([ | |
258 | b'parents', |
|
258 | b'parents', | |
259 | b'revision' |
|
259 | b'revision' | |
260 | ], |
|
260 | ]), | |
261 | b'haveparents': True, |
|
261 | b'haveparents': True, | |
262 | b'nodes': [ |
|
262 | b'nodes': [ | |
263 | b'0123456...' |
|
263 | b'0123456...' | |
@@ -304,10 +304,10 b' Request for HTTPv2 service returns infor' | |||||
304 | }, |
|
304 | }, | |
305 | b'manifestdata': { |
|
305 | b'manifestdata': { | |
306 | b'args': { |
|
306 | b'args': { | |
307 | b'fields': [ |
|
307 | b'fields': set([ | |
308 | b'parents', |
|
308 | b'parents', | |
309 | b'revision' |
|
309 | b'revision' | |
310 | ], |
|
310 | ]), | |
311 | b'haveparents': True, |
|
311 | b'haveparents': True, | |
312 | b'nodes': [ |
|
312 | b'nodes': [ | |
313 | b'0123456...' |
|
313 | b'0123456...' | |
@@ -369,7 +369,7 b' capabilities command returns expected in' | |||||
369 | s> Content-Type: application/mercurial-cbor\r\n |
|
369 | s> Content-Type: application/mercurial-cbor\r\n | |
370 | s> Content-Length: *\r\n (glob) |
|
370 | s> Content-Length: *\r\n (glob) | |
371 | s> \r\n |
|
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 | sending capabilities command |
|
373 | sending capabilities command | |
374 | s> POST /api/exp-http-v2-0001/ro/capabilities HTTP/1.1\r\n |
|
374 | s> POST /api/exp-http-v2-0001/ro/capabilities HTTP/1.1\r\n | |
375 | s> Accept-Encoding: identity\r\n |
|
375 | s> Accept-Encoding: identity\r\n | |
@@ -392,11 +392,11 b' capabilities command returns expected in' | |||||
392 | s> \xa1FstatusBok |
|
392 | s> \xa1FstatusBok | |
393 | s> \r\n |
|
393 | s> \r\n | |
394 | received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation) |
|
394 | received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation) | |
395 |
s> 3 |
|
395 | s> 314\r\n | |
396 |
s> \x0 |
|
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\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 |
|
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 | s> \r\n |
|
398 | s> \r\n | |
399 |
received frame(size=7 |
|
399 | received frame(size=780; request=1; stream=2; streamflags=; type=command-response; flags=continuation) | |
400 | s> 8\r\n |
|
400 | s> 8\r\n | |
401 | s> \x00\x00\x00\x01\x00\x02\x002 |
|
401 | s> \x00\x00\x00\x01\x00\x02\x002 | |
402 | s> \r\n |
|
402 | s> \r\n | |
@@ -442,10 +442,10 b' capabilities command returns expected in' | |||||
442 | }, |
|
442 | }, | |
443 | b'filedata': { |
|
443 | b'filedata': { | |
444 | b'args': { |
|
444 | b'args': { | |
445 | b'fields': [ |
|
445 | b'fields': set([ | |
446 | b'parents', |
|
446 | b'parents', | |
447 | b'revision' |
|
447 | b'revision' | |
448 | ], |
|
448 | ]), | |
449 | b'haveparents': True, |
|
449 | b'haveparents': True, | |
450 | b'nodes': [ |
|
450 | b'nodes': [ | |
451 | b'0123456...' |
|
451 | b'0123456...' | |
@@ -492,10 +492,10 b' capabilities command returns expected in' | |||||
492 | }, |
|
492 | }, | |
493 | b'manifestdata': { |
|
493 | b'manifestdata': { | |
494 | b'args': { |
|
494 | b'args': { | |
495 | b'fields': [ |
|
495 | b'fields': set([ | |
496 | b'parents', |
|
496 | b'parents', | |
497 | b'revision' |
|
497 | b'revision' | |
498 | ], |
|
498 | ]), | |
499 | b'haveparents': True, |
|
499 | b'haveparents': True, | |
500 | b'nodes': [ |
|
500 | b'nodes': [ | |
501 | b'0123456...' |
|
501 | b'0123456...' |
@@ -69,14 +69,14 b' Missing arguments is an error' | |||||
69 | s> Content-Type: application/mercurial-exp-framing-0005\r\n |
|
69 | s> Content-Type: application/mercurial-exp-framing-0005\r\n | |
70 | s> Transfer-Encoding: chunked\r\n |
|
70 | s> Transfer-Encoding: chunked\r\n | |
71 | s> \r\n |
|
71 | s> \r\n | |
72 |
s> 4 |
|
72 | s> 4e\r\n | |
73 |
s> |
|
73 | s> F\x00\x00\x01\x00\x02\x012 | |
74 |
s> \xa2Eerror\xa1GmessageX\ |
|
74 | s> \xa2Eerror\xa1GmessageX\'missing required arguments: nodes, pathFstatusEerror | |
75 |
|
|
75 | s> \r\n | |
76 |
received frame(size= |
|
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 | [255] |
|
80 | [255] | |
81 |
|
81 | |||
82 | $ sendhttpv2peer << EOF |
|
82 | $ sendhttpv2peer << EOF | |
@@ -101,14 +101,14 b' Missing arguments is an error' | |||||
101 | s> Content-Type: application/mercurial-exp-framing-0005\r\n |
|
101 | s> Content-Type: application/mercurial-exp-framing-0005\r\n | |
102 | s> Transfer-Encoding: chunked\r\n |
|
102 | s> Transfer-Encoding: chunked\r\n | |
103 | s> \r\n |
|
103 | s> \r\n | |
104 |
s> 4 |
|
104 | s> 47\r\n | |
105 |
s> |
|
105 | s> ?\x00\x00\x01\x00\x02\x012 | |
106 |
s> \xa2Eerror\xa1GmessageX |
|
106 | s> \xa2Eerror\xa1GmessageX missing required arguments: pathFstatusEerror | |
107 | s> \r\n |
|
107 | s> \r\n | |
108 |
received frame(size=6 |
|
108 | received frame(size=63; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=eos) | |
109 | s> 0\r\n |
|
109 | s> 0\r\n | |
110 | s> \r\n |
|
110 | s> \r\n | |
111 | abort: path argument must be defined! |
|
111 | abort: missing required arguments: path! | |
112 | [255] |
|
112 | [255] | |
113 |
|
113 | |||
114 | Unknown node is an error |
|
114 | Unknown node is an error |
@@ -65,14 +65,14 b' Missing arguments is an error' | |||||
65 | s> Content-Type: application/mercurial-exp-framing-0005\r\n |
|
65 | s> Content-Type: application/mercurial-exp-framing-0005\r\n | |
66 | s> Transfer-Encoding: chunked\r\n |
|
66 | s> Transfer-Encoding: chunked\r\n | |
67 | s> \r\n |
|
67 | s> \r\n | |
68 |
s> 4 |
|
68 | s> 4e\r\n | |
69 |
s> |
|
69 | s> F\x00\x00\x01\x00\x02\x012 | |
70 |
s> \xa2Eerror\xa1GmessageX\ |
|
70 | s> \xa2Eerror\xa1GmessageX\'missing required arguments: nodes, treeFstatusEerror | |
71 |
|
|
71 | s> \r\n | |
72 |
received frame(size= |
|
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 | [255] |
|
76 | [255] | |
77 |
|
77 | |||
78 | $ sendhttpv2peer << EOF |
|
78 | $ sendhttpv2peer << EOF | |
@@ -97,14 +97,14 b' Missing arguments is an error' | |||||
97 | s> Content-Type: application/mercurial-exp-framing-0005\r\n |
|
97 | s> Content-Type: application/mercurial-exp-framing-0005\r\n | |
98 | s> Transfer-Encoding: chunked\r\n |
|
98 | s> Transfer-Encoding: chunked\r\n | |
99 | s> \r\n |
|
99 | s> \r\n | |
100 |
s> 4 |
|
100 | s> 47\r\n | |
101 |
s> |
|
101 | s> ?\x00\x00\x01\x00\x02\x012 | |
102 |
s> \xa2Eerror\xa1GmessageX |
|
102 | s> \xa2Eerror\xa1GmessageX missing required arguments: treeFstatusEerror | |
103 | s> \r\n |
|
103 | s> \r\n | |
104 |
received frame(size=6 |
|
104 | received frame(size=63; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=eos) | |
105 | s> 0\r\n |
|
105 | s> 0\r\n | |
106 | s> \r\n |
|
106 | s> \r\n | |
107 |
abort: tree |
|
107 | abort: missing required arguments: tree! | |
108 | [255] |
|
108 | [255] | |
109 |
|
109 | |||
110 | Unknown node is an error |
|
110 | Unknown node is an error |
General Comments 0
You need to be logged in to leave comments.
Login now