mercurial/wireprotov1server.py
author Martin von Zweigbergk <martinvonz@google.com>
Fri, 04 May 2018 21:58:43 -0700
changeset 37860 a91f31a1e281
parent 37785 b4d85bc122bd
child 38164 aac4be30e250
permissions -rw-r--r--
revlog: extract function for getting node from known-to-exist rev Many of the calls to index_node() (which converts a rev to a nodeid) are done with a rev that's know to exist. If the function fails, there's something really wrong and we should just abort. This was done in only one place. This patch starts by extracting that code to a function that we can reuse in later patches. Differential Revision: https://phab.mercurial-scm.org/D3456
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
37785
b4d85bc122bd wireproto: rename wireproto to wireprotov1server (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37784
diff changeset
     1
# wireprotov1server.py - Wire protocol version 1 server functionality
11581
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
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    10
import os
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    11
import tempfile
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    12
25993
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    13
from .i18n import _
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    14
from .node import (
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    15
    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
    16
    nullid,
25993
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    17
)
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    18
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    19
from . import (
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    20
    bundle2,
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    21
    changegroup as changegroupmod,
34097
f7d41b85bbf6 changegroup: replace changegroupsubset with makechangegroup
Durham Goode <durham@fb.com>
parents: 34062
diff changeset
    22
    discovery,
25993
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    23
    encoding,
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    24
    error,
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    25
    exchange,
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    26
    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
    27
    pycompat,
26443
d947086d8973 streamclone: move code out of exchange.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25993
diff changeset
    28
    streamclone,
25993
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    29
    util,
36073
cd6ab329c5c7 wireprototypes: move wire protocol response types to new module
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36071
diff changeset
    30
    wireprototypes,
25993
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    31
)
20903
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    32
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37053
diff changeset
    33
from .utils import (
37119
d4a2e0d5d042 procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
    34
    procutil,
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37053
diff changeset
    35
    stringutil,
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37053
diff changeset
    36
)
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37053
diff changeset
    37
28883
032c4c2f802a pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents: 28666
diff changeset
    38
urlerr = util.urlerr
032c4c2f802a pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents: 28666
diff changeset
    39
urlreq = util.urlreq
032c4c2f802a pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents: 28666
diff changeset
    40
30909
d554e624c5fe bundle1: fix bundle1-denied reporting for push over ssh
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30762
diff changeset
    41
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
    42
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
    43
                        'IncompatibleClient')
d554e624c5fe bundle1: fix bundle1-denied reporting for push over ssh
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30762
diff changeset
    44
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
    45
37393
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
    46
def clientcompressionsupport(proto):
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
    47
    """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
    48
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
    49
    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
    50
    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
    51
    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
    52
    """
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
    53
    for cap in proto.getprotocaps():
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
    54
        if cap.startswith('comp='):
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
    55
            return cap[5:].split(',')
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
    56
    return ['zlib', 'none']
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
    57
20902
1e4fda2f5cf1 wireproto: document possible return type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20775
diff changeset
    58
# 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
    59
29590
84c1a5942f1d wireproto: extract repo filtering to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29341
diff changeset
    60
def getdispatchrepo(repo, proto, command):
84c1a5942f1d wireproto: extract repo filtering to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29341
diff changeset
    61
    """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
    62
84c1a5942f1d wireproto: extract repo filtering to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29341
diff changeset
    63
    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
    64
    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
    65
    specialized circumstances.
84c1a5942f1d wireproto: extract repo filtering to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29341
diff changeset
    66
    """
84c1a5942f1d wireproto: extract repo filtering to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29341
diff changeset
    67
    return repo.filtered('served')
84c1a5942f1d wireproto: extract repo filtering to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29341
diff changeset
    68
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    69
def dispatch(repo, proto, command):
29590
84c1a5942f1d wireproto: extract repo filtering to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29341
diff changeset
    70
    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
    71
37782
99accae4cc59 wireproto: reimplement dispatch() for version 2 server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37781
diff changeset
    72
    func, spec = commands[command]
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    73
    args = proto.getargs(spec)
37485
0b7475ea38cf wireproto: port heads command to wire protocol v2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37414
diff changeset
    74
37782
99accae4cc59 wireproto: reimplement dispatch() for version 2 server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37781
diff changeset
    75
    return func(repo, proto, *args)
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    76
13721
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
    77
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
    78
    opts = {}
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
    79
    for k in keys:
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
    80
        if k in others:
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
    81
            opts[k] = others[k]
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
    82
            del others[k]
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
    83
    if others:
37119
d4a2e0d5d042 procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
    84
        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
    85
                              % (cmd, ",".join(others)))
13721
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
    86
    return opts
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
    87
27633
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
    88
def bundle1allowed(repo, action):
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
    89
    """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
    90
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
    91
    Priority is:
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
    92
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
    93
    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
    94
    2. server.bundle1.<action>
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
    95
    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
    96
    4. server.bundle1
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
    97
    """
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
    98
    ui = repo.ui
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
    99
    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
   100
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   101
    if gd:
