mercurial/wireproto.py
author Martin von Zweigbergk <martinvonz@google.com>
Fri, 06 Apr 2018 11:26:50 -0700
changeset 37396 9966f44ecab4
parent 37393 afcfdf53e4b5
child 37412 1d459f61b42a
permissions -rw-r--r--
debugwhyunstable: add support for revsets Differential Revision: https://phab.mercurial-scm.org/D3166
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     1
# wireproto.py - generic wire protocol support functions
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     2
#
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     3
# Copyright 2005-2010 Matt Mackall <mpm@selenic.com>
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     4
#
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms of the
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     6
# GNU General Public License version 2 or any later version.
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     7
25993
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
     8
from __future__ import absolute_import
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
     9
29341
0d83ad967bf8 cleanup: replace uses of util.(md5|sha1|sha256|sha512) with hashlib.\1
Augie Fackler <raf@durin42.com>
parents: 29216
diff changeset
    10
import hashlib
25993
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    11
import os
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    12
import tempfile
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    13
25993
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    14
from .i18n import _
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    15
from .node import (
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    16
    bin,
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    17
    hex,
32260
d0d9a4fca59b clone: add a server-side option to disable full getbundles (pull-based clones)
Siddharth Agarwal <sid0@fb.com>
parents: 31451
diff changeset
    18
    nullid,
25993
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    19
)
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    20
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    21
from . import (
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    22
    bundle2,
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    23
    changegroup as changegroupmod,
34097
f7d41b85bbf6 changegroup: replace changegroupsubset with makechangegroup
Durham Goode <durham@fb.com>
parents: 34062
diff changeset
    24
    discovery,
25993
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    25
    encoding,
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    26
    error,
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    27
    exchange,
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    28
    peer,
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    29
    pushkey as pushkeymod,
30924
48dea083f66d py3: convert the mode argument of os.fdopen to unicodes (1 of 2)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30914
diff changeset
    30
    pycompat,
33806
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
    31
    repository,
26443
d947086d8973 streamclone: move code out of exchange.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25993
diff changeset
    32
    streamclone,
25993
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    33
    util,
36073
cd6ab329c5c7 wireprototypes: move wire protocol response types to new module
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36071
diff changeset
    34
    wireprototypes,
25993
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    35
)
20903
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    36
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37053
diff changeset
    37
from .utils import (
37119
d4a2e0d5d042 procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
    38
    procutil,
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37053
diff changeset
    39
    stringutil,
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37053
diff changeset
    40
)
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37053
diff changeset
    41
28883
032c4c2f802a pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents: 28666
diff changeset
    42
urlerr = util.urlerr
032c4c2f802a pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents: 28666
diff changeset
    43
urlreq = util.urlreq
032c4c2f802a pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents: 28666
diff changeset
    44
30909
d554e624c5fe bundle1: fix bundle1-denied reporting for push over ssh
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30762
diff changeset
    45
bundle2requiredmain = _('incompatible Mercurial client; bundle2 required')
d554e624c5fe bundle1: fix bundle1-denied reporting for push over ssh
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30762
diff changeset
    46
bundle2requiredhint = _('see https://www.mercurial-scm.org/wiki/'
d554e624c5fe bundle1: fix bundle1-denied reporting for push over ssh
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30762
diff changeset
    47
                        'IncompatibleClient')
d554e624c5fe bundle1: fix bundle1-denied reporting for push over ssh
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30762
diff changeset
    48
bundle2required = '%s\n(%s)\n' % (bundle2requiredmain, bundle2requiredhint)
27246
b288fb2724bf wireproto: config options to disable bundle1
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27243
diff changeset
    49
28436
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28435
diff changeset
    50
class remoteiterbatcher(peer.iterbatcher):
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28435
diff changeset
    51
    def __init__(self, remote):
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28435
diff changeset
    52
        super(remoteiterbatcher, self).__init__()
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28435
diff changeset
    53
        self._remote = remote
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28435
diff changeset
    54
28438
48fd02dac1d4 wireproto: make iterbatcher behave streamily over http(s)
Augie Fackler <augie@google.com>
parents: 28436
diff changeset
    55
    def __getattr__(self, name):
33764
297d1b70685c wireproto: properly implement batchable checking
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33499
diff changeset
    56
        # Validate this method is batchable, since submit() only supports
297d1b70685c wireproto: properly implement batchable checking
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33499
diff changeset
    57
        # batchable methods.
297d1b70685c wireproto: properly implement batchable checking
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33499
diff changeset
    58
        fn = getattr(self._remote, name)
297d1b70685c wireproto: properly implement batchable checking
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33499
diff changeset
    59
        if not getattr(fn, 'batchable', None):
297d1b70685c wireproto: properly implement batchable checking
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33499
diff changeset
    60
            raise error.ProgrammingError('Attempted to batch a non-batchable '
297d1b70685c wireproto: properly implement batchable checking
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33499
diff changeset
    61
                                         'call to %r' % name)
297d1b70685c wireproto: properly implement batchable checking
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33499
diff changeset
    62
28438
48fd02dac1d4 wireproto: make iterbatcher behave streamily over http(s)
Augie Fackler <augie@google.com>
parents: 28436
diff changeset
    63
        return super(remoteiterbatcher, self).__getattr__(name)
48fd02dac1d4 wireproto: make iterbatcher behave streamily over http(s)
Augie Fackler <augie@google.com>
parents: 28436
diff changeset
    64
28436
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28435
diff changeset
    65
    def submit(self):
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28435
diff changeset
    66
        """Break the batch request into many patch calls and pipeline them.
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28435
diff changeset
    67
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28435
diff changeset
    68
        This is mostly valuable over http where request sizes can be
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28435
diff changeset
    69
        limited, but can be used in other places as well.
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28435
diff changeset
    70
        """
33766
4c706037adef wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33765
diff changeset
    71
        # 2-tuple of (command, arguments) that represents what will be
4c706037adef wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33765
diff changeset
    72
        # sent over the wire.
4c706037adef wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33765
diff changeset
    73
        requests = []
4c706037adef wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33765
diff changeset
    74
4c706037adef wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33765
diff changeset
    75
        # 4-tuple of (command, final future, @batchable generator, remote
4c706037adef wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33765
diff changeset
    76
        # future).
4c706037adef wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33765
diff changeset
    77
        results = []
4c706037adef wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33765
diff changeset
    78
4c706037adef wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33765
diff changeset
    79
        for command, args, opts, finalfuture in self.calls:
4c706037adef wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33765
diff changeset
    80
            mtd = getattr(self._remote, command)
34726
daf12f69699f python3: replace im_{self,func} with __{self,func}__ globally
Augie Fackler <augie@google.com>
parents: 34613
diff changeset
    81
            batchable = mtd.batchable(mtd.__self__, *args, **opts)
33766
4c706037adef wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33765
diff changeset
    82
4c706037adef wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33765
diff changeset
    83
            commandargs, fremote = next(batchable)
4c706037adef wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33765
diff changeset
    84
            assert fremote
4c706037adef wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33765
diff changeset
    85
            requests.append((command, commandargs))
4c706037adef wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33765
diff changeset
    86
            results.append((command, finalfuture, batchable, fremote))
4c706037adef wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33765
diff changeset
    87
4c706037adef wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33765
diff changeset
    88
        if requests:
4c706037adef wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33765
diff changeset
    89
            self._resultiter = self._remote._submitbatch(requests)
4c706037adef wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33765
diff changeset
    90
4c706037adef wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33765
diff changeset
    91
        self._results = results
28436
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28435
diff changeset
    92
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28435
diff changeset
    93
    def results(self):
33766
4c706037adef wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33765
diff changeset
    94
        for command, finalfuture, batchable, remotefuture in self._results:
4c706037adef wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33765
diff changeset
    95
            # Get the raw result, set it in the remote future, feed it
4c706037adef wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33765
diff changeset
    96
            # back into the @batchable generator so it can be decoded, and
4c706037adef wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33765
diff changeset
    97
            # set the result on the final future to this value.
4c706037adef wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33765
diff changeset
    98
            remoteresult = next(self._resultiter)
4c706037adef wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33765
diff changeset
    99
            remotefuture.set(remoteresult)
4c706037adef wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33765
diff changeset
   100
            finalfuture.set(next(batchable))
4c706037adef wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33765
diff changeset
   101
4c706037adef wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33765
diff changeset
   102
            # Verify our @batchable generators only emit 2 values.
4c706037adef wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33765
diff changeset
   103
            try:
4c706037adef wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33765
diff changeset
   104
                next(batchable)
4c706037adef wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33765
diff changeset
   105
            except StopIteration:
4c706037adef wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33765
diff changeset
   106
                pass
4c706037adef wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33765
diff changeset
   107
            else:
4c706037adef wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33765
diff changeset
   108
                raise error.ProgrammingError('%s @batchable generator emitted '
4c706037adef wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33765
diff changeset
   109
                                             'unexpected value count' % command)
4c706037adef wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33765
diff changeset
   110
4c706037adef wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33765
diff changeset
   111
            yield finalfuture.value
28436
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28435
diff changeset
   112
25912
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 25711
diff changeset
   113
# Forward a couple of names from peer to make wireproto interactions
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 25711
diff changeset
   114
# slightly more sensible.
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 25711
diff changeset
   115
batchable = peer.batchable
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 25711
diff changeset
   116
future = peer.future
14621
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
   117
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   118
# list of nodes encoding / decoding
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   119
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   120
def decodelist(l, sep=' '):
13722
f4a85acef50c wireproto: fix decodelist to properly return empty list
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13721
diff changeset
   121
    if l:
34729
6f532c1a4af0 wireproto: use listcomp instead of map()
Augie Fackler <augie@google.com>
parents: 34726
diff changeset
   122
        return [bin(v) for v in  l.split(sep)]
13722
f4a85acef50c wireproto: fix decodelist to properly return empty list
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13721
diff changeset
   123
    return []
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   124
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   125
def encodelist(l, sep=' '):
23848
c5456b64eb07 discovery: run discovery on filtered repository
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23591
diff changeset
   126
    try:
c5456b64eb07 discovery: run discovery on filtered repository
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23591
diff changeset
   127
        return sep.join(map(hex, l))
c5456b64eb07 discovery: run discovery on filtered repository
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23591
diff changeset
   128
    except TypeError:
c5456b64eb07 discovery: run discovery on filtered repository
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23591
diff changeset
   129
        raise
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   130
14622
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   131
# batched call argument encoding
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   132
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   133
def escapearg(plain):
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   134
    return (plain
25708
d3d32643c060 wireproto: correctly escape batched args and responses (issue4739)
Augie Fackler <augie@google.com>
parents: 25691
diff changeset
   135
            .replace(':', ':c')
d3d32643c060 wireproto: correctly escape batched args and responses (issue4739)
Augie Fackler <augie@google.com>
parents: 25691
diff changeset
   136
            .replace(',', ':o')
d3d32643c060 wireproto: correctly escape batched args and responses (issue4739)
Augie Fackler <augie@google.com>
parents: 25691
diff changeset
   137
            .replace(';', ':s')
d3d32643c060 wireproto: correctly escape batched args and responses (issue4739)
Augie Fackler <augie@google.com>
parents: 25691
diff changeset
   138
            .replace('=', ':e'))
14622
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   139
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   140
def unescapearg(escaped):
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   141
    return (escaped
25708
d3d32643c060 wireproto: correctly escape batched args and responses (issue4739)
Augie Fackler <augie@google.com>
parents: 25691
diff changeset
   142
            .replace(':e', '=')
d3d32643c060 wireproto: correctly escape batched args and responses (issue4739)
Augie Fackler <augie@google.com>
parents: 25691
diff changeset
   143
            .replace(':s', ';')
d3d32643c060 wireproto: correctly escape batched args and responses (issue4739)
Augie Fackler <augie@google.com>
parents: 25691
diff changeset
   144
            .replace(':o', ',')
d3d32643c060 wireproto: correctly escape batched args and responses (issue4739)
Augie Fackler <augie@google.com>
parents: 25691
diff changeset
   145
            .replace(':c', ':'))
14622
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   146
29733
bb04f96df51c wireproto: consolidate code for obtaining "cmds" argument value
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29706
diff changeset
   147
def encodebatchcmds(req):
bb04f96df51c wireproto: consolidate code for obtaining "cmds" argument value
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29706
diff changeset
   148
    """Return a ``cmds`` argument value for the ``batch`` command."""
bb04f96df51c wireproto: consolidate code for obtaining "cmds" argument value
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29706
diff changeset
   149
    cmds = []
bb04f96df51c wireproto: consolidate code for obtaining "cmds" argument value
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29706
diff changeset
   150
    for op, argsdict in req:
29734
62e2e048d068 wireproto: unescape argument names in batch command (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29733
diff changeset
   151
        # Old servers didn't properly unescape argument names. So prevent
62e2e048d068 wireproto: unescape argument names in batch command (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29733
diff changeset
   152
        # the sending of argument names that may not be decoded properly by
62e2e048d068 wireproto: unescape argument names in batch command (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29733
diff changeset
   153
        # servers.
62e2e048d068 wireproto: unescape argument names in batch command (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29733
diff changeset
   154
        assert all(escapearg(k) == k for k in argsdict)
62e2e048d068 wireproto: unescape argument names in batch command (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29733
diff changeset
   155
29733
bb04f96df51c wireproto: consolidate code for obtaining "cmds" argument value
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29706
diff changeset
   156
        args = ','.join('%s=%s' % (escapearg(k), escapearg(v))
bb04f96df51c wireproto: consolidate code for obtaining "cmds" argument value
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29706
diff changeset
   157
                        for k, v in argsdict.iteritems())
bb04f96df51c wireproto: consolidate code for obtaining "cmds" argument value
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29706
diff changeset
   158
        cmds.append('%s %s' % (op, args))
bb04f96df51c wireproto: consolidate code for obtaining "cmds" argument value
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29706
diff changeset
   159
bb04f96df51c wireproto: consolidate code for obtaining "cmds" argument value
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29706
diff changeset
   160
    return ';'.join(cmds)
bb04f96df51c wireproto: consolidate code for obtaining "cmds" argument value
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29706
diff changeset
   161
37393
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
   162
def clientcompressionsupport(proto):
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
   163
    """Returns a list of compression methods supported by the client.
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
   164
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
   165
    Returns a list of the compression methods supported by the client
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
   166
    according to the protocol capabilities. If no such capability has
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
   167
    been announced, fallback to the default of zlib and uncompressed.
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
   168
    """
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
   169
    for cap in proto.getprotocaps():
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
   170
        if cap.startswith('comp='):
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
   171
            return cap[5:].split(',')
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
   172
    return ['zlib', 'none']
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
   173
21646
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   174
# mapping of options accepted by getbundle and their types
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   175
#
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   176
# Meant to be extended by extensions. It is extensions responsibility to ensure
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   177
# such options are properly processed in exchange.getbundle.
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   178
#
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   179
# supported types are:
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   180
#
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   181
# :nodes: list of binary nodes
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   182
# :csv:   list of comma-separated values
25403
30ab130af221 wireprotocol: distinguish list and set in getbundle argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25339
diff changeset
   183
# :scsv:  list of comma-separated values return as set
21646
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   184
# :plain: string with no transformation needed.
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   185
gboptsmap = {'heads':  'nodes',
35267
cb4dcd7fabe7 getbundle: add support for 'bookmarks' boolean argument
Boris Feld <boris.feld@octobus.net>
parents: 34741
diff changeset
   186
             'bookmarks': 'boolean',
21646
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   187
             'common': 'nodes',
22353
47e3420ae889 getbundle: add `obsmarkers` argument to getbundle
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22351
diff changeset
   188
             'obsmarkers': 'boolean',
34322
10e162bb9bf5 pull: use 'phase-heads' to retrieve phase information
Boris Feld <boris.feld@octobus.net>
parents: 34100
diff changeset
   189
             'phases': 'boolean',
25403
30ab130af221 wireprotocol: distinguish list and set in getbundle argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25339
diff changeset
   190
             'bundlecaps': 'scsv',
21989
bdb6d97f0a04 getbundle: add a ``cg`` boolean argument to control changegroup inclusion
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21988
diff changeset
   191
             'listkeys': 'csv',
26690
704818fb170d exchange: advertise if a clone bundle was attempted
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26686
diff changeset
   192
             'cg': 'boolean',
35759
c24dad55ac19 bundle2: add support for a 'stream' parameter to 'getbundle'
Boris Feld <boris.feld@octobus.net>
parents: 35750
diff changeset
   193
             'cbattempted': 'boolean',
c24dad55ac19 bundle2: add support for a 'stream' parameter to 'getbundle'
Boris Feld <boris.feld@octobus.net>
parents: 35750
diff changeset
   194
             'stream': 'boolean',
c24dad55ac19 bundle2: add support for a 'stream' parameter to 'getbundle'
Boris Feld <boris.feld@octobus.net>
parents: 35750
diff changeset
   195
}
21646
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   196
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   197
# client side
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   198
33806
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   199
class wirepeer(repository.legacypeer):
27243
3abee2ba27af wireproto: add docstring for wirepeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26911
diff changeset
   200
    """Client-side interface for communicating with a peer repository.
14622
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   201
27243
3abee2ba27af wireproto: add docstring for wirepeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26911
diff changeset
   202
    Methods commonly call wire protocol commands of the same name.
3abee2ba27af wireproto: add docstring for wirepeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26911
diff changeset
   203
3abee2ba27af wireproto: add docstring for wirepeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26911
diff changeset
   204
    See also httppeer.py and sshpeer.py for protocol-specific
3abee2ba27af wireproto: add docstring for wirepeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26911
diff changeset
   205
    implementations of this interface.
3abee2ba27af wireproto: add docstring for wirepeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26911
diff changeset
   206
    """
37320
39f7d4ee8bcd repository: port peer interfaces to zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37295
diff changeset
   207
    # Begin of ipeercommands interface.
14622
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   208
28436
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28435
diff changeset
   209
    def iterbatch(self):
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28435
diff changeset
   210
        return remoteiterbatcher(self)
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28435
diff changeset
   211
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   212
    @batchable
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   213
    def lookup(self, key):
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   214
        self.requirecap('lookup', _('look up remote revision'))
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   215
        f = future()
20671
5442cab57b09 wireproto: remove todict() and use {} literals instead
Augie Fackler <raf@durin42.com>
parents: 19201
diff changeset
   216
        yield {'key': encoding.fromlocal(key)}, f
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   217
        d = f.value
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   218
        success, data = d[:-1].split(" ", 1)
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   219
        if int(success):
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   220
            yield bin(data)
34062
6c6169f71b8d wireproto: do not abort after successful lookup
Kyle Lippincott <spectral@google.com>
parents: 33806
diff changeset
   221
        else:
6c6169f71b8d wireproto: do not abort after successful lookup
Kyle Lippincott <spectral@google.com>
parents: 33806
diff changeset
   222
            self._abort(error.RepoError(data))
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   223
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   224
    @batchable
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   225
    def heads(self):
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   226
        f = future()
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   227
        yield {}, f
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   228
        d = f.value
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   229
        try:
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   230
            yield decodelist(d[:-1])
13726
378522bdc059 wireproto: avoid naked excepts
Matt Mackall <mpm@selenic.com>
parents: 13723
diff changeset
   231
        except ValueError:
11879
4e804302d30c fix undefined variables, spotted by pylint
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11627
diff changeset
   232
            self._abort(error.ResponseError(_("unexpected response:"), d))
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   233
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   234
    @batchable
13723
e615765fdcc7 wireproto: add known([id]) function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13722
diff changeset
   235
    def known(self, nodes):
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   236
        f = future()
20671
5442cab57b09 wireproto: remove todict() and use {} literals instead
Augie Fackler <raf@durin42.com>
parents: 19201
diff changeset
   237
        yield {'nodes': encodelist(nodes)}, f
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   238
        d = f.value
13723
e615765fdcc7 wireproto: add known([id]) function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13722
diff changeset
   239
        try:
22201
269688a398c4 cleanup: fix some list comprehension redefinitions of existing vars
Mads Kiilerich <madski@unity3d.com>
parents: 21989
diff changeset
   240
            yield [bool(int(b)) for b in d]
13726
378522bdc059 wireproto: avoid naked excepts
Matt Mackall <mpm@selenic.com>
parents: 13723
diff changeset
   241
        except ValueError:
13723
e615765fdcc7 wireproto: add known([id]) function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13722
diff changeset
   242
            self._abort(error.ResponseError(_("unexpected response:"), d))
e615765fdcc7 wireproto: add known([id]) function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13722
diff changeset
   243
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   244
    @batchable
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   245
    def branchmap(self):
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   246
        f = future()
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   247
        yield {}, f
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   248
        d = f.value
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   249
        try:
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   250
            branchmap = {}
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   251
            for branchpart in d.splitlines():
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   252
                branchname, branchheads = branchpart.split(' ', 1)
28883
032c4c2f802a pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents: 28666
diff changeset
   253
                branchname = encoding.tolocal(urlreq.unquote(branchname))
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   254
                branchheads = decodelist(branchheads)
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   255
                branchmap[branchname] = branchheads
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   256
            yield branchmap
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   257
        except TypeError:
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   258
            self._abort(error.ResponseError(_("unexpected response:"), d))
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   259
33806
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   260
    @batchable
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   261
    def listkeys(self, namespace):
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   262
        if not self.capable('pushkey'):
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   263
            yield {}, None
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   264
        f = future()
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   265
        self.ui.debug('preparing listkeys for "%s"\n' % namespace)
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   266
        yield {'namespace': encoding.fromlocal(namespace)}, f
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   267
        d = f.value
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   268
        self.ui.debug('received listkey for "%s": %i bytes\n'
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   269
                      % (namespace, len(d)))
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   270
        yield pushkeymod.decodekeys(d)
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   271
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   272
    @batchable
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   273
    def pushkey(self, namespace, key, old, new):
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   274
        if not self.capable('pushkey'):
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   275
            yield False, None
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   276
        f = future()
17293
d3f84ccc5495 pushkey: add more verbose debug output regarding pushkey
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17205
diff changeset
   277
        self.ui.debug('preparing pushkey for "%s:%s"\n' % (namespace, key))
20671
5442cab57b09 wireproto: remove todict() and use {} literals instead
Augie Fackler <raf@durin42.com>
parents: 19201
diff changeset
   278
        yield {'namespace': encoding.fromlocal(namespace),
5442cab57b09 wireproto: remove todict() and use {} literals instead
Augie Fackler <raf@durin42.com>
parents: 19201
diff changeset
   279
               'key': encoding.fromlocal(key),
5442cab57b09 wireproto: remove todict() and use {} literals instead
Augie Fackler <raf@durin42.com>
parents: 19201
diff changeset
   280
               'old': encoding.fromlocal(old),
5442cab57b09 wireproto: remove todict() and use {} literals instead
Augie Fackler <raf@durin42.com>
parents: 19201
diff changeset
   281
               'new': encoding.fromlocal(new)}, f
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   282
        d = f.value
15652
ca6accdad79c wireproto: handle other server output in pushkey
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15585
diff changeset
   283
        d, output = d.split('\n', 1)
13450
b3f9af7c22c5 wireproto: catch possible cast error in pushkey
David Soria Parra <dsp@php.net>
parents: 13050
diff changeset
   284
        try:
b3f9af7c22c5 wireproto: catch possible cast error in pushkey
David Soria Parra <dsp@php.net>
parents: 13050
diff changeset
   285
            d = bool(int(d))
b3f9af7c22c5 wireproto: catch possible cast error in pushkey
David Soria Parra <dsp@php.net>
parents: 13050
diff changeset
   286
        except ValueError:
b3f9af7c22c5 wireproto: catch possible cast error in pushkey
David Soria Parra <dsp@php.net>
parents: 13050
diff changeset
   287
            raise error.ResponseError(
b3f9af7c22c5 wireproto: catch possible cast error in pushkey
David Soria Parra <dsp@php.net>
parents: 13050
diff changeset
   288
                _('push failed (unexpected response):'), d)
15652
ca6accdad79c wireproto: handle other server output in pushkey
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15585
diff changeset
   289
        for l in output.splitlines(True):
ca6accdad79c wireproto: handle other server output in pushkey
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15585
diff changeset
   290
            self.ui.status(_('remote: '), l)
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   291
        yield d
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   292
11588
8a1f625e971d protocol: unify stream_out client code
Matt Mackall <mpm@selenic.com>
parents: 11587
diff changeset
   293
    def stream_out(self):
8a1f625e971d protocol: unify stream_out client code
Matt Mackall <mpm@selenic.com>
parents: 11587
diff changeset
   294
        return self._callstream('stream_out')
8a1f625e971d protocol: unify stream_out client code
Matt Mackall <mpm@selenic.com>
parents: 11587
diff changeset
   295
21646
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   296
    def getbundle(self, source, **kwargs):
34739
b880cc11da5d wireproto: bounce kwargs to/from bytes/str as needed
Augie Fackler <augie@google.com>
parents: 34731
diff changeset
   297
        kwargs = pycompat.byteskwargs(kwargs)
13741
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13726
diff changeset
   298
        self.requirecap('getbundle', _('look up remote changes'))
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13726
diff changeset
   299
        opts = {}
25128
631766d1f57a getbundle: sort bundlecaps before exchanging then over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24797
diff changeset
   300
        bundlecaps = kwargs.get('bundlecaps')
631766d1f57a getbundle: sort bundlecaps before exchanging then over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24797
diff changeset
   301
        if bundlecaps is not None:
631766d1f57a getbundle: sort bundlecaps before exchanging then over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24797
diff changeset
   302
            kwargs['bundlecaps'] = sorted(bundlecaps)
631766d1f57a getbundle: sort bundlecaps before exchanging then over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24797
diff changeset
   303
        else:
631766d1f57a getbundle: sort bundlecaps before exchanging then over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24797
diff changeset
   304
            bundlecaps = () # kwargs could have it to None
21646
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   305
        for key, value in kwargs.iteritems():
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   306
            if value is None:
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   307
                continue
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   308
            keytype = gboptsmap.get(key)
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   309
            if keytype is None:
34730
6be264009841 wireproto: use a proper exception instead of `assert False`
Augie Fackler <augie@google.com>
parents: 34729
diff changeset
   310
                raise error.ProgrammingError(
6be264009841 wireproto: use a proper exception instead of `assert False`
Augie Fackler <augie@google.com>
parents: 34729
diff changeset
   311
                    'Unexpectedly None keytype for key %s' % key)
21646
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   312
            elif keytype == 'nodes':
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   313
                value = encodelist(value)
25403
30ab130af221 wireprotocol: distinguish list and set in getbundle argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25339
diff changeset
   314
            elif keytype in ('csv', 'scsv'):
21646
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   315
                value = ','.join(value)
21988
12cd3827b860 wireproto: add a ``boolean`` type for getbundle parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21728
diff changeset
   316
            elif keytype == 'boolean':
22351
7e6dd496d327 wireprotocol: fix 'boolean' handling
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22342
diff changeset
   317
                value = '%i' % bool(value)
21646
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   318
            elif keytype != 'plain':
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   319
                raise KeyError('unknown getbundle option type %s'
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   320
                               % keytype)
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   321
            opts[key] = value
34739
b880cc11da5d wireproto: bounce kwargs to/from bytes/str as needed
Augie Fackler <augie@google.com>
parents: 34731
diff changeset
   322
        f = self._callcompressable("getbundle", **pycompat.strkwargs(opts))
25149
3f0744eeaeaf cleanup: use __builtins__.any instead of util.any
Augie Fackler <augie@google.com>
parents: 25128
diff changeset
   323
        if any((cap.startswith('HG2') for cap in bundlecaps)):
24641
60fecc5b14a4 unbundle20: retrieve unbundler instances through a factory function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23878
diff changeset
   324
            return bundle2.getunbundler(self.ui, f)
21069
0a9cae236738 bundle2: allow bundle2 for pulling over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21064
diff changeset
   325
        else:
22390
e2806b8613ca changegroup: rename bundle-related functions and classes
Sune Foldager <cryo@cyanite.org>
parents: 22353
diff changeset
   326
            return changegroupmod.cg1unpacker(f, 'UN')
13741
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13726
diff changeset
   327
29706
7f6130c7ffe1 wirepeer: rename confusing `source` parameter
Augie Fackler <augie@google.com>
parents: 29590
diff changeset
   328
    def unbundle(self, cg, heads, url):
11592
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
   329
        '''Send cg (a readable file-like object representing the
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
   330
        changegroup to push, typically a chunkbuffer object) to the
21075
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   331
        remote server as a bundle.
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   332
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   333
        When pushing a bundle10 stream, return an integer indicating the
32880
4c2a46f89f08 wireproto: update reference to deleted addchangegroup()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32744
diff changeset
   334
        result of the push (see changegroup.apply()).
21075
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   335
29706
7f6130c7ffe1 wirepeer: rename confusing `source` parameter
Augie Fackler <augie@google.com>
parents: 29590
diff changeset
   336
        When pushing a bundle20 stream, return a bundle20 stream.
7f6130c7ffe1 wirepeer: rename confusing `source` parameter
Augie Fackler <augie@google.com>
parents: 29590
diff changeset
   337
7f6130c7ffe1 wirepeer: rename confusing `source` parameter
Augie Fackler <augie@google.com>
parents: 29590
diff changeset
   338
        `url` is the url the client thinks it's pushing to, which is
7f6130c7ffe1 wirepeer: rename confusing `source` parameter
Augie Fackler <augie@google.com>
parents: 29590
diff changeset
   339
        visible to hooks.
7f6130c7ffe1 wirepeer: rename confusing `source` parameter
Augie Fackler <augie@google.com>
parents: 29590
diff changeset
   340
        '''
11592
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
   341
14419
ede7cea1550f wireproto: do not hash when heads == ['force']
Martin Geisler <mg@aragost.com>
parents: 14093
diff changeset
   342
        if heads != ['force'] and self.capable('unbundlehash'):
13942
88f0e41d8802 wireproto: allow unbundle with hashed heads parameter (issue2126)
Shuhei Takahashi <takahashi.shuhei@gmail.com>
parents: 13741
diff changeset
   343
            heads = encodelist(['hashed',
29341
0d83ad967bf8 cleanup: replace uses of util.(md5|sha1|sha256|sha512) with hashlib.\1
Augie Fackler <raf@durin42.com>
parents: 29216
diff changeset
   344
                                hashlib.sha1(''.join(sorted(heads))).digest()])
13942
88f0e41d8802 wireproto: allow unbundle with hashed heads parameter (issue2126)
Shuhei Takahashi <takahashi.shuhei@gmail.com>
parents: 13741
diff changeset
   345
        else:
88f0e41d8802 wireproto: allow unbundle with hashed heads parameter (issue2126)
Shuhei Takahashi <takahashi.shuhei@gmail.com>
parents: 13741
diff changeset
   346
            heads = encodelist(heads)
88f0e41d8802 wireproto: allow unbundle with hashed heads parameter (issue2126)
Shuhei Takahashi <takahashi.shuhei@gmail.com>
parents: 13741
diff changeset
   347
21075
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   348
        if util.safehasattr(cg, 'deltaheader'):
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   349
            # this a bundle10, do the old style call sequence
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   350
            ret, output = self._callpush("unbundle", cg, heads=heads)
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   351
            if ret == "":
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   352
                raise error.ResponseError(
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   353
                    _('push failed:'), output)
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   354
            try:
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   355
                ret = int(ret)
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   356
            except ValueError:
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   357
                raise error.ResponseError(
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   358
                    _('push failed (unexpected response):'), ret)
11592
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
   359
21075
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   360
            for l in output.splitlines(True):
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   361
                self.ui.status(_('remote: '), l)
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   362
        else:
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   363
            # bundle2 push. Send a stream, fetch a stream.
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   364
            stream = self._calltwowaystream('unbundle', cg, heads=heads)
24641
60fecc5b14a4 unbundle20: retrieve unbundler instances through a factory function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23878
diff changeset
   365
            ret = bundle2.getunbundler(self.ui, stream)
11592
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
   366
        return ret
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
   367
37320
39f7d4ee8bcd repository: port peer interfaces to zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37295
diff changeset
   368
    # End of ipeercommands interface.
33806
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   369
37320
39f7d4ee8bcd repository: port peer interfaces to zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37295
diff changeset
   370
    # Begin of ipeerlegacycommands interface.
33806
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   371
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   372
    def branches(self, nodes):
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   373
        n = encodelist(nodes)
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   374
        d = self._call("branches", nodes=n)
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   375
        try:
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   376
            br = [tuple(decodelist(b)) for b in d.splitlines()]
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   377
            return br
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   378
        except ValueError:
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   379
            self._abort(error.ResponseError(_("unexpected response:"), d))
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   380
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   381
    def between(self, pairs):
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   382
        batch = 8 # avoid giant requests
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   383
        r = []
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   384
        for i in xrange(0, len(pairs), batch):
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   385
            n = " ".join([encodelist(p, '-') for p in pairs[i:i + batch]])
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   386
            d = self._call("between", pairs=n)
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   387
            try:
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   388
                r.extend(l and decodelist(l) or [] for l in d.splitlines())
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   389
            except ValueError:
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   390
                self._abort(error.ResponseError(_("unexpected response:"), d))
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   391
        return r
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   392
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   393
    def changegroup(self, nodes, kind):
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   394
        n = encodelist(nodes)
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   395
        f = self._callcompressable("changegroup", roots=n)
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   396
        return changegroupmod.cg1unpacker(f, 'UN')
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   397
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   398
    def changegroupsubset(self, bases, heads, kind):
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   399
        self.requirecap('changegroupsubset', _('look up remote changes'))
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   400
        bases = encodelist(bases)
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   401
        heads = encodelist(heads)
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   402
        f = self._callcompressable("changegroupsubset",
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   403
                                   bases=bases, heads=heads)
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   404
        return changegroupmod.cg1unpacker(f, 'UN')
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   405
37320
39f7d4ee8bcd repository: port peer interfaces to zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37295
diff changeset
   406
    # End of ipeerlegacycommands interface.
33806
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   407
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   408
    def _submitbatch(self, req):
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   409
        """run batch request <req> on the server
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   410
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   411
        Returns an iterator of the raw responses from the server.
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   412
        """
36945
4901d1e22b27 peer-request: include more details about batch commands
Boris Feld <boris.feld@octobus.net>
parents: 36840
diff changeset
   413
        ui = self.ui
4901d1e22b27 peer-request: include more details about batch commands
Boris Feld <boris.feld@octobus.net>
parents: 36840
diff changeset
   414
        if ui.debugflag and ui.configbool('devel', 'debug.peer-request'):
4901d1e22b27 peer-request: include more details about batch commands
Boris Feld <boris.feld@octobus.net>
parents: 36840
diff changeset
   415
            ui.debug('devel-peer-request: batched-content\n')
4901d1e22b27 peer-request: include more details about batch commands
Boris Feld <boris.feld@octobus.net>
parents: 36840
diff changeset
   416
            for op, args in req:
4901d1e22b27 peer-request: include more details about batch commands
Boris Feld <boris.feld@octobus.net>
parents: 36840
diff changeset
   417
                msg = 'devel-peer-request:    - %s (%d arguments)\n'
4901d1e22b27 peer-request: include more details about batch commands
Boris Feld <boris.feld@octobus.net>
parents: 36840
diff changeset
   418
                ui.debug(msg % (op, len(args)))
4901d1e22b27 peer-request: include more details about batch commands
Boris Feld <boris.feld@octobus.net>
parents: 36840
diff changeset
   419
33806
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   420
        rsp = self._callstream("batch", cmds=encodebatchcmds(req))
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   421
        chunk = rsp.read(1024)
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   422
        work = [chunk]
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   423
        while chunk:
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   424
            while ';' not in chunk and chunk:
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   425
                chunk = rsp.read(1024)
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   426
                work.append(chunk)
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   427
            merged = ''.join(work)
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   428
            while ';' in merged:
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   429
                one, merged = merged.split(';', 1)
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   430
                yield unescapearg(one)
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   431
            chunk = rsp.read(1024)
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   432
            work = [merged, chunk]
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   433
        yield unescapearg(''.join(work))
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   434
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   435
    def _submitone(self, op, args):
34739
b880cc11da5d wireproto: bounce kwargs to/from bytes/str as needed
Augie Fackler <augie@google.com>
parents: 34731
diff changeset
   436
        return self._call(op, **pycompat.strkwargs(args))
33806
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   437
14048
58e58406ed19 wireproto: add test for new optional arg missing on server
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13942
diff changeset
   438
    def debugwireargs(self, one, two, three=None, four=None, five=None):
13720
9c4e04fe267e debug: add debugwireargs to test argument passing over the wire
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13450
diff changeset
   439
        # don't pass optional arguments left at their default value
9c4e04fe267e debug: add debugwireargs to test argument passing over the wire
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13450
diff changeset
   440
        opts = {}
9c4e04fe267e debug: add debugwireargs to test argument passing over the wire
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13450
diff changeset
   441
        if three is not None:
35374
7d2292416046 py3: handle keyword arguments correctly in wireproto.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35267
diff changeset
   442
            opts[r'three'] = three
13720
9c4e04fe267e debug: add debugwireargs to test argument passing over the wire
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13450
diff changeset
   443
        if four is not None:
35374
7d2292416046 py3: handle keyword arguments correctly in wireproto.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35267
diff changeset
   444
            opts[r'four'] = four
13720
9c4e04fe267e debug: add debugwireargs to test argument passing over the wire
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13450
diff changeset
   445
        return self._call('debugwireargs', one=one, two=two, **opts)
9c4e04fe267e debug: add debugwireargs to test argument passing over the wire
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13450
diff changeset
   446
20904
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   447
    def _call(self, cmd, **args):
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   448
        """execute <cmd> on the server
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   449
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   450
        The command is expected to return a simple string.
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   451
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   452
        returns the server reply as a string."""
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   453
        raise NotImplementedError()
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   454
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   455
    def _callstream(self, cmd, **args):
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   456
        """execute <cmd> on the server
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   457
28435
176736afa886 wireproto: document quirk of _callstream between http and ssh
Augie Fackler <augie@google.com>
parents: 27633
diff changeset
   458
        The command is expected to return a stream. Note that if the
176736afa886 wireproto: document quirk of _callstream between http and ssh
Augie Fackler <augie@google.com>
parents: 27633
diff changeset
   459
        command doesn't return a stream, _callstream behaves
176736afa886 wireproto: document quirk of _callstream between http and ssh
Augie Fackler <augie@google.com>
parents: 27633
diff changeset
   460
        differently for ssh and http peers.
20904
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   461
28435
176736afa886 wireproto: document quirk of _callstream between http and ssh
Augie Fackler <augie@google.com>
parents: 27633
diff changeset
   462
        returns the server reply as a file like object.
176736afa886 wireproto: document quirk of _callstream between http and ssh
Augie Fackler <augie@google.com>
parents: 27633
diff changeset
   463
        """
20904
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   464
        raise NotImplementedError()
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   465
20905
167047ba3cfa wireproto: drop the _decompress method in favor a new call type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20904
diff changeset
   466
    def _callcompressable(self, cmd, **args):
167047ba3cfa wireproto: drop the _decompress method in favor a new call type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20904
diff changeset
   467
        """execute <cmd> on the server
167047ba3cfa wireproto: drop the _decompress method in favor a new call type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20904
diff changeset
   468
167047ba3cfa wireproto: drop the _decompress method in favor a new call type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20904
diff changeset
   469
        The command is expected to return a stream.
167047ba3cfa wireproto: drop the _decompress method in favor a new call type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20904
diff changeset
   470
21024
7731a2281cf0 spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents: 20969
diff changeset
   471
        The stream may have been compressed in some implementations. This
20905
167047ba3cfa wireproto: drop the _decompress method in favor a new call type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20904
diff changeset
   472
        function takes care of the decompression. This is the only difference
167047ba3cfa wireproto: drop the _decompress method in favor a new call type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20904
diff changeset
   473
        with _callstream.
167047ba3cfa wireproto: drop the _decompress method in favor a new call type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20904
diff changeset
   474
167047ba3cfa wireproto: drop the _decompress method in favor a new call type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20904
diff changeset
   475
        returns the server reply as a file like object.
167047ba3cfa wireproto: drop the _decompress method in favor a new call type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20904
diff changeset
   476
        """
167047ba3cfa wireproto: drop the _decompress method in favor a new call type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20904
diff changeset
   477
        raise NotImplementedError()
167047ba3cfa wireproto: drop the _decompress method in favor a new call type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20904
diff changeset
   478
20904
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   479
    def _callpush(self, cmd, fp, **args):
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   480
        """execute a <cmd> on server
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   481
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   482
        The command is expected to be related to a push. Push has a special
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   483
        return method.
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   484
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   485
        returns the server reply as a (ret, output) tuple. ret is either
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   486
        empty (error) or a stringified int.
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   487
        """
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   488
        raise NotImplementedError()
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   489
21072
0879352d67d8 wireproto: add a _calltwowaystream method on wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21069
diff changeset
   490
    def _calltwowaystream(self, cmd, fp, **args):
0879352d67d8 wireproto: add a _calltwowaystream method on wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21069
diff changeset
   491
        """execute <cmd> on server
0879352d67d8 wireproto: add a _calltwowaystream method on wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21069
diff changeset
   492
0879352d67d8 wireproto: add a _calltwowaystream method on wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21069
diff changeset
   493
        The command will send a stream to the server and get a stream in reply.
0879352d67d8 wireproto: add a _calltwowaystream method on wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21069
diff changeset
   494
        """
0879352d67d8 wireproto: add a _calltwowaystream method on wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21069
diff changeset
   495
        raise NotImplementedError()
0879352d67d8 wireproto: add a _calltwowaystream method on wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21069
diff changeset
   496
20904
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   497
    def _abort(self, exception):
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   498
        """clearly abort the wire protocol connection and raise the exception
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   499
        """
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   500
        raise NotImplementedError()
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   501
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   502
# server side
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   503
20902
1e4fda2f5cf1 wireproto: document possible return type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20775
diff changeset
   504
# wire protocol command can either return a string or one of these classes.
15017
f4522df38c65 wireproto: add out-of-band error class to allow remote repo to report errors
Andrew Pritchard <andrewp@fogcreek.com>
parents: 14970
diff changeset
   505
29590
84c1a5942f1d wireproto: extract repo filtering to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29341
diff changeset
   506
def getdispatchrepo(repo, proto, command):
84c1a5942f1d wireproto: extract repo filtering to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29341
diff changeset
   507
    """Obtain the repo used for processing wire protocol commands.
84c1a5942f1d wireproto: extract repo filtering to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29341
diff changeset
   508
84c1a5942f1d wireproto: extract repo filtering to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29341
diff changeset
   509
    The intent of this function is to serve as a monkeypatch point for
84c1a5942f1d wireproto: extract repo filtering to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29341
diff changeset
   510
    extensions that need commands to operate on different repo views under
84c1a5942f1d wireproto: extract repo filtering to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29341
diff changeset
   511
    specialized circumstances.
84c1a5942f1d wireproto: extract repo filtering to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29341
diff changeset
   512
    """
84c1a5942f1d wireproto: extract repo filtering to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29341
diff changeset
   513
    return repo.filtered('served')
84c1a5942f1d wireproto: extract repo filtering to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29341
diff changeset
   514
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   515
def dispatch(repo, proto, command):
29590
84c1a5942f1d wireproto: extract repo filtering to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29341
diff changeset
   516
    repo = getdispatchrepo(repo, proto, command)
37295
45b39c69fae0 wireproto: separate commands tables for version 1 and 2 commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37293
diff changeset
   517
45b39c69fae0 wireproto: separate commands tables for version 1 and 2 commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37293
diff changeset
   518
    transportversion = wireprototypes.TRANSPORTS[proto.name]['version']
45b39c69fae0 wireproto: separate commands tables for version 1 and 2 commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37293
diff changeset
   519
    commandtable = commandsv2 if transportversion == 2 else commands
45b39c69fae0 wireproto: separate commands tables for version 1 and 2 commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37293
diff changeset
   520
    func, spec = commandtable[command]
45b39c69fae0 wireproto: separate commands tables for version 1 and 2 commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37293
diff changeset
   521
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   522
    args = proto.getargs(spec)
11625
cdeb861335d5 protocol: wrap non-string protocol responses in classes
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11623
diff changeset
   523
    return func(repo, proto, *args)
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   524
13721
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
   525
def options(cmd, keys, others):
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
   526
    opts = {}
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
   527
    for k in keys:
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
   528
        if k in others:
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
   529
            opts[k] = others[k]
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
   530
            del others[k]
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
   531
    if others:
37119
d4a2e0d5d042 procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
   532
        procutil.stderr.write("warning: %s ignored unexpected arguments %s\n"
d4a2e0d5d042 procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
   533
                              % (cmd, ",".join(others)))
13721
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
   534
    return opts
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
   535
27633
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   536
def bundle1allowed(repo, action):
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   537
    """Whether a bundle1 operation is allowed from the server.
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   538
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   539
    Priority is:
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   540
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   541
    1. server.bundle1gd.<action> (if generaldelta active)
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   542
    2. server.bundle1.<action>
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   543
    3. server.bundle1gd (if generaldelta active)
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   544
    4. server.bundle1
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   545
    """
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   546
    ui = repo.ui
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   547
    gd = 'generaldelta' in repo.requirements
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   548
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   549
    if gd:
34613
5e61cd5fb0fc configitems: register the 'server.bundle*' family of config
Boris Feld <boris.feld@octobus.net>
parents: 34322
diff changeset
   550
        v = ui.configbool('server', 'bundle1gd.%s' % action)
27633
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   551
        if v is not None:
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   552
            return v
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   553
34613
5e61cd5fb0fc configitems: register the 'server.bundle*' family of config
Boris Feld <boris.feld@octobus.net>
parents: 34322
diff changeset
   554
    v = ui.configbool('server', 'bundle1.%s' % action)
27246
b288fb2724bf wireproto: config options to disable bundle1
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27243
diff changeset
   555
    if v is not None:
b288fb2724bf wireproto: config options to disable bundle1
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27243
diff changeset
   556
        return v
b288fb2724bf wireproto: config options to disable bundle1
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27243
diff changeset
   557
27633
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   558
    if gd:
33220
40861b2254a5 configitems: register the 'server.bundle1gd' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33219
diff changeset
   559
        v = ui.configbool('server', 'bundle1gd')
27633
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   560
        if v is not None:
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   561
            return v
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   562
33219
ffb1d0f541f5 configitems: register the 'server.bundle1' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32880
diff changeset
   563
    return ui.configbool('server', 'bundle1')
27246
b288fb2724bf wireproto: config options to disable bundle1
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27243
diff changeset
   564
36071
038bcb759b75 wireproto: remove unused proto argument from supportedcompengines (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36070
diff changeset
   565
def supportedcompengines(ui, role):
30762
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   566
    """Obtain the list of supported compression engines for a request."""
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   567
    assert role in (util.CLIENTROLE, util.SERVERROLE)
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   568
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   569
    compengines = util.compengines.supportedwireengines(role)
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   570
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   571
    # Allow config to override default list and ordering.
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   572
    if role == util.SERVERROLE:
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   573
        configengines = ui.configlist('server', 'compressionengines')
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   574
        config = 'server.compressionengines'
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   575
    else:
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   576
        # This is currently implemented mainly to facilitate testing. In most
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   577
        # cases, the server should be in charge of choosing a compression engine
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   578
        # because a server has the most to lose from a sub-optimal choice. (e.g.
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   579
        # CPU DoS due to an expensive engine or a network DoS due to poor
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   580
        # compression ratio).
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   581
        configengines = ui.configlist('experimental',
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   582
                                      'clientcompressionengines')
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   583
        config = 'experimental.clientcompressionengines'
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   584
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   585
    # No explicit config. Filter out the ones that aren't supposed to be
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   586
    # advertised and return default ordering.
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   587
    if not configengines:
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   588
        attr = 'serverpriority' if role == util.SERVERROLE else 'clientpriority'
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   589
        return [e for e in compengines
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   590
                if getattr(e.wireprotosupport(), attr) > 0]
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   591
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   592
    # If compression engines are listed in the config, assume there is a good
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   593
    # reason for it (like server operators wanting to achieve specific
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   594
    # performance characteristics). So fail fast if the config references
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   595
    # unusable compression engines.
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   596
    validnames = set(e.name() for e in compengines)
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   597
    invalidnames = set(e for e in configengines if e not in validnames)
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   598
    if invalidnames:
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   599
        raise error.Abort(_('invalid compression engine defined in %s: %s') %
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   600
                          (config, ', '.join(sorted(invalidnames))))
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   601
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   602
    compengines = [e for e in compengines if e.name() in configengines]
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   603
    compengines = sorted(compengines,
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   604
                         key=lambda e: configengines.index(e.name()))
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   605
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   606
    if not compengines:
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   607
        raise error.Abort(_('%s config option does not specify any known '
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   608
                            'compression engines') % config,
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   609
                          hint=_('usable compression engines: %s') %
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   610
                          ', '.sorted(validnames))
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   611
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   612
    return compengines
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   613
35981
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   614
class commandentry(object):
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   615
    """Represents a declared wire protocol command."""
36800
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   616
    def __init__(self, func, args='', transports=None,
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   617
                 permission='push'):
35981
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   618
        self.func = func
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   619
        self.args = args
36609
abc3b9801563 wireproto: allow wire protocol commands to declare transport support
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36535
diff changeset
   620
        self.transports = transports or set()
36800
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   621
        self.permission = permission
35981
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   622
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   623
    def _merge(self, func, args):
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   624
        """Merge this instance with an incoming 2-tuple.
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   625
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   626
        This is called when a caller using the old 2-tuple API attempts
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   627
        to replace an instance. The incoming values are merged with
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   628
        data not captured by the 2-tuple and a new instance containing
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   629
        the union of the two objects is returned.
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   630
        """
36800
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   631
        return commandentry(func, args=args, transports=set(self.transports),
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   632
                            permission=self.permission)
35981
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   633
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   634
    # Old code treats instances as 2-tuples. So expose that interface.
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   635
    def __iter__(self):
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   636
        yield self.func
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   637
        yield self.args
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   638
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   639
    def __getitem__(self, i):
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   640
        if i == 0:
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   641
            return self.func
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   642
        elif i == 1:
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   643
            return self.args
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   644
        else:
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   645
            raise IndexError('can only access elements 0 and 1')
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   646
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   647
class commanddict(dict):
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   648
    """Container for registered wire protocol commands.
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   649
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   650
    It behaves like a dict. But __setitem__ is overwritten to allow silent
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   651
    coercion of values from 2-tuples for API compatibility.
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   652
    """
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   653
    def __setitem__(self, k, v):
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   654
        if isinstance(v, commandentry):
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   655
            pass
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   656
        # Cast 2-tuples to commandentry instances.
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   657
        elif isinstance(v, tuple):
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   658
            if len(v) != 2:
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   659
                raise ValueError('command tuples must have exactly 2 elements')
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   660
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   661
            # It is common for extensions to wrap wire protocol commands via
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   662
            # e.g. ``wireproto.commands[x] = (newfn, args)``. Because callers
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   663
            # doing this aren't aware of the new API that uses objects to store
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   664
            # command entries, we automatically merge old state with new.
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   665
            if k in self:
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   666
                v = self[k]._merge(v[0], v[1])
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   667
            else:
36609
abc3b9801563 wireproto: allow wire protocol commands to declare transport support
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36535
diff changeset
   668
                # Use default values from @wireprotocommand.
abc3b9801563 wireproto: allow wire protocol commands to declare transport support
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36535
diff changeset
   669
                v = commandentry(v[0], args=v[1],
36800
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   670
                                 transports=set(wireprototypes.TRANSPORTS),
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   671
                                 permission='push')
35981
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   672
        else:
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   673
            raise ValueError('command entries must be commandentry instances '
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   674
                             'or 2-tuples')
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   675
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   676
        return super(commanddict, self).__setitem__(k, v)
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   677
35982
5a56bf4180ad wireproto: function for testing if wire protocol command is available
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35981
diff changeset
   678
    def commandavailable(self, command, proto):
5a56bf4180ad wireproto: function for testing if wire protocol command is available
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35981
diff changeset
   679
        """Determine if a command is available for the requested protocol."""
36609
abc3b9801563 wireproto: allow wire protocol commands to declare transport support
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36535
diff changeset
   680
        assert proto.name in wireprototypes.TRANSPORTS
abc3b9801563 wireproto: allow wire protocol commands to declare transport support
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36535
diff changeset
   681
abc3b9801563 wireproto: allow wire protocol commands to declare transport support
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36535
diff changeset
   682
        entry = self.get(command)
abc3b9801563 wireproto: allow wire protocol commands to declare transport support
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36535
diff changeset
   683
abc3b9801563 wireproto: allow wire protocol commands to declare transport support
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36535
diff changeset
   684
        if not entry:
abc3b9801563 wireproto: allow wire protocol commands to declare transport support
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36535
diff changeset
   685
            return False
abc3b9801563 wireproto: allow wire protocol commands to declare transport support
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36535
diff changeset
   686
abc3b9801563 wireproto: allow wire protocol commands to declare transport support
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36535
diff changeset
   687
        if proto.name not in entry.transports:
abc3b9801563 wireproto: allow wire protocol commands to declare transport support
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36535
diff changeset
   688
            return False
abc3b9801563 wireproto: allow wire protocol commands to declare transport support
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36535
diff changeset
   689
abc3b9801563 wireproto: allow wire protocol commands to declare transport support
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36535
diff changeset
   690
        return True
abc3b9801563 wireproto: allow wire protocol commands to declare transport support
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36535
diff changeset
   691
abc3b9801563 wireproto: allow wire protocol commands to declare transport support
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36535
diff changeset
   692
# Constants specifying which transports a wire protocol command should be
abc3b9801563 wireproto: allow wire protocol commands to declare transport support
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36535
diff changeset
   693
# available on. For use with @wireprotocommand.
abc3b9801563 wireproto: allow wire protocol commands to declare transport support
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36535
diff changeset
   694
POLICY_ALL = 'all'
abc3b9801563 wireproto: allow wire protocol commands to declare transport support
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36535
diff changeset
   695
POLICY_V1_ONLY = 'v1-only'
abc3b9801563 wireproto: allow wire protocol commands to declare transport support
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36535
diff changeset
   696
POLICY_V2_ONLY = 'v2-only'
35982
5a56bf4180ad wireproto: function for testing if wire protocol command is available
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35981
diff changeset
   697
37295
45b39c69fae0 wireproto: separate commands tables for version 1 and 2 commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37293
diff changeset
   698
# For version 1 transports.
35981
ef683a0fd21f wireproto: define and use types for wire protocol commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35980
diff changeset
   699
commands = commanddict()
20906
7a634b34fc91 wireproto: add decorator for wire protocol command
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20905
diff changeset
   700
37295
45b39c69fae0 wireproto: separate commands tables for version 1 and 2 commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37293
diff changeset
   701
# For version 2 transports.
45b39c69fae0 wireproto: separate commands tables for version 1 and 2 commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37293
diff changeset
   702
commandsv2 = commanddict()
45b39c69fae0 wireproto: separate commands tables for version 1 and 2 commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37293
diff changeset
   703
36800
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   704
def wireprotocommand(name, args='', transportpolicy=POLICY_ALL,
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   705
                     permission='push'):
35980
b4976912a6ef wireproto: improve docstring for @wireprotocommand
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35979
diff changeset
   706
    """Decorator to declare a wire protocol command.
b4976912a6ef wireproto: improve docstring for @wireprotocommand
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35979
diff changeset
   707
b4976912a6ef wireproto: improve docstring for @wireprotocommand
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35979
diff changeset
   708
    ``name`` is the name of the wire protocol command being provided.
b4976912a6ef wireproto: improve docstring for @wireprotocommand
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35979
diff changeset
   709
b4976912a6ef wireproto: improve docstring for @wireprotocommand
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35979
diff changeset
   710
    ``args`` is a space-delimited list of named arguments that the command
b4976912a6ef wireproto: improve docstring for @wireprotocommand
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35979
diff changeset
   711
    accepts. ``*`` is a special value that says to accept all arguments.
36609
abc3b9801563 wireproto: allow wire protocol commands to declare transport support
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36535
diff changeset
   712
abc3b9801563 wireproto: allow wire protocol commands to declare transport support
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36535
diff changeset
   713
    ``transportpolicy`` is a POLICY_* constant denoting which transports
abc3b9801563 wireproto: allow wire protocol commands to declare transport support
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36535
diff changeset
   714
    this wire protocol command should be exposed to. By default, commands
abc3b9801563 wireproto: allow wire protocol commands to declare transport support
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36535
diff changeset
   715
    are exposed to all wire protocol transports.
36800
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   716
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   717
    ``permission`` defines the permission type needed to run this command.
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   718
    Can be ``push`` or ``pull``. These roughly map to read-write and read-only,
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   719
    respectively. Default is to assume command requires ``push`` permissions
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   720
    because otherwise commands not declaring their permissions could modify
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   721
    a repository that is supposed to be read-only.
35980
b4976912a6ef wireproto: improve docstring for @wireprotocommand
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35979
diff changeset
   722
    """
36609
abc3b9801563 wireproto: allow wire protocol commands to declare transport support
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36535
diff changeset
   723
    if transportpolicy == POLICY_ALL:
abc3b9801563 wireproto: allow wire protocol commands to declare transport support
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36535
diff changeset
   724
        transports = set(wireprototypes.TRANSPORTS)
37295
45b39c69fae0 wireproto: separate commands tables for version 1 and 2 commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37293
diff changeset
   725
        transportversions = {1, 2}
36609
abc3b9801563 wireproto: allow wire protocol commands to declare transport support
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36535
diff changeset
   726
    elif transportpolicy == POLICY_V1_ONLY:
abc3b9801563 wireproto: allow wire protocol commands to declare transport support
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36535
diff changeset
   727
        transports = {k for k, v in wireprototypes.TRANSPORTS.items()
abc3b9801563 wireproto: allow wire protocol commands to declare transport support
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36535
diff changeset
   728
                      if v['version'] == 1}
37295
45b39c69fae0 wireproto: separate commands tables for version 1 and 2 commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37293
diff changeset
   729
        transportversions = {1}
36609
abc3b9801563 wireproto: allow wire protocol commands to declare transport support
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36535
diff changeset
   730
    elif transportpolicy == POLICY_V2_ONLY:
abc3b9801563 wireproto: allow wire protocol commands to declare transport support
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36535
diff changeset
   731
        transports = {k for k, v in wireprototypes.TRANSPORTS.items()
abc3b9801563 wireproto: allow wire protocol commands to declare transport support
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36535
diff changeset
   732
                      if v['version'] == 2}
37295
45b39c69fae0 wireproto: separate commands tables for version 1 and 2 commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37293
diff changeset
   733
        transportversions = {2}
36609
abc3b9801563 wireproto: allow wire protocol commands to declare transport support
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36535
diff changeset
   734
    else:
36840
ef68493d652b wireproto: raise ProgrammingError instead of Abort
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36835
diff changeset
   735
        raise error.ProgrammingError('invalid transport policy value: %s' %
ef68493d652b wireproto: raise ProgrammingError instead of Abort
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36835
diff changeset
   736
                                     transportpolicy)
36609
abc3b9801563 wireproto: allow wire protocol commands to declare transport support
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36535
diff changeset
   737
37053
cd0ca979a8b8 wireproto: nominally don't expose "batch" to version 2 wire transports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36991
diff changeset
   738
    # Because SSHv2 is a mirror of SSHv1, we allow "batch" commands through to
cd0ca979a8b8 wireproto: nominally don't expose "batch" to version 2 wire transports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36991
diff changeset
   739
    # SSHv2.
cd0ca979a8b8 wireproto: nominally don't expose "batch" to version 2 wire transports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36991
diff changeset
   740
    # TODO undo this hack when SSH is using the unified frame protocol.
cd0ca979a8b8 wireproto: nominally don't expose "batch" to version 2 wire transports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36991
diff changeset
   741
    if name == b'batch':
cd0ca979a8b8 wireproto: nominally don't expose "batch" to version 2 wire transports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36991
diff changeset
   742
        transports.add(wireprototypes.SSHV2)
cd0ca979a8b8 wireproto: nominally don't expose "batch" to version 2 wire transports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36991
diff changeset
   743
36800
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   744
    if permission not in ('push', 'pull'):
36840
ef68493d652b wireproto: raise ProgrammingError instead of Abort
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36835
diff changeset
   745
        raise error.ProgrammingError('invalid wire protocol permission; '
ef68493d652b wireproto: raise ProgrammingError instead of Abort
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36835
diff changeset
   746
                                     'got %s; expected "push" or "pull"' %
ef68493d652b wireproto: raise ProgrammingError instead of Abort
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36835
diff changeset
   747
                                     permission)
36800
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   748
20906
7a634b34fc91 wireproto: add decorator for wire protocol command
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20905
diff changeset
   749
    def register(func):
37295
45b39c69fae0 wireproto: separate commands tables for version 1 and 2 commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37293
diff changeset
   750
        if 1 in transportversions:
45b39c69fae0 wireproto: separate commands tables for version 1 and 2 commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37293
diff changeset
   751
            if name in commands:
45b39c69fae0 wireproto: separate commands tables for version 1 and 2 commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37293
diff changeset
   752
                raise error.ProgrammingError('%s command already registered '
45b39c69fae0 wireproto: separate commands tables for version 1 and 2 commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37293
diff changeset
   753
                                             'for version 1' % name)
45b39c69fae0 wireproto: separate commands tables for version 1 and 2 commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37293
diff changeset
   754
            commands[name] = commandentry(func, args=args,
45b39c69fae0 wireproto: separate commands tables for version 1 and 2 commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37293
diff changeset
   755
                                          transports=transports,
45b39c69fae0 wireproto: separate commands tables for version 1 and 2 commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37293
diff changeset
   756
                                          permission=permission)
45b39c69fae0 wireproto: separate commands tables for version 1 and 2 commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37293
diff changeset
   757
        if 2 in transportversions:
45b39c69fae0 wireproto: separate commands tables for version 1 and 2 commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37293
diff changeset
   758
            if name in commandsv2:
45b39c69fae0 wireproto: separate commands tables for version 1 and 2 commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37293
diff changeset
   759
                raise error.ProgrammingError('%s command already registered '
45b39c69fae0 wireproto: separate commands tables for version 1 and 2 commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37293
diff changeset
   760
                                             'for version 2' % name)
45b39c69fae0 wireproto: separate commands tables for version 1 and 2 commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37293
diff changeset
   761
            commandsv2[name] = commandentry(func, args=args,
45b39c69fae0 wireproto: separate commands tables for version 1 and 2 commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37293
diff changeset
   762
                                            transports=transports,
45b39c69fae0 wireproto: separate commands tables for version 1 and 2 commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37293
diff changeset
   763
                                            permission=permission)
45b39c69fae0 wireproto: separate commands tables for version 1 and 2 commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37293
diff changeset
   764
20906
7a634b34fc91 wireproto: add decorator for wire protocol command
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20905
diff changeset
   765
        return func
7a634b34fc91 wireproto: add decorator for wire protocol command
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20905
diff changeset
   766
    return register
7a634b34fc91 wireproto: add decorator for wire protocol command
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20905
diff changeset
   767
36755
ff4bc0ab6740 wireproto: check permissions when executing "batch" command (BC) (SEC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36754
diff changeset
   768
# TODO define a more appropriate permissions type to use for this.
37053
cd0ca979a8b8 wireproto: nominally don't expose "batch" to version 2 wire transports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36991
diff changeset
   769
@wireprotocommand('batch', 'cmds *', permission='pull',
cd0ca979a8b8 wireproto: nominally don't expose "batch" to version 2 wire transports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36991
diff changeset
   770
                  transportpolicy=POLICY_V1_ONLY)
14622
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   771
def batch(repo, proto, cmds, others):
18382
f3b21beb9802 filtering: rename filters to their antonyms
Kevin Bullock <kbullock@ringworld.org>
parents: 18381
diff changeset
   772
    repo = repo.filtered("served")
14622
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   773
    res = []
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   774
    for pair in cmds.split(';'):
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   775
        op, args = pair.split(' ', 1)
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   776
        vals = {}
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   777
        for a in args.split(','):
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   778
            if a:
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   779
                n, v = a.split('=')
29734
62e2e048d068 wireproto: unescape argument names in batch command (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29733
diff changeset
   780
                vals[unescapearg(n)] = unescapearg(v)
14622
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   781
        func, spec = commands[op]
36755
ff4bc0ab6740 wireproto: check permissions when executing "batch" command (BC) (SEC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36754
diff changeset
   782
36801
66de4555cefd wireproto: formalize permissions checking as part of protocol interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36800
diff changeset
   783
        # Validate that client has permissions to perform this command.
66de4555cefd wireproto: formalize permissions checking as part of protocol interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36800
diff changeset
   784
        perm = commands[op].permission
66de4555cefd wireproto: formalize permissions checking as part of protocol interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36800
diff changeset
   785
        assert perm in ('push', 'pull')
66de4555cefd wireproto: formalize permissions checking as part of protocol interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36800
diff changeset
   786
        proto.checkperm(perm)
36755
ff4bc0ab6740 wireproto: check permissions when executing "batch" command (BC) (SEC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36754
diff changeset
   787
14622
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   788
        if spec:
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   789
            keys = spec.split()
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   790
            data = {}
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   791
            for k in keys:
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   792
                if k == '*':
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   793
                    star = {}
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   794
                    for key in vals.keys():
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   795
                        if key not in keys:
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   796
                            star[key] = vals[key]
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   797
                    data['*'] = star
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   798
                else:
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   799
                    data[k] = vals[k]
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   800
            result = func(repo, proto, *[data[k] for k in keys])
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   801
        else:
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   802
            result = func(repo, proto)
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   803
        if isinstance(result, wireprototypes.ooberror):
15017
f4522df38c65 wireproto: add out-of-band error class to allow remote repo to report errors
Andrew Pritchard <andrewp@fogcreek.com>
parents: 14970
diff changeset
   804
            return result
36074
2f7290555c96 wireproto: introduce type for raw byte responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36073
diff changeset
   805
2f7290555c96 wireproto: introduce type for raw byte responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36073
diff changeset
   806
        # For now, all batchable commands must return bytesresponse or
2f7290555c96 wireproto: introduce type for raw byte responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36073
diff changeset
   807
        # raw bytes (for backwards compatibility).
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   808
        assert isinstance(result, (wireprototypes.bytesresponse, bytes))
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   809
        if isinstance(result, wireprototypes.bytesresponse):
36074
2f7290555c96 wireproto: introduce type for raw byte responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36073
diff changeset
   810
            result = result.data
14622
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   811
        res.append(escapearg(result))
36074
2f7290555c96 wireproto: introduce type for raw byte responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36073
diff changeset
   812
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   813
    return wireprototypes.bytesresponse(';'.join(res))
14622
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   814
36800
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   815
@wireprotocommand('between', 'pairs', transportpolicy=POLICY_V1_ONLY,
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   816
                  permission='pull')
11583
944c23762c3c protocol: add proto to method prototypes
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
   817
def between(repo, proto, pairs):
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   818
    pairs = [decodelist(p, '-') for p in pairs.split(" ")]
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   819
    r = []
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   820
    for b in repo.between(pairs):
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   821
        r.append(encodelist(b) + "\n")
36074
2f7290555c96 wireproto: introduce type for raw byte responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36073
diff changeset
   822
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   823
    return wireprototypes.bytesresponse(''.join(r))
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   824
36800
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   825
@wireprotocommand('branchmap', permission='pull')
11583
944c23762c3c protocol: add proto to method prototypes
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
   826
def branchmap(repo, proto):
18281
898c575833c9 clfilter: drop extra filtering in wireprotocol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18280
diff changeset
   827
    branchmap = repo.branchmap()
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   828
    heads = []
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   829
    for branch, nodes in branchmap.iteritems():
28883
032c4c2f802a pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents: 28666
diff changeset
   830
        branchname = urlreq.quote(encoding.fromlocal(branch))
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   831
        branchnodes = encodelist(nodes)
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   832
        heads.append('%s %s' % (branchname, branchnodes))
36074
2f7290555c96 wireproto: introduce type for raw byte responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36073
diff changeset
   833
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   834
    return wireprototypes.bytesresponse('\n'.join(heads))
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   835
36800
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   836
@wireprotocommand('branches', 'nodes', transportpolicy=POLICY_V1_ONLY,
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   837
                  permission='pull')
11583
944c23762c3c protocol: add proto to method prototypes
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
   838
def branches(repo, proto, nodes):
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   839
    nodes = decodelist(nodes)
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   840
    r = []
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   841
    for b in repo.branches(nodes):
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   842
        r.append(encodelist(b) + "\n")
36074
2f7290555c96 wireproto: introduce type for raw byte responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36073
diff changeset
   843
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   844
    return wireprototypes.bytesresponse(''.join(r))
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   845
36800
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   846
@wireprotocommand('clonebundles', '', permission='pull')
26857
e5a1df51bb25 wireproto: move clonebundles command from extension (issue4931)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26690
diff changeset
   847
def clonebundles(repo, proto):
e5a1df51bb25 wireproto: move clonebundles command from extension (issue4931)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26690
diff changeset
   848
    """Server command for returning info for available bundles to seed clones.
e5a1df51bb25 wireproto: move clonebundles command from extension (issue4931)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26690
diff changeset
   849
e5a1df51bb25 wireproto: move clonebundles command from extension (issue4931)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26690
diff changeset
   850
    Clients will parse this response and determine what bundle to fetch.
e5a1df51bb25 wireproto: move clonebundles command from extension (issue4931)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26690
diff changeset
   851
e5a1df51bb25 wireproto: move clonebundles command from extension (issue4931)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26690
diff changeset
   852
    Extensions may wrap this command to filter or dynamically emit data
e5a1df51bb25 wireproto: move clonebundles command from extension (issue4931)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26690
diff changeset
   853
    depending on the request. e.g. you could advertise URLs for the closest
e5a1df51bb25 wireproto: move clonebundles command from extension (issue4931)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26690
diff changeset
   854
    data center given the client's IP address.
e5a1df51bb25 wireproto: move clonebundles command from extension (issue4931)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26690
diff changeset
   855
    """
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   856
    return wireprototypes.bytesresponse(
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   857
        repo.vfs.tryread('clonebundles.manifest'))
20774
cdc3ac896997 wireproto: extract capabilities list in outside the wireproto function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20671
diff changeset
   858
36612
e89959970a08 wireproto: don't expose changegroupsubset capability if not available
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36611
diff changeset
   859
wireprotocaps = ['lookup', 'branchmap', 'pushkey',
37053
cd0ca979a8b8 wireproto: nominally don't expose "batch" to version 2 wire transports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36991
diff changeset
   860
                 'known', 'getbundle', 'unbundlehash']
20775
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   861
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   862
def _capabilities(repo, proto):
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   863
    """return a list of capabilities for a repo
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   864
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   865
    This function exists to allow extensions to easily wrap capabilities
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   866
    computation
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   867
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   868
    - returns a lists: easy to alter
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   869
    - change done here will be propagated to both `capabilities` and `hello`
21024
7731a2281cf0 spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents: 20969
diff changeset
   870
      command without any other action needed.
20775
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   871
    """
20774
cdc3ac896997 wireproto: extract capabilities list in outside the wireproto function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20671
diff changeset
   872
    # copy to prevent modification of the global list
cdc3ac896997 wireproto: extract capabilities list in outside the wireproto function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20671
diff changeset
   873
    caps = list(wireprotocaps)
36612
e89959970a08 wireproto: don't expose changegroupsubset capability if not available
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36611
diff changeset
   874
e89959970a08 wireproto: don't expose changegroupsubset capability if not available
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36611
diff changeset
   875
    # Command of same name as capability isn't exposed to version 1 of
e89959970a08 wireproto: don't expose changegroupsubset capability if not available
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36611
diff changeset
   876
    # transports. So conditionally add it.
e89959970a08 wireproto: don't expose changegroupsubset capability if not available
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36611
diff changeset
   877
    if commands.commandavailable('changegroupsubset', proto):
e89959970a08 wireproto: don't expose changegroupsubset capability if not available
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36611
diff changeset
   878
        caps.append('changegroupsubset')
e89959970a08 wireproto: don't expose changegroupsubset capability if not available
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36611
diff changeset
   879
32744
33b7283a3828 streamclone: consider secret changesets (BC) (issue5589)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32291
diff changeset
   880
    if streamclone.allowservergeneration(repo):
33225
90a1b62bdc91 configitems: register the 'server.preferuncompressed' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33224
diff changeset
   881
        if repo.ui.configbool('server', 'preferuncompressed'):
16361
6097ede2be4d protocol: Add the stream-preferred capability
Benoit Allard <benoit@aeteurope.nl>
parents: 15925
diff changeset
   882
            caps.append('stream-preferred')
12296
d7fff529d85d clone: only use stream when we understand the revlog format
Sune Foldager <cryo@cyanite.org>
parents: 12085
diff changeset
   883
        requiredformats = repo.requirements & repo.supportedformats
d7fff529d85d clone: only use stream when we understand the revlog format
Sune Foldager <cryo@cyanite.org>
parents: 12085
diff changeset
   884
        # if our local revlogs are just revlogv1, add 'stream' cap
32291
bd872f64a8ba cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents: 32260
diff changeset
   885
        if not requiredformats - {'revlogv1'}:
12296
d7fff529d85d clone: only use stream when we understand the revlog format
Sune Foldager <cryo@cyanite.org>
parents: 12085
diff changeset
   886
            caps.append('stream')
d7fff529d85d clone: only use stream when we understand the revlog format
Sune Foldager <cryo@cyanite.org>
parents: 12085
diff changeset
   887
        # otherwise, add 'streamreqs' detailing our local revlog format
d7fff529d85d clone: only use stream when we understand the revlog format
Sune Foldager <cryo@cyanite.org>
parents: 12085
diff changeset
   888
        else:
26911
d7e5e4da8394 stream: sort stream capability before serialisation
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26857
diff changeset
   889
            caps.append('streamreqs=%s' % ','.join(sorted(requiredformats)))
33499
0407a51b9d8c codemod: register core configitems using a script
Jun Wu <quark@fb.com>
parents: 33225
diff changeset
   890
    if repo.ui.configbool('experimental', 'bundle2-advertise'):
35783
c97639ad6874 bundle2: specify what capabilities will be used for
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35782
diff changeset
   891
        capsblob = bundle2.encodecaps(bundle2.getrepocaps(repo, role='server'))
28883
032c4c2f802a pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents: 28666
diff changeset
   892
        caps.append('bundle2=' + urlreq.quote(capsblob))
28666
ae53ecc47414 bundle: move writebundle() from changegroup.py to bundle2.py (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 28530
diff changeset
   893
    caps.append('unbundle=%s' % ','.join(bundle2.bundlepriority))
30563
e118233172fe wireproto: only advertise HTTP-specific capabilities to HTTP peers (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30473
diff changeset
   894
36613
6e585bca962e wireproto: add transport specific capabilities in the transport
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36612
diff changeset
   895
    return proto.addcapabilities(repo, caps)
20775
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   896
21024
7731a2281cf0 spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents: 20969
diff changeset
   897
# If you are writing an extension and consider wrapping this function. Wrap
20775
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   898
# `_capabilities` instead.
36800
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   899
@wireprotocommand('capabilities', permission='pull')
20775
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   900
def capabilities(repo, proto):
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   901
    return wireprototypes.bytesresponse(' '.join(_capabilities(repo, proto)))
11594
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
   902
36800
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   903
@wireprotocommand('changegroup', 'roots', transportpolicy=POLICY_V1_ONLY,
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   904
                  permission='pull')
11584
1af96b090116 protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents: 11583
diff changeset
   905
def changegroup(repo, proto, roots):
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   906
    nodes = decodelist(roots)
34100
1632999d4bed changegroup: replace changegroup with makechangegroup
Durham Goode <durham@fb.com>
parents: 34097
diff changeset
   907
    outgoing = discovery.outgoing(repo, missingroots=nodes,
1632999d4bed changegroup: replace changegroup with makechangegroup
Durham Goode <durham@fb.com>
parents: 34097
diff changeset
   908
                                  missingheads=repo.heads())
1632999d4bed changegroup: replace changegroup with makechangegroup
Durham Goode <durham@fb.com>
parents: 34097
diff changeset
   909
    cg = changegroupmod.makechangegroup(repo, outgoing, '01', 'serve')
35705
8cdb671dbd0b wireproto: drop support for reader interface from streamres (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35491
diff changeset
   910
    gen = iter(lambda: cg.read(32768), '')
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   911
    return wireprototypes.streamres(gen=gen)
11584
1af96b090116 protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents: 11583
diff changeset
   912
36611
6906547c8476 wireproto: don't expose legacy commands to version 2 of wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36609
diff changeset
   913
@wireprotocommand('changegroupsubset', 'bases heads',
36800
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   914
                  transportpolicy=POLICY_V1_ONLY,
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   915
                  permission='pull')
11584
1af96b090116 protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents: 11583
diff changeset
   916
def changegroupsubset(repo, proto, bases, heads):
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   917
    bases = decodelist(bases)
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   918
    heads = decodelist(heads)
34097
f7d41b85bbf6 changegroup: replace changegroupsubset with makechangegroup
Durham Goode <durham@fb.com>
parents: 34062
diff changeset
   919
    outgoing = discovery.outgoing(repo, missingroots=bases,
f7d41b85bbf6 changegroup: replace changegroupsubset with makechangegroup
Durham Goode <durham@fb.com>
parents: 34062
diff changeset
   920
                                  missingheads=heads)
f7d41b85bbf6 changegroup: replace changegroupsubset with makechangegroup
Durham Goode <durham@fb.com>
parents: 34062
diff changeset
   921
    cg = changegroupmod.makechangegroup(repo, outgoing, '01', 'serve')
35705
8cdb671dbd0b wireproto: drop support for reader interface from streamres (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35491
diff changeset
   922
    gen = iter(lambda: cg.read(32768), '')
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   923
    return wireprototypes.streamres(gen=gen)
11584
1af96b090116 protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents: 11583
diff changeset
   924
36800
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   925
@wireprotocommand('debugwireargs', 'one two *',
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   926
                  permission='pull')
13721
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
   927
def debugwireargs(repo, proto, one, two, others):
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
   928
    # only accept optional args from the known set
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
   929
    opts = options('debugwireargs', ['three', 'four'], others)
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   930
    return wireprototypes.bytesresponse(repo.debugwireargs(
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   931
        one, two, **pycompat.strkwargs(opts)))
13720
9c4e04fe267e debug: add debugwireargs to test argument passing over the wire
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13450
diff changeset
   932
36800
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   933
@wireprotocommand('getbundle', '*', permission='pull')
13741
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13726
diff changeset
   934
def getbundle(repo, proto, others):
21646
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   935
    opts = options('getbundle', gboptsmap.keys(), others)
13741
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13726
diff changeset
   936
    for k, v in opts.iteritems():
21646
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   937
        keytype = gboptsmap[k]
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   938
        if keytype == 'nodes':
19201
309c439cdbaa bundle-ng: add bundlecaps argument to getbundle() command
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 19176
diff changeset
   939
            opts[k] = decodelist(v)
21646
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   940
        elif keytype == 'csv':
25403
30ab130af221 wireprotocol: distinguish list and set in getbundle argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25339
diff changeset
   941
            opts[k] = list(v.split(','))
30ab130af221 wireprotocol: distinguish list and set in getbundle argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25339
diff changeset
   942
        elif keytype == 'scsv':
19201
309c439cdbaa bundle-ng: add bundlecaps argument to getbundle() command
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 19176
diff changeset
   943
            opts[k] = set(v.split(','))
21988
12cd3827b860 wireproto: add a ``boolean`` type for getbundle parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21728
diff changeset
   944
        elif keytype == 'boolean':
26686
3e7f675628ad wireproto: properly parse false boolean args (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
   945
            # Client should serialize False as '0', which is a non-empty string
3e7f675628ad wireproto: properly parse false boolean args (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
   946
            # so it evaluates as a True bool.
3e7f675628ad wireproto: properly parse false boolean args (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
   947
            if v == '0':
3e7f675628ad wireproto: properly parse false boolean args (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
   948
                opts[k] = False
3e7f675628ad wireproto: properly parse false boolean args (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
   949
            else:
3e7f675628ad wireproto: properly parse false boolean args (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
   950
                opts[k] = bool(v)
21646
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   951
        elif keytype != 'plain':
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   952
            raise KeyError('unknown getbundle option type %s'
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   953
                           % keytype)
27246
b288fb2724bf wireproto: config options to disable bundle1
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27243
diff changeset
   954
27633
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   955
    if not bundle1allowed(repo, 'pull'):
27246
b288fb2724bf wireproto: config options to disable bundle1
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27243
diff changeset
   956
        if not exchange.bundle2requested(opts.get('bundlecaps')):
36223
2e07dc514073 wireprotoserver: add version to HTTP protocol name (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36221
diff changeset
   957
            if proto.name == 'http-v1':
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   958
                return wireprototypes.ooberror(bundle2required)
30912
3d4afc2fdcd7 bundle1: fix bundle1-denied reporting for pull over ssh
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30910
diff changeset
   959
            raise error.Abort(bundle2requiredmain,
3d4afc2fdcd7 bundle1: fix bundle1-denied reporting for pull over ssh
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30910
diff changeset
   960
                              hint=bundle2requiredhint)
27246
b288fb2724bf wireproto: config options to disable bundle1
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27243
diff changeset
   961
35787
a84dbc87dae9 exchange: send bundle2 stream clones uncompressed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35785
diff changeset
   962
    prefercompressed = True
35782
9d249f3de730 wireproto: don't compress errors from getbundle()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35760
diff changeset
   963
30914
f3807a135e43 wireproto: properly report server Abort during 'getbundle'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30912
diff changeset
   964
    try:
33223
d227451ee280 configitems: register the 'server.disablefullbundle' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33220
diff changeset
   965
        if repo.ui.configbool('server', 'disablefullbundle'):
32260
d0d9a4fca59b clone: add a server-side option to disable full getbundles (pull-based clones)
Siddharth Agarwal <sid0@fb.com>
parents: 31451
diff changeset
   966
            # Check to see if this is a full clone.
d0d9a4fca59b clone: add a server-side option to disable full getbundles (pull-based clones)
Siddharth Agarwal <sid0@fb.com>
parents: 31451
diff changeset
   967
            clheads = set(repo.changelog.heads())
35760
133a678673cb clone: allow bundle2's stream clone with 'server.disablefullbundle'
Boris Feld <boris.feld@octobus.net>
parents: 35759
diff changeset
   968
            changegroup = opts.get('cg', True)
32260
d0d9a4fca59b clone: add a server-side option to disable full getbundles (pull-based clones)
Siddharth Agarwal <sid0@fb.com>
parents: 31451
diff changeset
   969
            heads = set(opts.get('heads', set()))
d0d9a4fca59b clone: add a server-side option to disable full getbundles (pull-based clones)
Siddharth Agarwal <sid0@fb.com>
parents: 31451
diff changeset
   970
            common = set(opts.get('common', set()))
d0d9a4fca59b clone: add a server-side option to disable full getbundles (pull-based clones)
Siddharth Agarwal <sid0@fb.com>
parents: 31451
diff changeset
   971
            common.discard(nullid)
35760
133a678673cb clone: allow bundle2's stream clone with 'server.disablefullbundle'
Boris Feld <boris.feld@octobus.net>
parents: 35759
diff changeset
   972
            if changegroup and not common and clheads == heads:
32260
d0d9a4fca59b clone: add a server-side option to disable full getbundles (pull-based clones)
Siddharth Agarwal <sid0@fb.com>
parents: 31451
diff changeset
   973
                raise error.Abort(
d0d9a4fca59b clone: add a server-side option to disable full getbundles (pull-based clones)
Siddharth Agarwal <sid0@fb.com>
parents: 31451
diff changeset
   974
                    _('server has pull-based clones disabled'),
d0d9a4fca59b clone: add a server-side option to disable full getbundles (pull-based clones)
Siddharth Agarwal <sid0@fb.com>
parents: 31451
diff changeset
   975
                    hint=_('remove --pull if specified or upgrade Mercurial'))
d0d9a4fca59b clone: add a server-side option to disable full getbundles (pull-based clones)
Siddharth Agarwal <sid0@fb.com>
parents: 31451
diff changeset
   976
35785
ba15580e53d5 exchange: return bundle info from getbundlechunks() (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35783
diff changeset
   977
        info, chunks = exchange.getbundlechunks(repo, 'serve',
ba15580e53d5 exchange: return bundle info from getbundlechunks() (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35783
diff changeset
   978
                                                **pycompat.strkwargs(opts))
35787
a84dbc87dae9 exchange: send bundle2 stream clones uncompressed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35785
diff changeset
   979
        prefercompressed = info.get('prefercompressed', True)
30914
f3807a135e43 wireproto: properly report server Abort during 'getbundle'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30912
diff changeset
   980
    except error.Abort as exc:
f3807a135e43 wireproto: properly report server Abort during 'getbundle'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30912
diff changeset
   981
        # cleanly forward Abort error to the client
f3807a135e43 wireproto: properly report server Abort during 'getbundle'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30912
diff changeset
   982
        if not exchange.bundle2requested(opts.get('bundlecaps')):
36223
2e07dc514073 wireprotoserver: add version to HTTP protocol name (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36221
diff changeset
   983
            if proto.name == 'http-v1':
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   984
                return wireprototypes.ooberror(pycompat.bytestr(exc) + '\n')
30914
f3807a135e43 wireproto: properly report server Abort during 'getbundle'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30912
diff changeset
   985
            raise # cannot do better for bundle1 + ssh
f3807a135e43 wireproto: properly report server Abort during 'getbundle'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30912
diff changeset
   986
        # bundle2 request expect a bundle2 reply
f3807a135e43 wireproto: properly report server Abort during 'getbundle'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30912
diff changeset
   987
        bundler = bundle2.bundle20(repo.ui)
36258
af0a19d8812b py3: get bytes-repr of network errors portably
Augie Fackler <augie@google.com>
parents: 36223
diff changeset
   988
        manargs = [('message', pycompat.bytestr(exc))]
30914
f3807a135e43 wireproto: properly report server Abort during 'getbundle'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30912
diff changeset
   989
        advargs = []
f3807a135e43 wireproto: properly report server Abort during 'getbundle'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30912
diff changeset
   990
        if exc.hint is not None:
f3807a135e43 wireproto: properly report server Abort during 'getbundle'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30912
diff changeset
   991
            advargs.append(('hint', exc.hint))
f3807a135e43 wireproto: properly report server Abort during 'getbundle'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30912
diff changeset
   992
        bundler.addpart(bundle2.bundlepart('error:abort',
f3807a135e43 wireproto: properly report server Abort during 'getbundle'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30912
diff changeset
   993
                                           manargs, advargs))
35782
9d249f3de730 wireproto: don't compress errors from getbundle()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35760
diff changeset
   994
        chunks = bundler.getchunks()
35787
a84dbc87dae9 exchange: send bundle2 stream clones uncompressed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35785
diff changeset
   995
        prefercompressed = False
35782
9d249f3de730 wireproto: don't compress errors from getbundle()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35760
diff changeset
   996
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   997
    return wireprototypes.streamres(
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   998
        gen=chunks, prefer_uncompressed=not prefercompressed)
13741
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13726
diff changeset
   999
36800
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
  1000
@wireprotocommand('heads', permission='pull')
11583
944c23762c3c protocol: add proto to method prototypes
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
  1001
def heads(repo, proto):
18281
898c575833c9 clfilter: drop extra filtering in wireprotocol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18280
diff changeset
  1002
    h = repo.heads()
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
  1003
    return wireprototypes.bytesresponse(encodelist(h) + '\n')
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1004
36800
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
  1005
@wireprotocommand('hello', permission='pull')
11594
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
  1006
def hello(repo, proto):
36221
62bca1c50e96 wireproto: improve docstring for "hello"
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36074
diff changeset
  1007
    """Called as part of SSH handshake to obtain server info.
62bca1c50e96 wireproto: improve docstring for "hello"
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36074
diff changeset
  1008
62bca1c50e96 wireproto: improve docstring for "hello"
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36074
diff changeset
  1009
    Returns a list of lines describing interesting things about the
62bca1c50e96 wireproto: improve docstring for "hello"
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36074
diff changeset
  1010
    server, in an RFC822-like format.
11594
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
  1011
36221
62bca1c50e96 wireproto: improve docstring for "hello"
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36074
diff changeset
  1012
    Currently, the only one defined is ``capabilities``, which consists of a
62bca1c50e96 wireproto: improve docstring for "hello"
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36074
diff changeset
  1013
    line of space separated tokens describing server abilities:
62bca1c50e96 wireproto: improve docstring for "hello"
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36074
diff changeset
  1014
62bca1c50e96 wireproto: improve docstring for "hello"
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36074
diff changeset
  1015
        capabilities: <token0> <token1> <token2>
62bca1c50e96 wireproto: improve docstring for "hello"
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36074
diff changeset
  1016
    """
36074
2f7290555c96 wireproto: introduce type for raw byte responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36073
diff changeset
  1017
    caps = capabilities(repo, proto).data
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
  1018
    return wireprototypes.bytesresponse('capabilities: %s\n' % caps)
11594
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
  1019
36800
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
  1020
@wireprotocommand('listkeys', 'namespace', permission='pull')
11583
944c23762c3c protocol: add proto to method prototypes
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
  1021
def listkeys(repo, proto, namespace):
36529
33c6f8f0388d wireproto: sort response to listkeys
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36431
diff changeset
  1022
    d = sorted(repo.listkeys(encoding.tolocal(namespace)).items())
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
  1023
    return wireprototypes.bytesresponse(pushkeymod.encodekeys(d))
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1024
36800
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
  1025
@wireprotocommand('lookup', 'key', permission='pull')
11583
944c23762c3c protocol: add proto to method prototypes
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
  1026
def lookup(repo, proto, key):
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1027
    try:
15925
f9fc46698352 wireproto: refuse to lookup secret csets
Matt Mackall <mpm@selenic.com>
parents: 15713
diff changeset
  1028
        k = encoding.tolocal(key)
37353
ac666c5c2e0c wireproto: use repo.lookup() for lookup command
Martin von Zweigbergk <martinvonz@google.com>
parents: 37320
diff changeset
  1029
        n = repo.lookup(k)
ac666c5c2e0c wireproto: use repo.lookup() for lookup command
Martin von Zweigbergk <martinvonz@google.com>
parents: 37320
diff changeset
  1030
        r = hex(n)
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1031
        success = 1
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25493
diff changeset
  1032
    except Exception as inst:
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37053
diff changeset
  1033
        r = stringutil.forcebytestr(inst)
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1034
        success = 0
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
  1035
    return wireprototypes.bytesresponse('%d %s\n' % (success, r))
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1036
36800
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
  1037
@wireprotocommand('known', 'nodes *', permission='pull')
14436
5adb52524779 wireproto: enable optional args for known() for future extensibility
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14419
diff changeset
  1038
def known(repo, proto, nodes, others):
36074
2f7290555c96 wireproto: introduce type for raw byte responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36073
diff changeset
  1039
    v = ''.join(b and '1' or '0' for b in repo.known(decodelist(nodes)))
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
  1040
    return wireprototypes.bytesresponse(v)
13723
e615765fdcc7 wireproto: add known([id]) function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13722
diff changeset
  1041
37393
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
  1042
@wireprotocommand('protocaps', 'caps', permission='pull',
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
  1043
                  transportpolicy=POLICY_V1_ONLY)
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
  1044
def protocaps(repo, proto, caps):
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
  1045
    if proto.name == wireprototypes.SSHV1:
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
  1046
        proto._protocaps = set(caps.split(' '))
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
  1047
    return wireprototypes.bytesresponse('OK')
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
  1048
36800
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
  1049
@wireprotocommand('pushkey', 'namespace key old new', permission='push')
11583
944c23762c3c protocol: add proto to method prototypes
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
  1050
def pushkey(repo, proto, namespace, key, old, new):
13050
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
  1051
    # compatibility with pre-1.8 clients which were accidentally
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
  1052
    # sending raw binary nodes rather than utf-8-encoded hex
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37053
diff changeset
  1053
    if len(new) == 20 and stringutil.escapestr(new) != new:
13050
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
  1054
        # looks like it could be a binary node
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
  1055
        try:
14064
e4bfb9c337f3 remove unused imports and variables
Alexander Solovyov <alexander@solovyov.net>
parents: 14048
diff changeset
  1056
            new.decode('utf-8')
13050
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
  1057
            new = encoding.tolocal(new) # but cleanly decodes as UTF-8
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
  1058
        except UnicodeDecodeError:
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
  1059
            pass # binary, leave unmodified
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
  1060
    else:
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
  1061
        new = encoding.tolocal(new) # normal path
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
  1062
36066
2ad145fbde54 wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35982
diff changeset
  1063
    with proto.mayberedirectstdio() as output:
35979
ae79cf6f9c82 wireproto: remove unnecessary exception trapping
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35860
diff changeset
  1064
        r = repo.pushkey(encoding.tolocal(namespace), encoding.tolocal(key),
ae79cf6f9c82 wireproto: remove unnecessary exception trapping
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35860
diff changeset
  1065
                         encoding.tolocal(old), new) or False
17793
8474be4412ca wireproto: fix pushkey hook failure and output on remote http repo
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 17603
diff changeset
  1066
36066
2ad145fbde54 wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35982
diff changeset
  1067
    output = output.getvalue() if output else ''
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
  1068
    return wireprototypes.bytesresponse('%d\n%s' % (int(r), output))
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1069
36800
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
  1070
@wireprotocommand('stream_out', permission='pull')
11585
5d907fbb9703 protocol: unify stream_out command
Matt Mackall <mpm@selenic.com>
parents: 11584
diff changeset
  1071
def stream(repo, proto):
11627
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
  1072
    '''If the server supports streaming clone, it advertises the "stream"
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
  1073
    capability with a value representing the version and flags of the repo
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
  1074
    it is serving. Client checks to see if it understands the format.
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
  1075
    '''
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
  1076
    return wireprototypes.streamreslegacy(
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
  1077
        streamclone.generatev1wireproto(repo))
11585
5d907fbb9703 protocol: unify stream_out command
Matt Mackall <mpm@selenic.com>
parents: 11584
diff changeset
  1078
36800
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
  1079
@wireprotocommand('unbundle', 'heads', permission='push')
11593
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
  1080
def unbundle(repo, proto, heads):
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
  1081
    their_heads = decodelist(heads)
11593
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
  1082
36067
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1083
    with proto.mayberedirectstdio() as output:
11593
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
  1084
        try:
36067
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1085
            exchange.check_heads(repo, their_heads, 'preparing changes')
27246
b288fb2724bf wireproto: config options to disable bundle1
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27243
diff changeset
  1086
36067
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1087
            # write bundle data to temporary file because it can be big
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1088
            fd, tempname = tempfile.mkstemp(prefix='hg-unbundle-')
36835
5bc7ff103081 py3: use r'' instead of sysstr('') to get around code transformer
Yuya Nishihara <yuya@tcha.org>
parents: 36801
diff changeset
  1089
            fp = os.fdopen(fd, r'wb+')
36067
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1090
            r = 0
24796
61ff209fc01d bundle2: refactor error bundle creation for the wireprotocol
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24696
diff changeset
  1091
            try:
36070
90ca4986616c wireprotoserver: rename getfile() to forwardpayload() (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36069
diff changeset
  1092
                proto.forwardpayload(fp)
36067
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1093
                fp.seek(0)
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1094
                gen = exchange.readbundle(repo.ui, fp, None)
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1095
                if (isinstance(gen, changegroupmod.cg1unpacker)
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1096
                    and not bundle1allowed(repo, 'push')):
36223
2e07dc514073 wireprotoserver: add version to HTTP protocol name (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36221
diff changeset
  1097
                    if proto.name == 'http-v1':
36067
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1098
                        # need to special case http because stderr do not get to
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1099
                        # the http client on failed push so we need to abuse
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1100
                        # some other error type to make sure the message get to
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1101
                        # the user.
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
  1102
                        return wireprototypes.ooberror(bundle2required)
36067
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1103
                    raise error.Abort(bundle2requiredmain,
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1104
                                      hint=bundle2requiredhint)
24796
61ff209fc01d bundle2: refactor error bundle creation for the wireprotocol
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24696
diff changeset
  1105
36067
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1106
                r = exchange.unbundle(repo, gen, their_heads, 'serve',
36069
957e773614d0 wireprotoserver: rename _client to client (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36067
diff changeset
  1107
                                      proto.client())
36067
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1108
                if util.safehasattr(r, 'addpart'):
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1109
                    # The return looks streamable, we are in the bundle2 case
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1110
                    # and should return a stream.
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
  1111
                    return wireprototypes.streamreslegacy(gen=r.getchunks())
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
  1112
                return wireprototypes.pushres(
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
  1113
                    r, output.getvalue() if output else '')
36067
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1114
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1115
            finally:
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1116
                fp.close()
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1117
                os.unlink(tempname)
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1118
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1119
        except (error.BundleValueError, error.Abort, error.PushRaced) as exc:
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1120
            # handle non-bundle2 case first
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1121
            if not getattr(exc, 'duringunbundle2', False):
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1122
                try:
25493
d8e7b0781ad7 bundle2: convey PushkeyFailed error over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25403
diff changeset
  1123
                    raise
36067
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1124
                except error.Abort:
37119
d4a2e0d5d042 procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
  1125
                    # The old code we moved used procutil.stderr directly.
36067
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1126
                    # We did not change it to minimise code change.
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1127
                    # This need to be moved to something proper.
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1128
                    # Feel free to do it.
37119
d4a2e0d5d042 procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
  1129
                    procutil.stderr.write("abort: %s\n" % exc)
36067
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1130
                    if exc.hint is not None:
37119
d4a2e0d5d042 procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
  1131
                        procutil.stderr.write("(%s)\n" % exc.hint)
d4a2e0d5d042 procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
  1132
                    procutil.stderr.flush()
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
  1133
                    return wireprototypes.pushres(
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
  1134
                        0, output.getvalue() if output else '')
36067
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1135
                except error.PushRaced:
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
  1136
                    return wireprototypes.pusherr(
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
  1137
                        pycompat.bytestr(exc),
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
  1138
                        output.getvalue() if output else '')
36067
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1139
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1140
            bundler = bundle2.bundle20(repo.ui)
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1141
            for out in getattr(exc, '_bundle2salvagedoutput', ()):
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1142
                bundler.addpart(out)
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1143
            try:
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1144
                try:
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1145
                    raise
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1146
                except error.PushkeyFailed as exc:
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1147
                    # check client caps
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1148
                    remotecaps = getattr(exc, '_replycaps', None)
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1149
                    if (remotecaps is not None
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1150
                            and 'pushkey' not in remotecaps.get('error', ())):
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1151
                        # no support remote side, fallback to Abort handler.
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1152
                        raise
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1153
                    part = bundler.newpart('error:pushkey')
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1154
                    part.addparam('in-reply-to', exc.partid)
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1155
                    if exc.namespace is not None:
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1156
                        part.addparam('namespace', exc.namespace,
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1157
                                      mandatory=False)
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1158
                    if exc.key is not None:
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1159
                        part.addparam('key', exc.key, mandatory=False)
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1160
                    if exc.new is not None:
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1161
                        part.addparam('new', exc.new, mandatory=False)
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1162
                    if exc.old is not None:
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1163
                        part.addparam('old', exc.old, mandatory=False)
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1164
                    if exc.ret is not None:
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1165
                        part.addparam('ret', exc.ret, mandatory=False)
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1166
            except error.BundleValueError as exc:
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1167
                errpart = bundler.newpart('error:unsupportedcontent')
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1168
                if exc.parttype is not None:
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1169
                    errpart.addparam('parttype', exc.parttype)
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1170
                if exc.params:
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1171
                    errpart.addparam('params', '\0'.join(exc.params))
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1172
            except error.Abort as exc:
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37053
diff changeset
  1173
                manargs = [('message', stringutil.forcebytestr(exc))]
36067
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1174
                advargs = []
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1175
                if exc.hint is not None:
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1176
                    advargs.append(('hint', exc.hint))
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1177
                bundler.addpart(bundle2.bundlepart('error:abort',
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1178
                                                   manargs, advargs))
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
  1179
            except error.PushRaced as exc:
36314
be9c497e0bfd wireproto: fix lingering str(exception) with util.forcebytestr(exception)
Augie Fackler <augie@google.com>
parents: 36258
diff changeset
  1180
                bundler.newpart('error:pushraced',
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37053
diff changeset
  1181
                                [('message', stringutil.forcebytestr(exc))])
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
  1182
            return wireprototypes.streamreslegacy(gen=bundler.getchunks())