34613
5e61cd5fb0fc configitems: register the 'server.bundle*' family of config
Boris Feld <boris.feld@octobus.net>
parents: 34322
diff changeset
   102
        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
   103
        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
   104
            return v
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   105
34613
5e61cd5fb0fc configitems: register the 'server.bundle*' family of config
Boris Feld <boris.feld@octobus.net>
parents: 34322
diff changeset
   106
    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
   107
    if v is not None:
b288fb2724bf wireproto: config options to disable bundle1
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27243
diff changeset
   108
        return v
b288fb2724bf wireproto: config options to disable bundle1
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27243
diff changeset
   109
27633
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   110
    if gd:
33220
40861b2254a5 configitems: register the 'server.bundle1gd' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33219
diff changeset
   111
        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
   112
        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
   113
            return v
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   114
33219
ffb1d0f541f5 configitems: register the 'server.bundle1' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32880
diff changeset
   115
    return ui.configbool('server', 'bundle1')
27246
b288fb2724bf wireproto: config options to disable bundle1
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27243
diff changeset
   116
37781
352932a11905 wireproto: move command registration types to wireprototypes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37780
diff changeset
   117
commands = wireprototypes.commanddict()
20906
7a634b34fc91 wireproto: add decorator for wire protocol command
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20905
diff changeset
   118
37780
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37779
diff changeset
   119
def wireprotocommand(name, args=None, permission='push'):
35980
b4976912a6ef wireproto: improve docstring for @wireprotocommand
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35979
diff changeset
   120
    """Decorator to declare a wire protocol command.
b4976912a6ef wireproto: improve docstring for @wireprotocommand
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35979
diff changeset
   121
b4976912a6ef wireproto: improve docstring for @wireprotocommand
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35979
diff changeset
   122
    ``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
   123
37535
69e46c1834ac wireproto: define and expose types of wire command arguments
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37534
diff changeset
   124
    ``args`` defines the named arguments accepted by the command. It is
37780
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37779
diff changeset
   125
    a space-delimited list of argument names. ``*`` denotes a special value
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37779
diff changeset
   126
    that says to accept all named arguments.
36800
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   127
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   128
    ``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
   129
    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
   130
    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
   131
    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
   132
    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
   133
    """
37780
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37779
diff changeset
   134
    transports = {k for k, v in wireprototypes.TRANSPORTS.items()
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37779
diff changeset
   135
                  if v['version'] == 1}
36609
abc3b9801563 wireproto: allow wire protocol commands to declare transport support
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36535
diff changeset
   136
37053
cd0ca979a8b8 wireproto: nominally don't expose "batch" to version 2 wire transports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36991
diff changeset
   137
    # 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
   138
    # SSHv2.
cd0ca979a8b8 wireproto: nominally don't expose "batch" to version 2 wire transports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36991
diff changeset
   139
    # 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
   140
    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
   141
        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
   142
36800
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   143
    if permission not in ('push', 'pull'):
36840
ef68493d652b wireproto: raise ProgrammingError instead of Abort
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36835
diff changeset
   144
        raise error.ProgrammingError('invalid wire protocol permission; '
ef68493d652b wireproto: raise ProgrammingError instead of Abort
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36835
diff changeset
   145
                                     'got %s; expected "push" or "pull"' %
ef68493d652b wireproto: raise ProgrammingError instead of Abort
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36835
diff changeset
   146
                                     permission)
36800
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   147
37780
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37779
diff changeset
   148
    if args is None:
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37779
diff changeset
   149
        args = ''
37535
69e46c1834ac wireproto: define and expose types of wire command arguments
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37534
diff changeset
   150
37780
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37779
diff changeset
   151
    if not isinstance(args, bytes):
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37779
diff changeset
   152
        raise error.ProgrammingError('arguments for version 1 commands '
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37779
diff changeset
   153
                                     'must be declared as bytes')
37535
69e46c1834ac wireproto: define and expose types of wire command arguments
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37534
diff changeset
   154
20906
7a634b34fc91 wireproto: add decorator for wire protocol command
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20905
diff changeset
   155
    def register(func):
37780
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37779
diff changeset
   156
        if name in commands:
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37779
diff changeset
   157
            raise error.ProgrammingError('%s command already registered '
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37779
diff changeset
   158
                                         'for version 1' % name)
37781
352932a11905 wireproto: move command registration types to wireprototypes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37780
diff changeset
   159
        commands[name] = wireprototypes.commandentry(
352932a11905 wireproto: move command registration types to wireprototypes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37780
diff changeset
   160
            func, args=args, transports=transports, permission=permission)
37295
45b39c69fae0 wireproto: separate commands tables for version 1 and 2 commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37293
diff changeset
   161
20906
7a634b34fc91 wireproto: add decorator for wire protocol command
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20905
diff changeset
   162
        return func
7a634b34fc91 wireproto: add decorator for wire protocol command
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20905
diff changeset
   163
    return register
7a634b34fc91 wireproto: add decorator for wire protocol command
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20905
diff changeset
   164
36755
ff4bc0ab6740 wireproto: check permissions when executing "batch" command (BC) (SEC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36754
diff changeset
   165
# TODO define a more appropriate permissions type to use for this.
37779
379d54eae6eb wireproto: don't pass transportpolicy argument
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
   166
@wireprotocommand('batch', 'cmds *', permission='pull')
14622
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   167
def batch(repo, proto, cmds, others):
37612
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   168
    unescapearg = wireprototypes.unescapebatcharg
18382
f3b21beb9802 filtering: rename filters to their antonyms
Kevin Bullock <kbullock@ringworld.org>
parents: 18381
diff changeset
   169
    repo = repo.filtered("served")
14622
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   170
    res = []
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   171
    for pair in cmds.split(';'):
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   172
        op, args = pair.split(' ', 1)
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   173
        vals = {}
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   174
        for a in args.split(','):
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   175
            if a:
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   176
                n, v = a.split('=')
29734
62e2e048d068 wireproto: unescape argument names in batch command (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29733
diff changeset
   177
                vals[unescapearg(n)] = unescapearg(v)
14622
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   178
        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
   179
36801
66de4555cefd wireproto: formalize permissions checking as part of protocol interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36800
diff changeset
   180
        # 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
   181
        perm = commands[op].permission
66de4555cefd wireproto: formalize permissions checking as part of protocol interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36800
diff changeset
   182
        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
   183
        proto.checkperm(perm)
36755
ff4bc0ab6740 wireproto: check permissions when executing "batch" command (BC) (SEC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36754
diff changeset
   184
14622
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   185
        if spec:
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   186
            keys = spec.split()
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   187
            data = {}
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   188
            for k in keys:
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   189
                if k == '*':
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   190
                    star = {}
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   191
                    for key in vals.keys():
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   192
                        if key not in keys:
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   193
                            star[key] = vals[key]
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   194
                    data['*'] = star
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   195
                else:
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   196
                    data[k] = vals[k]
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   197
            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
   198
        else:
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   199
            result = func(repo, proto)
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   200
        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
   201
            return result
36074
2f7290555c96 wireproto: introduce type for raw byte responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36073
diff changeset
   202
2f7290555c96 wireproto: introduce type for raw byte responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36073
diff changeset
   203
        # 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
   204
        # raw bytes (for backwards compatibility).
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   205
        assert isinstance(result, (wireprototypes.bytesresponse, bytes))
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   206
        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
   207
            result = result.data
37612
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   208
        res.append(wireprototypes.escapebatcharg(result))
36074
2f7290555c96 wireproto: introduce type for raw byte responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36073
diff changeset
   209
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   210
    return wireprototypes.bytesresponse(';'.join(res))
14622
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   211
37779
379d54eae6eb wireproto: don't pass transportpolicy argument
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
   212
@wireprotocommand('between', 'pairs', permission='pull')
11583
944c23762c3c protocol: add proto to method prototypes
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
   213
def between(repo, proto, pairs):
37612
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   214
    pairs = [wireprototypes.decodelist(p, '-') for p in pairs.split(" ")]
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   215
    r = []
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   216
    for b in repo.between(pairs):
37612
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   217
        r.append(wireprototypes.encodelist(b) + "\n")
36074
2f7290555c96 wireproto: introduce type for raw byte responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36073
diff changeset
   218
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   219
    return wireprototypes.bytesresponse(''.join(r))
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   220
37779
379d54eae6eb wireproto: don't pass transportpolicy argument
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
   221
@wireprotocommand('branchmap', permission='pull')
11583
944c23762c3c protocol: add proto to method prototypes
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
   222
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
   223
    branchmap = repo.branchmap()
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   224
    heads = []
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   225
    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
   226
        branchname = urlreq.quote(encoding.fromlocal(branch))
37612
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   227
        branchnodes = wireprototypes.encodelist(nodes)
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   228
        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
   229
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   230
    return wireprototypes.bytesresponse('\n'.join(heads))
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   231
37779
379d54eae6eb wireproto: don't pass transportpolicy argument
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
   232
@wireprotocommand('branches', 'nodes', permission='pull')
11583
944c23762c3c protocol: add proto to method prototypes
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
   233
def branches(repo, proto, nodes):
37612
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   234
    nodes = wireprototypes.decodelist(nodes)
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   235
    r = []
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   236
    for b in repo.branches(nodes):
37612
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   237
        r.append(wireprototypes.encodelist(b) + "\n")
36074
2f7290555c96 wireproto: introduce type for raw byte responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36073
diff changeset
   238
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   239
    return wireprototypes.bytesresponse(''.join(r))
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   240
37779
379d54eae6eb wireproto: don't pass transportpolicy argument
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
   241
@wireprotocommand('clonebundles', '', permission='pull')
26857
e5a1df51bb25 wireproto: move clonebundles command from extension (issue4931)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26690
diff changeset
   242
def clonebundles(repo, proto):
e5a1df51bb25 wireproto: move clonebundles command from extension (issue4931)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26690
diff changeset
   243
    """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
   244
e5a1df51bb25 wireproto: move clonebundles command from extension (issue4931)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26690
diff changeset
   245
    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
   246
e5a1df51bb25 wireproto: move clonebundles command from extension (issue4931)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26690
diff changeset
   247
    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
   248
    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
   249
    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
   250
    """
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   251
    return wireprototypes.bytesresponse(
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   252
        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
   253
36612
e89959970a08 wireproto: don't expose changegroupsubset capability if not available
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36611
diff changeset
   254
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
   255
                 '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
   256
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   257
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
   258
    """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
   259
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   260
    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
   261
    computation
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   262
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   263
    - 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
   264
    - 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
   265
      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
   266
    """
20774
cdc3ac896997 wireproto: extract capabilities list in outside the wireproto function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20671
diff changeset
   267
    # 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
   268
    caps = list(wireprotocaps)
36612
e89959970a08 wireproto: don't expose changegroupsubset capability if not available
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36611
diff changeset
   269
e89959970a08 wireproto: don't expose changegroupsubset capability if not available
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36611
diff changeset
   270
    # 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
   271
    # 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
   272
    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
   273
        caps.append('changegroupsubset')
e89959970a08 wireproto: don't expose changegroupsubset capability if not available
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36611
diff changeset
   274
32744
33b7283a3828 streamclone: consider secret changesets (BC) (issue5589)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32291
diff changeset
   275
    if streamclone.allowservergeneration(repo):
33225
90a1b62bdc91 configitems: register the 'server.preferuncompressed' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33224
diff changeset
   276
        if repo.ui.configbool('server', 'preferuncompressed'):
16361
6097ede2be4d protocol: Add the stream-preferred capability
Benoit Allard <benoit@aeteurope.nl>
parents: 15925
diff changeset
   277
            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
   278
        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
   279
        # 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
   280
        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
   281
            caps.append('stream')
d7fff529d85d clone: only use stream when we understand the revlog format
Sune Foldager <cryo@cyanite.org>
parents: 12085
diff changeset
   282
        # 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
   283
        else:
26911
d7e5e4da8394 stream: sort stream capability before serialisation
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26857
diff changeset
   284
            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
   285
    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
   286
        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
   287
        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
   288
    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
   289
36613
6e585bca962e wireproto: add transport specific capabilities in the transport
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36612
diff changeset
   290
    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
   291
21024
7731a2281cf0 spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents: 20969
diff changeset
   292
# 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
   293
# `_capabilities` instead.
37779
379d54eae6eb wireproto: don't pass transportpolicy argument
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
   294
@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
   295
def capabilities(repo, proto):
37413
33af46d639b4 wireproto: send server capabilities in canonical order
Joerg Sonnenberger <joerg@bec.de>
parents: 37412
diff changeset
   296
    caps = _capabilities(repo, proto)
33af46d639b4 wireproto: send server capabilities in canonical order
Joerg Sonnenberger <joerg@bec.de>
parents: 37412
diff changeset
   297
    return wireprototypes.bytesresponse(' '.join(sorted(caps)))
11594
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
   298
37779
379d54eae6eb wireproto: don't pass transportpolicy argument
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
   299
@wireprotocommand('changegroup', 'roots', permission='pull')
11584
1af96b090116 protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents: 11583
diff changeset
   300
def changegroup(repo, proto, roots):
37612
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   301
    nodes = wireprototypes.decodelist(roots)
34100
1632999d4bed changegroup: replace changegroup with makechangegroup
Durham Goode <durham@fb.com>
parents: 34097
diff changeset
   302
    outgoing = discovery.outgoing(repo, missingroots=nodes,
1632999d4bed changegroup: replace changegroup with makechangegroup
Durham Goode <durham@fb.com>
parents: 34097
diff changeset
   303
                                  missingheads=repo.heads())
1632999d4bed changegroup: replace changegroup with makechangegroup
Durham Goode <durham@fb.com>
parents: 34097
diff changeset
   304
    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
   305
    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
   306
    return wireprototypes.streamres(gen=gen)
11584
1af96b090116 protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents: 11583
diff changeset
   307
36611
6906547c8476 wireproto: don't expose legacy commands to version 2 of wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36609
diff changeset
   308
@wireprotocommand('changegroupsubset', 'bases heads',
36800
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   309
                  permission='pull')
11584
1af96b090116 protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents: 11583
diff changeset
   310
def changegroupsubset(repo, proto, bases, heads):
37612
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   311
    bases = wireprototypes.decodelist(bases)
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   312
    heads = wireprototypes.decodelist(heads)
34097
f7d41b85bbf6 changegroup: replace changegroupsubset with makechangegroup
Durham Goode <durham@fb.com>
parents: 34062
diff changeset
   313
    outgoing = discovery.outgoing(repo, missingroots=bases,
f7d41b85bbf6 changegroup: replace changegroupsubset with makechangegroup
Durham Goode <durham@fb.com>
parents: 34062
diff changeset
   314
                                  missingheads=heads)
f7d41b85bbf6 changegroup: replace changegroupsubset with makechangegroup
Durham Goode <durham@fb.com>
parents: 34062
diff changeset
   315
    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
   316
    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
   317
    return wireprototypes.streamres(gen=gen)
11584
1af96b090116 protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents: 11583
diff changeset
   318
36800
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   319
@wireprotocommand('debugwireargs', 'one two *',
37779
379d54eae6eb wireproto: don't pass transportpolicy argument
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
   320
                  permission='pull')
13721
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
   321
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
   322
    # 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
   323
    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
   324
    return wireprototypes.bytesresponse(repo.debugwireargs(
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   325
        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
   326
37498
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   327
def find_pullbundle(repo, proto, opts, clheads, heads, common):
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   328
    """Return a file object for the first matching pullbundle.
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   329
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   330
    Pullbundles are specified in .hg/pullbundles.manifest similar to
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   331
    clonebundles.
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   332
    For each entry, the bundle specification is checked for compatibility:
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   333
    - Client features vs the BUNDLESPEC.
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   334
    - Revisions shared with the clients vs base revisions of the bundle.
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   335
      A bundle can be applied only if all its base revisions are known by
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   336
      the client.
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   337
    - At least one leaf of the bundle's DAG is missing on the client.
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   338
    - Every leaf of the bundle's DAG is part of node set the client wants.
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   339
      E.g. do not send a bundle of all changes if the client wants only
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   340
      one specific branch of many.
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   341
    """
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   342
    def decodehexstring(s):
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   343
        return set([h.decode('hex') for h in s.split(';')])
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   344
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   345
    manifest = repo.vfs.tryread('pullbundles.manifest')
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   346
    if not manifest:
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   347
        return None
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   348
    res = exchange.parseclonebundlesmanifest(repo, manifest)
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   349
    res = exchange.filterclonebundleentries(repo, res)
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   350
    if not res:
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   351
        return None
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   352
    cl = repo.changelog
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   353
    heads_anc = cl.ancestors([cl.rev(rev) for rev in heads], inclusive=True)
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   354
    common_anc = cl.ancestors([cl.rev(rev) for rev in common], inclusive=True)
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   355
    compformats = clientcompressionsupport(proto)
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   356
    for entry in res:
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   357
        if 'COMPRESSION' in entry and entry['COMPRESSION'] not in compformats:
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   358
            continue
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   359
        # No test yet for VERSION, since V2 is supported by any client
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   360
        # that advertises partial pulls
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   361
        if 'heads' in entry:
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   362
            try:
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   363
                bundle_heads = decodehexstring(entry['heads'])
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   364
            except TypeError:
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   365
                # Bad heads entry
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   366
                continue
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   367
            if bundle_heads.issubset(common):
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   368
                continue # Nothing new
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   369
            if all(cl.rev(rev) in common_anc for rev in bundle_heads):
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   370
                continue # Still nothing new
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   371
            if any(cl.rev(rev) not in heads_anc and
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   372
                   cl.rev(rev) not in common_anc for rev in bundle_heads):
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   373
                continue
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   374
        if 'bases' in entry:
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   375
            try:
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   376
                bundle_bases = decodehexstring(entry['bases'])
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   377
            except TypeError:
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   378
                # Bad bases entry
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   379
                continue
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   380
            if not all(cl.rev(rev) in common_anc for rev in bundle_bases):
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   381
                continue
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   382
        path = entry['URL']
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   383
        repo.ui.debug('sending pullbundle "%s"\n' % path)
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   384
        try:
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   385
            return repo.vfs.open(path)
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   386
        except IOError:
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   387
            repo.ui.debug('pullbundle "%s" not accessible\n' % path)
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   388
            continue
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   389
    return None
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   390
37779
379d54eae6eb wireproto: don't pass transportpolicy argument
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
   391
@wireprotocommand('getbundle', '*', permission='pull')
13741
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13726
diff changeset
   392
def getbundle(repo, proto, others):
37613
96d735601ca1 wireproto: move gboptsmap to wireprototypes and rename (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37612
diff changeset
   393
    opts = options('getbundle', wireprototypes.GETBUNDLE_ARGUMENTS.keys(),
96d735601ca1 wireproto: move gboptsmap to wireprototypes and rename (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37612
diff changeset
   394
                   others)
13741
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13726
diff changeset
   395
    for k, v in opts.iteritems():
37613
96d735601ca1 wireproto: move gboptsmap to wireprototypes and rename (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37612
diff changeset
   396
        keytype = wireprototypes.GETBUNDLE_ARGUMENTS[k]
21646
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   397
        if keytype == 'nodes':
37612
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   398
            opts[k] = wireprototypes.decodelist(v)
21646
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   399
        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
   400
            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
   401
        elif keytype == 'scsv':
19201
309c439cdbaa bundle-ng: add bundlecaps argument to getbundle() command
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 19176
diff changeset
   402
            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
   403
        elif keytype == 'boolean':
26686
3e7f675628ad wireproto: properly parse false boolean args (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
   404
            # 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
   405
            # 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
   406
            if v == '0':
3e7f675628ad wireproto: properly parse false boolean args (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
   407
                opts[k] = False
3e7f675628ad wireproto: properly parse false boolean args (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
   408
            else:
3e7f675628ad wireproto: properly parse false boolean args (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
   409
                opts[k] = bool(v)
21646
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   410
        elif keytype != 'plain':
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   411
            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
   412
                           % keytype)
27246
b288fb2724bf wireproto: config options to disable bundle1
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27243
diff changeset
   413
27633
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   414
    if not bundle1allowed(repo, 'pull'):
27246
b288fb2724bf wireproto: config options to disable bundle1
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27243
diff changeset
   415
        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
   416
            if proto.name == 'http-v1':
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   417
                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
   418
            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
   419
                              hint=bundle2requiredhint)
27246
b288fb2724bf wireproto: config options to disable bundle1
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27243
diff changeset
   420
35787
a84dbc87dae9 exchange: send bundle2 stream clones uncompressed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35785
diff changeset
   421
    prefercompressed = True
35782
9d249f3de730 wireproto: don't compress errors from getbundle()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35760
diff changeset
   422
30914
f3807a135e43 wireproto: properly report server Abort during 'getbundle'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30912
diff changeset
   423
    try:
37498
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   424
        clheads = set(repo.changelog.heads())
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   425
        heads = set(opts.get('heads', set()))
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   426
        common = set(opts.get('common', set()))
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   427
        common.discard(nullid)
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   428
        if (repo.ui.configbool('server', 'pullbundle') and
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   429
            'partial-pull' in proto.getprotocaps()):
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   430
            # Check if a pre-built bundle covers this request.
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   431
            bundle = find_pullbundle(repo, proto, opts, clheads, heads, common)
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   432
            if bundle:
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   433
                return wireprototypes.streamres(gen=util.filechunkiter(bundle),
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   434
                                                prefer_uncompressed=True)
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   435
33223
d227451ee280 configitems: register the 'server.disablefullbundle' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33220
diff changeset
   436
        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
   437
            # Check to see if this is a full clone.
35760
133a678673cb clone: allow bundle2's stream clone with 'server.disablefullbundle'
Boris Feld <boris.feld@octobus.net>
parents: 35759
diff changeset
   438
            changegroup = opts.get('cg', True)
133a678673cb clone: allow bundle2's stream clone with 'server.disablefullbundle'
Boris Feld <boris.feld@octobus.net>
parents: 35759
diff changeset
   439
            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
   440
                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
   441
                    _('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
   442
                    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
   443
35785
ba15580e53d5 exchange: return bundle info from getbundlechunks() (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35783
diff changeset
   444
        info, chunks = exchange.getbundlechunks(repo, 'serve',
ba15580e53d5 exchange: return bundle info from getbundlechunks() (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35783
diff changeset
   445
                                                **pycompat.strkwargs(opts))
35787
a84dbc87dae9 exchange: send bundle2 stream clones uncompressed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35785
diff changeset
   446
        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
   447
    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
   448
        # 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
   449
        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
   450
            if proto.name == 'http-v1':
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   451
                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
   452
            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
   453
        # 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
   454
        bundler = bundle2.bundle20(repo.ui)
36258
af0a19d8812b py3: get bytes-repr of network errors portably
Augie Fackler <augie@google.com>
parents: 36223
diff changeset
   455
        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
   456
        advargs = []
f3807a135e43 wireproto: properly report server Abort during 'getbundle'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30912
diff changeset
   457
        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
   458
            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
   459
        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
   460
                                           manargs, advargs))
35782
9d249f3de730 wireproto: don't compress errors from getbundle()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35760
diff changeset
   461
        chunks = bundler.getchunks()
35787
a84dbc87dae9 exchange: send bundle2 stream clones uncompressed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35785
diff changeset
   462
        prefercompressed = False
35782
9d249f3de730 wireproto: don't compress errors from getbundle()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35760
diff changeset
   463
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   464
    return wireprototypes.streamres(
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   465
        gen=chunks, prefer_uncompressed=not prefercompressed)
13741
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13726
diff changeset
   466
37779
379d54eae6eb wireproto: don't pass transportpolicy argument
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
   467
@wireprotocommand('heads', permission='pull')
11583
944c23762c3c protocol: add proto to method prototypes
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
   468
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
   469
    h = repo.heads()
37612
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   470
    return wireprototypes.bytesresponse(wireprototypes.encodelist(h) + '\n')
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   471
37779
379d54eae6eb wireproto: don't pass transportpolicy argument
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
   472
@wireprotocommand('hello', permission='pull')
11594
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
   473
def hello(repo, proto):
36221
62bca1c50e96 wireproto: improve docstring for "hello"
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36074
diff changeset
   474
    """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
   475
62bca1c50e96 wireproto: improve docstring for "hello"
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36074
diff changeset
   476
    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
   477
    server, in an RFC822-like format.
11594
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
   478
36221
62bca1c50e96 wireproto: improve docstring for "hello"
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36074
diff changeset
   479
    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
   480
    line of space separated tokens describing server abilities:
62bca1c50e96 wireproto: improve docstring for "hello"
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36074
diff changeset
   481
62bca1c50e96 wireproto: improve docstring for "hello"
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36074
diff changeset
   482
        capabilities: <token0> <token1> <token2>
62bca1c50e96 wireproto: improve docstring for "hello"
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36074
diff changeset
   483
    """
36074
2f7290555c96 wireproto: introduce type for raw byte responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36073
diff changeset
   484
    caps = capabilities(repo, proto).data
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   485
    return wireprototypes.bytesresponse('capabilities: %s\n' % caps)
11594
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
   486
37779
379d54eae6eb wireproto: don't pass transportpolicy argument
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
   487
@wireprotocommand('listkeys', 'namespace', permission='pull')
11583
944c23762c3c protocol: add proto to method prototypes
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
   488
def listkeys(repo, proto, namespace):
36529
33c6f8f0388d wireproto: sort response to listkeys
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36431
diff changeset
   489
    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
   490
    return wireprototypes.bytesresponse(pushkeymod.encodekeys(d))
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   491
37779
379d54eae6eb wireproto: don't pass transportpolicy argument
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
   492
@wireprotocommand('lookup', 'key', permission='pull')
11583
944c23762c3c protocol: add proto to method prototypes
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
   493
def lookup(repo, proto, key):
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   494
    try:
15925
f9fc46698352 wireproto: refuse to lookup secret csets
Matt Mackall <mpm@selenic.com>
parents: 15713
diff changeset
   495
        k = encoding.tolocal(key)
37353
ac666c5c2e0c wireproto: use repo.lookup() for lookup command
Martin von Zweigbergk <martinvonz@google.com>
parents: 37320
diff changeset
   496
        n = repo.lookup(k)
ac666c5c2e0c wireproto: use repo.lookup() for lookup command
Martin von Zweigbergk <martinvonz@google.com>
parents: 37320
diff changeset
   497
        r = hex(n)
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   498
        success = 1
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25493
diff changeset
   499
    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
   500
        r = stringutil.forcebytestr(inst)
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   501
        success = 0
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   502
    return wireprototypes.bytesresponse('%d %s\n' % (success, r))
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   503
37779
379d54eae6eb wireproto: don't pass transportpolicy argument
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
   504
@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
   505
def known(repo, proto, nodes, others):
37612
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   506
    v = ''.join(b and '1' or '0'
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   507
                for b in repo.known(wireprototypes.decodelist(nodes)))
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   508
    return wireprototypes.bytesresponse(v)
13723
e615765fdcc7 wireproto: add known([id]) function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13722
diff changeset
   509
37779
379d54eae6eb wireproto: don't pass transportpolicy argument
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
   510
@wireprotocommand('protocaps', 'caps', permission='pull')
37393
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
   511
def protocaps(repo, proto, caps):
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
   512
    if proto.name == wireprototypes.SSHV1:
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
   513
        proto._protocaps = set(caps.split(' '))
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
   514
    return wireprototypes.bytesresponse('OK')
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
   515
37779
379d54eae6eb wireproto: don't pass transportpolicy argument
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
   516
@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
   517
def pushkey(repo, proto, namespace, key, old, new):
13050
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
   518
    # compatibility with pre-1.8 clients which were accidentally
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
   519
    # 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
   520
    if len(new) == 20 and stringutil.escapestr(new) != new:
13050
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
   521
        # looks like it could be a binary node
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
   522
        try:
14064
e4bfb9c337f3 remove unused imports and variables
Alexander Solovyov <alexander@solovyov.net>
parents: 14048
diff changeset
   523
            new.decode('utf-8')
13050
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
   524
            new = encoding.tolocal(new) # but cleanly decodes as UTF-8
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
   525
        except UnicodeDecodeError:
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
   526
            pass # binary, leave unmodified
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
   527
    else:
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
   528
        new = encoding.tolocal(new) # normal path
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
   529
36066
2ad145fbde54 wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35982
diff changeset
   530
    with proto.mayberedirectstdio() as output:
35979
ae79cf6f9c82 wireproto: remove unnecessary exception trapping
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35860
diff changeset
   531
        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
   532
                         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
   533
36066
2ad145fbde54 wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35982
diff changeset
   534
    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
   535
    return wireprototypes.bytesresponse('%d\n%s' % (int(r), output))
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   536
37779
379d54eae6eb wireproto: don't pass transportpolicy argument
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
   537
@wireprotocommand('stream_out', permission='pull')
11585
5d907fbb9703 protocol: unify stream_out command
Matt Mackall <mpm@selenic.com>
parents: 11584
diff changeset
   538
def stream(repo, proto):
11627
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
   539
    '''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
   540
    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
   541
    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
   542
    '''
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   543
    return wireprototypes.streamreslegacy(
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   544
        streamclone.generatev1wireproto(repo))
11585
5d907fbb9703 protocol: unify stream_out command
Matt Mackall <mpm@selenic.com>
parents: 11584
diff changeset
   545
37779
379d54eae6eb wireproto: don't pass transportpolicy argument
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
   546
@wireprotocommand('unbundle', 'heads', permission='push')
11593
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
   547
def unbundle(repo, proto, heads):
37612
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   548
    their_heads = wireprototypes.decodelist(heads)
11593
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
   549
36067
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   550
    with proto.mayberedirectstdio() as output:
11593
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
   551
        try:
36067
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   552
            exchange.check_heads(repo, their_heads, 'preparing changes')
37414
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   553
            cleanup = lambda: None
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   554
            try:
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   555
                payload = proto.getpayload()
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   556
                if repo.ui.configbool('server', 'streamunbundle'):
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   557
                    def cleanup():
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   558
                        # Ensure that the full payload is consumed, so
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   559
                        # that the connection doesn't contain trailing garbage.
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   560
                        for p in payload:
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   561
                            pass
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   562
                    fp = util.chunkbuffer(payload)
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   563
                else:
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   564
                    # write bundle data to temporary file as it can be big
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   565
                    fp, tempname = None, None
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   566
                    def cleanup():
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   567
                        if fp:
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   568
                            fp.close()
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   569
                        if tempname:
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   570
                            os.unlink(tempname)
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   571
                    fd, tempname = tempfile.mkstemp(prefix='hg-unbundle-')
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   572
                    repo.ui.debug('redirecting incoming bundle to %s\n' %
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   573
                        tempname)
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   574
                    fp = os.fdopen(fd, pycompat.sysstr('wb+'))
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   575
                    r = 0
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   576
                    for p in payload:
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   577
                        fp.write(p)
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   578
                    fp.seek(0)
27246
b288fb2724bf wireproto: config options to disable bundle1
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27243
diff changeset
   579
36067
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   580
                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
   581
                if (isinstance(gen, changegroupmod.cg1unpacker)
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   582
                    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
   583
                    if proto.name == 'http-v1':
36067
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   584
                        # 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
   585
                        # 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
   586
                        # 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
   587
                        # the user.
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   588
                        return wireprototypes.ooberror(bundle2required)
36067
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   589
                    raise error.Abort(bundle2requiredmain,
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   590
                                      hint=bundle2requiredhint)
24796
61ff209fc01d bundle2: refactor error bundle creation for the wireprotocol
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24696
diff changeset
   591
36067
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   592
                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
   593
                                      proto.client())
36067
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   594
                if util.safehasattr(r, 'addpart'):
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   595
                    # 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
   596
                    # and should return a stream.
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   597
                    return wireprototypes.streamreslegacy(gen=r.getchunks())
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   598
                return wireprototypes.pushres(
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   599
                    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
   600
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   601
            finally:
37414
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   602
                cleanup()
36067
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   603
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   604
        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
   605
            # handle non-bundle2 case first
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   606
            if not getattr(exc, 'duringunbundle2', False):
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   607
                try:
25493
d8e7b0781ad7 bundle2: convey PushkeyFailed error over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25403
diff changeset
   608
                    raise
36067
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   609
                except error.Abort:
37119
d4a2e0d5d042 procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
   610
                    # 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
   611
                    # 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
   612
                    # 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
   613
                    # 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
   614
                    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
   615
                    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
   616
                        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
   617
                    procutil.stderr.flush()
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   618
                    return wireprototypes.pushres(
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   619
                        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
   620
                except error.PushRaced:
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   621
                    return wireprototypes.pusherr(
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   622
                        pycompat.bytestr(exc),
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   623
                        output.getvalue() if output else '')
36067
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   624
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   625
            bundler = bundle2.bundle20(repo.ui)
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   626
            for out in getattr(exc, '_bundle2salvagedoutput', ()):
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   627
                bundler.addpart(out)
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   628
            try:
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   629
                try:
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   630
                    raise
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   631
                except error.PushkeyFailed as exc:
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   632
                    # check client caps
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   633
                    remotecaps = getattr(exc, '_replycaps', None)
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   634
                    if (remotecaps is not None
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   635
                            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
   636
                        # 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
   637
                        raise
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   638
                    part = bundler.newpart('error:pushkey')
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   639
                    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
   640
                    if exc.namespace is not None:
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   641
                        part.addparam('namespace', exc.namespace,
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   642
                                      mandatory=False)
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   643
                    if exc.key is not None:
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   644
                        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
   645
                    if exc.new is not None:
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   646
                        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
   647
                    if exc.old is not None:
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   648
                        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
   649
                    if exc.ret is not None:
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   650
                        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
   651
            except error.BundleValueError as exc:
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   652
                errpart = bundler.newpart('error:unsupportedcontent')
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   653
                if exc.parttype is not None:
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   654
                    errpart.addparam('parttype', exc.parttype)
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   655
                if exc.params:
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   656
                    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
   657
            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
   658
                manargs = [('message', stringutil.forcebytestr(exc))]
36067
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   659
                advargs = []
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   660
                if exc.hint is not None:
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   661
                    advargs.append(('hint', exc.hint))
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   662
                bundler.addpart(bundle2.bundlepart('error:abort',
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   663
                                                   manargs, advargs))
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   664
            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
   665
                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
   666
                                [('message', stringutil.forcebytestr(exc))])
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   667
            return wireprototypes.streamreslegacy(gen=bundler.getchunks())