mercurial/wireprotoserver.py
author Arseniy Alekseyev <aalekseyev@janestreet.com>
Mon, 26 Jun 2023 11:21:43 +0100
branchstable
changeset 50720 bfbd84c57bda
parent 50481 45c7bada5200
child 51483 13c004b54cbe
permissions -rw-r--r--
dirstate-v2: actually fix the dirstate-v2 upgrade race It looks like the previous fix for the dirstate-v2 upgrade race didn't work. The problem is that it only recovers in case the size of the v1 `dirstate` file is smaller than the `v2` one, whereas in real life it's always larger. This commit changes the test to be more realistic, which reveals the crash, and changes the code to fix the crash.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
5598
d534ba1c4eb4 separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
     1
# Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
46819
d4ba4d51f85f contributor: change mentions of mpm to olivia
Raphaël Gomès <rgomes@octobus.net>
parents: 46404
diff changeset
     2
# Copyright 2005-2007 Olivia Mackall <olivia@selenic.com>
5598
d534ba1c4eb4 separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
     3
#
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 8109
diff changeset
     4
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9713
diff changeset
     5
# GNU General Public License version 2 or any later version.
5598
d534ba1c4eb4 separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
     6
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 20903
diff changeset
     7
36104
2ad145fbde54 wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36103
diff changeset
     8
import contextlib
30764
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
     9
import struct
36552
e7411fb7ba7f wireprotoserver: ability to run an SSH server until an event is set
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36403
diff changeset
    10
import threading
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 20903
diff changeset
    11
35899
1bf5263fe5cc wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35898
diff changeset
    12
from .i18n import _
35896
ef3a24a023ec wireprotoserver: rename hgweb.protocol to wireprotoserver (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35750
diff changeset
    13
from . import (
35899
1bf5263fe5cc wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35898
diff changeset
    14
    encoding,
34509
e21f274cccea hgweb: in protocol adapter, avoid control reaching end of non-void function
Augie Fackler <augie@google.com>
parents: 33842
diff changeset
    15
    error,
34742
5a9cad0dfddb hgweb: when unpacking args from request form, convert to bytes
Augie Fackler <augie@google.com>
parents: 34740
diff changeset
    16
    pycompat,
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 20903
diff changeset
    17
    util,
36111
cd6ab329c5c7 wireprototypes: move wire protocol response types to new module
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36110
diff changeset
    18
    wireprototypes,
37785
b4d85bc122bd wireproto: rename wireproto to wireprotov1server (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37783
diff changeset
    19
    wireprotov1server,
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 20903
diff changeset
    20
)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
    21
from .interfaces import util as interfaceutil
37123
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37064
diff changeset
    22
from .utils import (
42041
3e47d1ec9da5 util: extract compression code in `mercurial.utils.compression`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 41285
diff changeset
    23
    compression,
46404
71443f742886 wireprotoserver: convert ErrorResponse to bytes
Matt Harbison <matt_harbison@yahoo.com>
parents: 45837
diff changeset
    24
    stringutil,
37123
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37064
diff changeset
    25
)
35896
ef3a24a023ec wireprotoserver: rename hgweb.protocol to wireprotoserver (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35750
diff changeset
    26
28861
86db5cb55d46 pycompat: switch to util.stringio for py3 compat
timeless <timeless@mozdev.org>
parents: 28530
diff changeset
    27
stringio = util.stringio
5963
5be210afe1b8 hgweb: explicitly check if requested command exists
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5915
diff changeset
    28
28883
032c4c2f802a pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents: 28861
diff changeset
    29
urlerr = util.urlerr
032c4c2f802a pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents: 28861
diff changeset
    30
urlreq = util.urlreq
032c4c2f802a pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents: 28861
diff changeset
    31
35898
1b76a9e0a9de wireprotoserver: don't import symbol from hgweb.common
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35897
diff changeset
    32
HTTP_OK = 200
1b76a9e0a9de wireprotoserver: don't import symbol from hgweb.common
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35897
diff changeset
    33
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    34
HGTYPE = b'application/mercurial-0.1'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    35
HGTYPE2 = b'application/mercurial-0.2'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    36
HGERRTYPE = b'application/hg-error'
11595
368cd5325348 protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents: 11594
diff changeset
    37
36565
3cd245945ef3 wireprotoserver: move SSHV1 and SSHV2 constants to wireprototypes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36555
diff changeset
    38
SSHV1 = wireprototypes.SSHV1
36015
48a3a9283f09 sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35940
diff changeset
    39
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
    40
36852
14f70c44af6c wireprotoserver: access headers through parsed request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36821
diff changeset
    41
def decodevaluefromheaders(req, headerprefix):
34744
0a2ef612ad50 hgweb: fix decodevaluefromheaders to always return a bytes value
Augie Fackler <augie@google.com>
parents: 34743
diff changeset
    42
    """Decode a long value from multiple HTTP request headers.
0a2ef612ad50 hgweb: fix decodevaluefromheaders to always return a bytes value
Augie Fackler <augie@google.com>
parents: 34743
diff changeset
    43
0a2ef612ad50 hgweb: fix decodevaluefromheaders to always return a bytes value
Augie Fackler <augie@google.com>
parents: 34743
diff changeset
    44
    Returns the value as a bytes, not a str.
0a2ef612ad50 hgweb: fix decodevaluefromheaders to always return a bytes value
Augie Fackler <augie@google.com>
parents: 34743
diff changeset
    45
    """
30759
3f5f0c98cd18 httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30567
diff changeset
    46
    chunks = []
3f5f0c98cd18 httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30567
diff changeset
    47
    i = 1
3f5f0c98cd18 httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30567
diff changeset
    48
    while True:
36852
14f70c44af6c wireprotoserver: access headers through parsed request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36821
diff changeset
    49
        v = req.headers.get(b'%s-%d' % (headerprefix, i))
30759
3f5f0c98cd18 httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30567
diff changeset
    50
        if v is None:
3f5f0c98cd18 httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30567
diff changeset
    51
            break
34744
0a2ef612ad50 hgweb: fix decodevaluefromheaders to always return a bytes value
Augie Fackler <augie@google.com>
parents: 34743
diff changeset
    52
        chunks.append(pycompat.bytesurl(v))
30759
3f5f0c98cd18 httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30567
diff changeset
    53
        i += 1
3f5f0c98cd18 httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30567
diff changeset
    54
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    55
    return b''.join(chunks)
30759
3f5f0c98cd18 httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30567
diff changeset
    56
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
    57
37810
856f381ad74b interfaceutil: module to stub out zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37785
diff changeset
    58
@interfaceutil.implementer(wireprototypes.baseprotocolhandler)
49037
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48966
diff changeset
    59
class httpv1protocolhandler:
36873
a755fd3b7146 hgweb: expose URL scheme and REMOTE_* attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36868
diff changeset
    60
    def __init__(self, req, ui, checkperm):
36852
14f70c44af6c wireprotoserver: access headers through parsed request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36821
diff changeset
    61
        self._req = req
35906
d747cf39cf70 wireprotoserver: make attributes private
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35905
diff changeset
    62
        self._ui = ui
36809
66de4555cefd wireproto: formalize permissions checking as part of protocol interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36808
diff changeset
    63
        self._checkperm = checkperm
37393
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37296
diff changeset
    64
        self._protocaps = None
35913
29759c46aa1a wireprotoserver: make name part of protocol interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35912
diff changeset
    65
29759c46aa1a wireprotoserver: make name part of protocol interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35912
diff changeset
    66
    @property
29759c46aa1a wireprotoserver: make name part of protocol interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35912
diff changeset
    67
    def name(self):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    68
        return b'http-v1'
30567
b3a9ef3d30e8 protocol: declare transport protocol name
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30475
diff changeset
    69
11595
368cd5325348 protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents: 11594
diff changeset
    70
    def getargs(self, args):
14093
ce99d887585f httprepo: long arguments support (issue2126)
Steven Brown <StevenGBrown@gmail.com>
parents: 13721
diff changeset
    71
        knownargs = self._args()
11595
368cd5325348 protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents: 11594
diff changeset
    72
        data = {}
368cd5325348 protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents: 11594
diff changeset
    73
        keys = args.split()
368cd5325348 protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents: 11594
diff changeset
    74
        for k in keys:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    75
            if k == b'*':
11595
368cd5325348 protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents: 11594
diff changeset
    76
                star = {}
14093
ce99d887585f httprepo: long arguments support (issue2126)
Steven Brown <StevenGBrown@gmail.com>
parents: 13721
diff changeset
    77
                for key in knownargs.keys():
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    78
                    if key != b'cmd' and key not in keys:
14093
ce99d887585f httprepo: long arguments support (issue2126)
Steven Brown <StevenGBrown@gmail.com>
parents: 13721
diff changeset
    79
                        star[key] = knownargs[key][0]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    80
                data[b'*'] = star
11595
368cd5325348 protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents: 11594
diff changeset
    81
            else:
14093
ce99d887585f httprepo: long arguments support (issue2126)
Steven Brown <StevenGBrown@gmail.com>
parents: 13721
diff changeset
    82
                data[k] = knownargs[k][0]
11595
368cd5325348 protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents: 11594
diff changeset
    83
        return [data[k] for k in keys]
35903
49426bb4476c wireprotoserver: add some blank lines between methods
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35900
diff changeset
    84
14093
ce99d887585f httprepo: long arguments support (issue2126)
Steven Brown <StevenGBrown@gmail.com>
parents: 13721
diff changeset
    85
    def _args(self):
36868
ec0af9c59270 hgweb: use a multidict for holding query string parameters
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36867
diff changeset
    86
        args = self._req.qsparams.asdictoflists()
36852
14f70c44af6c wireprotoserver: access headers through parsed request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36821
diff changeset
    87
        postlen = int(self._req.headers.get(b'X-HgArgs-Post', 0))
28530
fd2acc5046f6 http: support sending hgargs via POST body instead of in GET or headers
Augie Fackler <augie@google.com>
parents: 27046
diff changeset
    88
        if postlen:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
    89
            args.update(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
    90
                urlreq.parseqs(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
    91
                    self._req.bodyfh.read(postlen), keep_blank_values=True
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
    92
                )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
    93
            )
28530
fd2acc5046f6 http: support sending hgargs via POST body instead of in GET or headers
Augie Fackler <augie@google.com>
parents: 27046
diff changeset
    94
            return args
30759
3f5f0c98cd18 httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30567
diff changeset
    95
36852
14f70c44af6c wireprotoserver: access headers through parsed request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36821
diff changeset
    96
        argvalue = decodevaluefromheaders(self._req, b'X-HgArg')
36115
a3d42d1865f1 wireprotoserver: define and use parse_qs from urllib
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36113
diff changeset
    97
        args.update(urlreq.parseqs(argvalue, keep_blank_values=True))
14093
ce99d887585f httprepo: long arguments support (issue2126)
Steven Brown <StevenGBrown@gmail.com>
parents: 13721
diff changeset
    98
        return args
35903
49426bb4476c wireprotoserver: add some blank lines between methods
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35900
diff changeset
    99
37393
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37296
diff changeset
   100
    def getprotocaps(self):
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37296
diff changeset
   101
        if self._protocaps is None:
37590
9170df9106a8 wireprotoserver: headers are bytes for us internally, use bytes
Augie Fackler <augie@google.com>
parents: 37557
diff changeset
   102
            value = decodevaluefromheaders(self._req, b'X-HgProto')
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   103
            self._protocaps = set(value.split(b' '))
37393
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37296
diff changeset
   104
        return self._protocaps
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37296
diff changeset
   105
37414
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37393
diff changeset
   106
    def getpayload(self):
36853
ed0456fde625 hgweb: handle CONTENT_LENGTH
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36852
diff changeset
   107
        # Existing clients *always* send Content-Length.
ed0456fde625 hgweb: handle CONTENT_LENGTH
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36852
diff changeset
   108
        length = int(self._req.headers[b'Content-Length'])
ed0456fde625 hgweb: handle CONTENT_LENGTH
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36852
diff changeset
   109
33842
3c91cc0c5fde httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents: 33228
diff changeset
   110
        # If httppostargs is used, we need to read Content-Length
3c91cc0c5fde httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents: 33228
diff changeset
   111
        # minus the amount that was consumed by args.
36852
14f70c44af6c wireprotoserver: access headers through parsed request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36821
diff changeset
   112
        length -= int(self._req.headers.get(b'X-HgArgs-Post', 0))
37414
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37393
diff changeset
   113
        return util.filechunkiter(self._req.bodyfh, limit=length)
35903
49426bb4476c wireprotoserver: add some blank lines between methods
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35900
diff changeset
   114
36104
2ad145fbde54 wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36103
diff changeset
   115
    @contextlib.contextmanager
2ad145fbde54 wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36103
diff changeset
   116
    def mayberedirectstdio(self):
2ad145fbde54 wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36103
diff changeset
   117
        oldout = self._ui.fout
2ad145fbde54 wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36103
diff changeset
   118
        olderr = self._ui.ferr
2ad145fbde54 wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36103
diff changeset
   119
2ad145fbde54 wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36103
diff changeset
   120
        out = util.stringio()
2ad145fbde54 wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36103
diff changeset
   121
2ad145fbde54 wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36103
diff changeset
   122
        try:
2ad145fbde54 wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36103
diff changeset
   123
            self._ui.fout = out
2ad145fbde54 wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36103
diff changeset
   124
            self._ui.ferr = out
2ad145fbde54 wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36103
diff changeset
   125
            yield out
2ad145fbde54 wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36103
diff changeset
   126
        finally:
2ad145fbde54 wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36103
diff changeset
   127
            self._ui.fout = oldout
2ad145fbde54 wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36103
diff changeset
   128
            self._ui.ferr = olderr
2ad145fbde54 wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36103
diff changeset
   129
36107
957e773614d0 wireprotoserver: rename _client to client (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36106
diff changeset
   130
    def client(self):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   131
        return b'remote:%s:%s:%s' % (
36873
a755fd3b7146 hgweb: expose URL scheme and REMOTE_* attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36868
diff changeset
   132
            self._req.urlscheme,
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   133
            urlreq.quote(self._req.remotehost or b''),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   134
            urlreq.quote(self._req.remoteuser or b''),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
   135
        )
11595
368cd5325348 protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents: 11594
diff changeset
   136
36642
6e585bca962e wireproto: add transport specific capabilities in the transport
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36639
diff changeset
   137
    def addcapabilities(self, repo, caps):
37056
cd0ca979a8b8 wireproto: nominally don't expose "batch" to version 2 wire transports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
   138
        caps.append(b'batch')
cd0ca979a8b8 wireproto: nominally don't expose "batch" to version 2 wire transports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
   139
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
   140
        caps.append(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   141
            b'httpheader=%d' % repo.ui.configint(b'server', b'maxhttpheaderlen')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
   142
        )
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   143
        if repo.ui.configbool(b'experimental', b'httppostargs'):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   144
            caps.append(b'httppostargs')
36642
6e585bca962e wireproto: add transport specific capabilities in the transport
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36639
diff changeset
   145
6e585bca962e wireproto: add transport specific capabilities in the transport
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36639
diff changeset
   146
        # FUTURE advertise 0.2rx once support is implemented
6e585bca962e wireproto: add transport specific capabilities in the transport
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36639
diff changeset
   147
        # FUTURE advertise minrx and mintx after consulting config option
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   148
        caps.append(b'httpmediatype=0.1rx,0.1tx,0.2tx')
36642
6e585bca962e wireproto: add transport specific capabilities in the transport
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36639
diff changeset
   149
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
   150
        compengines = wireprototypes.supportedcompengines(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
   151
            repo.ui, compression.SERVERROLE
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
   152
        )
36642
6e585bca962e wireproto: add transport specific capabilities in the transport
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36639
diff changeset
   153
        if compengines:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   154
            comptypes = b','.join(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
   155
                urlreq.quote(e.wireprotosupport().name) for e in compengines
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
   156
            )
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   157
            caps.append(b'compression=%s' % comptypes)
36642
6e585bca962e wireproto: add transport specific capabilities in the transport
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36639
diff changeset
   158
6e585bca962e wireproto: add transport specific capabilities in the transport
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36639
diff changeset
   159
        return caps
6e585bca962e wireproto: add transport specific capabilities in the transport
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36639
diff changeset
   160
36809
66de4555cefd wireproto: formalize permissions checking as part of protocol interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36808
diff changeset
   161
    def checkperm(self, perm):
66de4555cefd wireproto: formalize permissions checking as part of protocol interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36808
diff changeset
   162
        return self._checkperm(perm)
66de4555cefd wireproto: formalize permissions checking as part of protocol interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36808
diff changeset
   163
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
   164
36269
72812ad205d1 wireprotoserver: return to using iscmd() method
Augie Fackler <augie@google.com>
parents: 36261
diff changeset
   165
# This method exists mostly so that extensions like remotefilelog can
72812ad205d1 wireprotoserver: return to using iscmd() method
Augie Fackler <augie@google.com>
parents: 36261
diff changeset
   166
# disable a kludgey legacy method only over http. As of early 2018,
72812ad205d1 wireprotoserver: return to using iscmd() method
Augie Fackler <augie@google.com>
parents: 36261
diff changeset
   167
# there are no other known users, so with any luck we can discard this
72812ad205d1 wireprotoserver: return to using iscmd() method
Augie Fackler <augie@google.com>
parents: 36261
diff changeset
   168
# hook if remotefilelog becomes a first-party extension.
11595
368cd5325348 protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents: 11594
diff changeset
   169
def iscmd(cmd):
37785
b4d85bc122bd wireproto: rename wireproto to wireprotov1server (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37783
diff changeset
   170
    return cmd in wireprotov1server.commands
11595
368cd5325348 protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents: 11594
diff changeset
   171
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
   172
36883
02bea04b4c54 hgweb: transition permissions hooks to modern request type (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36873
diff changeset
   173
def handlewsgirequest(rctx, req, res, checkperm):
36820
158d4ecc03c8 wireprotoserver: move all wire protocol handling logic out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36818
diff changeset
   174
    """Possibly process a wire protocol request.
36023
cdc93fe1da77 wireprotoserver: move protocol parsing and dispatch out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36021
diff changeset
   175
36820
158d4ecc03c8 wireprotoserver: move all wire protocol handling logic out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36818
diff changeset
   176
    If the current request is a wire protocol request, the request is
158d4ecc03c8 wireprotoserver: move all wire protocol handling logic out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36818
diff changeset
   177
    processed by this function.
36023
cdc93fe1da77 wireprotoserver: move protocol parsing and dispatch out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36021
diff changeset
   178
36818
886fba199022 hgweb: only recognize wire protocol commands from query string (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36812
diff changeset
   179
    ``req`` is a ``parsedrequest`` instance.
36867
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   180
    ``res`` is a ``wsgiresponse`` instance.
36820
158d4ecc03c8 wireprotoserver: move all wire protocol handling logic out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36818
diff changeset
   181
36867
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   182
    Returns a bool indicating if the request was serviced. If set, the caller
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   183
    should stop processing the request, as a response has already been issued.
36023
cdc93fe1da77 wireprotoserver: move protocol parsing and dispatch out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36021
diff changeset
   184
    """
36820
158d4ecc03c8 wireprotoserver: move all wire protocol handling logic out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36818
diff changeset
   185
    # Avoid cycle involving hg module.
158d4ecc03c8 wireprotoserver: move all wire protocol handling logic out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36818
diff changeset
   186
    from .hgweb import common as hgwebcommon
158d4ecc03c8 wireprotoserver: move all wire protocol handling logic out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36818
diff changeset
   187
36809
66de4555cefd wireproto: formalize permissions checking as part of protocol interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36808
diff changeset
   188
    repo = rctx.repo
66de4555cefd wireproto: formalize permissions checking as part of protocol interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36808
diff changeset
   189
36023
cdc93fe1da77 wireprotoserver: move protocol parsing and dispatch out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36021
diff changeset
   190
    # HTTP version 1 wire protocol requests are denoted by a "cmd" query
cdc93fe1da77 wireprotoserver: move protocol parsing and dispatch out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36021
diff changeset
   191
    # string parameter. If it isn't present, this isn't a wire protocol
cdc93fe1da77 wireprotoserver: move protocol parsing and dispatch out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36021
diff changeset
   192
    # request.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   193
    if b'cmd' not in req.qsparams:
36867
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   194
        return False
36023
cdc93fe1da77 wireprotoserver: move protocol parsing and dispatch out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36021
diff changeset
   195
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   196
    cmd = req.qsparams[b'cmd']
36023
cdc93fe1da77 wireprotoserver: move protocol parsing and dispatch out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36021
diff changeset
   197
cdc93fe1da77 wireprotoserver: move protocol parsing and dispatch out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36021
diff changeset
   198
    # The "cmd" request parameter is used by both the wire protocol and hgweb.
cdc93fe1da77 wireprotoserver: move protocol parsing and dispatch out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36021
diff changeset
   199
    # While not all wire protocol commands are available for all transports,
cdc93fe1da77 wireprotoserver: move protocol parsing and dispatch out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36021
diff changeset
   200
    # if we see a "cmd" value that resembles a known wire protocol command, we
cdc93fe1da77 wireprotoserver: move protocol parsing and dispatch out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36021
diff changeset
   201
    # route it to a protocol handler. This is better than routing possible
cdc93fe1da77 wireprotoserver: move protocol parsing and dispatch out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36021
diff changeset
   202
    # wire protocol requests to hgweb because it prevents hgweb from using
cdc93fe1da77 wireprotoserver: move protocol parsing and dispatch out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36021
diff changeset
   203
    # known wire protocol commands and it is less confusing for machine
cdc93fe1da77 wireprotoserver: move protocol parsing and dispatch out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36021
diff changeset
   204
    # clients.
36269
72812ad205d1 wireprotoserver: return to using iscmd() method
Augie Fackler <augie@google.com>
parents: 36261
diff changeset
   205
    if not iscmd(cmd):
36867
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   206
        return False
36820
158d4ecc03c8 wireprotoserver: move all wire protocol handling logic out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36818
diff changeset
   207
158d4ecc03c8 wireprotoserver: move all wire protocol handling logic out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36818
diff changeset
   208
    # The "cmd" query string argument is only valid on the root path of the
158d4ecc03c8 wireprotoserver: move all wire protocol handling logic out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36818
diff changeset
   209
    # repo. e.g. ``/?cmd=foo``, ``/repo?cmd=foo``. URL paths within the repo
158d4ecc03c8 wireprotoserver: move all wire protocol handling logic out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36818
diff changeset
   210
    # like ``/blah?cmd=foo`` are not allowed. So don't recognize the request
158d4ecc03c8 wireprotoserver: move all wire protocol handling logic out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36818
diff changeset
   211
    # in this case. We send an HTTP 404 for backwards compatibility reasons.
158d4ecc03c8 wireprotoserver: move all wire protocol handling logic out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36818
diff changeset
   212
    if req.dispatchpath:
36867
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   213
        res.status = hgwebcommon.statusmessage(404)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   214
        res.headers[b'Content-Type'] = HGTYPE
36867
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   215
        # TODO This is not a good response to issue for this request. This
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   216
        # is mostly for BC for now.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   217
        res.setbodybytes(b'0\n%s\n' % b'Not Found')
36867
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   218
        return True
36023
cdc93fe1da77 wireprotoserver: move protocol parsing and dispatch out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36021
diff changeset
   219
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
   220
    proto = httpv1protocolhandler(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
   221
        req, repo.ui, lambda perm: checkperm(rctx, req, perm)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
   222
    )
30764
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   223
36820
158d4ecc03c8 wireprotoserver: move all wire protocol handling logic out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36818
diff changeset
   224
    # The permissions checker should be the only thing that can raise an
158d4ecc03c8 wireprotoserver: move all wire protocol handling logic out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36818
diff changeset
   225
    # ErrorResponse. It is kind of a layer violation to catch an hgweb
158d4ecc03c8 wireprotoserver: move all wire protocol handling logic out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36818
diff changeset
   226
    # exception here. So consider refactoring into a exception type that
158d4ecc03c8 wireprotoserver: move all wire protocol handling logic out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36818
diff changeset
   227
    # is associated with the wire protocol.
158d4ecc03c8 wireprotoserver: move all wire protocol handling logic out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36818
diff changeset
   228
    try:
36873
a755fd3b7146 hgweb: expose URL scheme and REMOTE_* attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36868
diff changeset
   229
        _callhttp(repo, req, res, proto, cmd)
36820
158d4ecc03c8 wireprotoserver: move all wire protocol handling logic out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36818
diff changeset
   230
    except hgwebcommon.ErrorResponse as e:
36867
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   231
        for k, v in e.headers:
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   232
            res.headers[k] = v
46404
71443f742886 wireprotoserver: convert ErrorResponse to bytes
Matt Harbison <matt_harbison@yahoo.com>
parents: 45837
diff changeset
   233
        res.status = hgwebcommon.statusmessage(
71443f742886 wireprotoserver: convert ErrorResponse to bytes
Matt Harbison <matt_harbison@yahoo.com>
parents: 45837
diff changeset
   234
            e.code, stringutil.forcebytestr(e)
71443f742886 wireprotoserver: convert ErrorResponse to bytes
Matt Harbison <matt_harbison@yahoo.com>
parents: 45837
diff changeset
   235
        )
36867
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   236
        # TODO This response body assumes the failed command was
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   237
        # "unbundle." That assumption is not always valid.
46404
71443f742886 wireprotoserver: convert ErrorResponse to bytes
Matt Harbison <matt_harbison@yahoo.com>
parents: 45837
diff changeset
   238
        res.setbodybytes(b'0\n%s\n' % stringutil.forcebytestr(e))
36820
158d4ecc03c8 wireprotoserver: move all wire protocol handling logic out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36818
diff changeset
   239
36867
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   240
    return True
36023
cdc93fe1da77 wireprotoserver: move protocol parsing and dispatch out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36021
diff changeset
   241
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
   242
37393
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37296
diff changeset
   243
def _httpresponsetype(ui, proto, prefer_uncompressed):
36110
341c886e411e wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36109
diff changeset
   244
    """Determine the appropriate response type and compression settings.
341c886e411e wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36109
diff changeset
   245
341c886e411e wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36109
diff changeset
   246
    Returns a tuple of (mediatype, compengine, engineopts).
341c886e411e wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36109
diff changeset
   247
    """
341c886e411e wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36109
diff changeset
   248
    # Determine the response media type and compression engine based
341c886e411e wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36109
diff changeset
   249
    # on the request parameters.
341c886e411e wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36109
diff changeset
   250
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   251
    if b'0.2' in proto.getprotocaps():
36110
341c886e411e wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36109
diff changeset
   252
        # All clients are expected to support uncompressed data.
341c886e411e wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36109
diff changeset
   253
        if prefer_uncompressed:
42041
3e47d1ec9da5 util: extract compression code in `mercurial.utils.compression`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 41285
diff changeset
   254
            return HGTYPE2, compression._noopengine(), {}
36110
341c886e411e wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36109
diff changeset
   255
341c886e411e wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36109
diff changeset
   256
        # Now find an agreed upon compression format.
37785
b4d85bc122bd wireproto: rename wireproto to wireprotov1server (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37783
diff changeset
   257
        compformats = wireprotov1server.clientcompressionsupport(proto)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
   258
        for engine in wireprototypes.supportedcompengines(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
   259
            ui, compression.SERVERROLE
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
   260
        ):
36110
341c886e411e wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36109
diff changeset
   261
            if engine.wireprotosupport().name in compformats:
341c886e411e wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36109
diff changeset
   262
                opts = {}
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   263
                level = ui.configint(b'server', b'%slevel' % engine.name())
36110
341c886e411e wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36109
diff changeset
   264
                if level is not None:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   265
                    opts[b'level'] = level
36110
341c886e411e wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36109
diff changeset
   266
341c886e411e wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36109
diff changeset
   267
                return HGTYPE2, engine, opts
341c886e411e wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36109
diff changeset
   268
341c886e411e wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36109
diff changeset
   269
        # No mutually supported compression format. Fall back to the
341c886e411e wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36109
diff changeset
   270
        # legacy protocol.
341c886e411e wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36109
diff changeset
   271
341c886e411e wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36109
diff changeset
   272
    # Don't allow untrusted settings because disabling compression or
341c886e411e wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36109
diff changeset
   273
    # setting a very high compression level could lead to flooding
341c886e411e wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36109
diff changeset
   274
    # the server's network or CPU.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   275
    opts = {b'level': ui.configint(b'server', b'zliblevel')}
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   276
    return HGTYPE, util.compengines[b'zlib'], opts
36110
341c886e411e wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36109
diff changeset
   277
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
   278
36873
a755fd3b7146 hgweb: expose URL scheme and REMOTE_* attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36868
diff changeset
   279
def _callhttp(repo, req, res, proto, cmd):
36867
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   280
    # Avoid cycle involving hg module.
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   281
    from .hgweb import common as hgwebcommon
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   282
35750
a39a9df7ecca wireproto: split streamres into legacy and modern case
Joerg Sonnenberger <joerg@bec.de>
parents: 35705
diff changeset
   283
    def genversion2(gen, engine, engineopts):
30764
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   284
        # application/mercurial-0.2 always sends a payload header
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   285
        # identifying the compression engine.
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   286
        name = engine.wireprotosupport().name
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   287
        assert 0 < len(name) < 256
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   288
        yield struct.pack(b'B', len(name))
30764
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   289
        yield name
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   290
35750
a39a9df7ecca wireproto: split streamres into legacy and modern case
Joerg Sonnenberger <joerg@bec.de>
parents: 35705
diff changeset
   291
        for chunk in gen:
a39a9df7ecca wireproto: split streamres into legacy and modern case
Joerg Sonnenberger <joerg@bec.de>
parents: 35705
diff changeset
   292
            yield chunk
30764
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   293
36867
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   294
    def setresponse(code, contenttype, bodybytes=None, bodygen=None):
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   295
        if code == HTTP_OK:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   296
            res.status = b'200 Script output follows'
36867
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   297
        else:
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   298
            res.status = hgwebcommon.statusmessage(code)
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   299
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   300
        res.headers[b'Content-Type'] = contenttype
36867
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   301
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   302
        if bodybytes is not None:
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   303
            res.setbodybytes(bodybytes)
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   304
        if bodygen is not None:
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   305
            res.setbodygen(bodygen)
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   306
37785
b4d85bc122bd wireproto: rename wireproto to wireprotov1server (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37783
diff changeset
   307
    if not wireprotov1server.commands.commandavailable(cmd, proto):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
   308
        setresponse(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
   309
            HTTP_OK,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
   310
            HGERRTYPE,
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   311
            _(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   312
                b'requested wire protocol command is not available over '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   313
                b'HTTP'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   314
            ),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
   315
        )
36867
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   316
        return
36021
5a56bf4180ad wireproto: function for testing if wire protocol command is available
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36015
diff changeset
   317
37785
b4d85bc122bd wireproto: rename wireproto to wireprotov1server (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37783
diff changeset
   318
    proto.checkperm(wireprotov1server.commands[cmd].permission)
36807
c638a13093cf wireprotoserver: check permissions in main dispatch function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36806
diff changeset
   319
50477
3b199593fedd hidden: add support to explicitly access hidden changesets via HTTP
Manuel Jacob <me@manueljacob.de>
parents: 49292
diff changeset
   320
    accesshidden = hgwebcommon.hashiddenaccess(repo, req)
3b199593fedd hidden: add support to explicitly access hidden changesets via HTTP
Manuel Jacob <me@manueljacob.de>
parents: 49292
diff changeset
   321
    rsp = wireprotov1server.dispatch(repo, proto, cmd, accesshidden)
36806
7574c8173d5e wireprotoserver: check if command available before calling it
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36768
diff changeset
   322
34510
c23fa3103925 hgweb: in protocol adapter, look for bytes instances, not str
Augie Fackler <augie@google.com>
parents: 34509
diff changeset
   323
    if isinstance(rsp, bytes):
36867
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   324
        setresponse(HTTP_OK, HGTYPE, bodybytes=rsp)
36112
2f7290555c96 wireproto: introduce type for raw byte responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36111
diff changeset
   325
    elif isinstance(rsp, wireprototypes.bytesresponse):
36867
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   326
        setresponse(HTTP_OK, HGTYPE, bodybytes=rsp.data)
36111
cd6ab329c5c7 wireprototypes: move wire protocol response types to new module
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36110
diff changeset
   327
    elif isinstance(rsp, wireprototypes.streamreslegacy):
36867
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   328
        setresponse(HTTP_OK, HGTYPE, bodygen=rsp.gen)
36111
cd6ab329c5c7 wireprototypes: move wire protocol response types to new module
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36110
diff changeset
   329
    elif isinstance(rsp, wireprototypes.streamres):
35705
8cdb671dbd0b wireproto: drop support for reader interface from streamres (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34744
diff changeset
   330
        gen = rsp.gen
30475
2add671bf55b wireproto: perform chunking and compression at protocol layer (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30376
diff changeset
   331
30764
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   332
        # This code for compression should not be streamres specific. It
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   333
        # is here because we only compress streamres at the moment.
36110
341c886e411e wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36109
diff changeset
   334
        mediatype, engine, engineopts = _httpresponsetype(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
   335
            repo.ui, proto, rsp.prefer_uncompressed
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
   336
        )
35750
a39a9df7ecca wireproto: split streamres into legacy and modern case
Joerg Sonnenberger <joerg@bec.de>
parents: 35705
diff changeset
   337
        gen = engine.compressstream(gen, engineopts)
30475
2add671bf55b wireproto: perform chunking and compression at protocol layer (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30376
diff changeset
   338
35750
a39a9df7ecca wireproto: split streamres into legacy and modern case
Joerg Sonnenberger <joerg@bec.de>
parents: 35705
diff changeset
   339
        if mediatype == HGTYPE2:
a39a9df7ecca wireproto: split streamres into legacy and modern case
Joerg Sonnenberger <joerg@bec.de>
parents: 35705
diff changeset
   340
            gen = genversion2(gen, engine, engineopts)
30764
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   341
36867
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   342
        setresponse(HTTP_OK, mediatype, bodygen=gen)
36111
cd6ab329c5c7 wireprototypes: move wire protocol response types to new module
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36110
diff changeset
   343
    elif isinstance(rsp, wireprototypes.pushres):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   344
        rsp = b'%d\n%s' % (rsp.res, rsp.output)
36867
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   345
        setresponse(HTTP_OK, HGTYPE, bodybytes=rsp)
36111
cd6ab329c5c7 wireprototypes: move wire protocol response types to new module
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36110
diff changeset
   346
    elif isinstance(rsp, wireprototypes.pusherr):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   347
        rsp = b'0\n%s\n' % rsp.res
36867
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   348
        res.drain = True
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   349
        setresponse(HTTP_OK, HGTYPE, bodybytes=rsp)
36111
cd6ab329c5c7 wireprototypes: move wire protocol response types to new module
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36110
diff changeset
   350
    elif isinstance(rsp, wireprototypes.ooberror):
36867
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   351
        setresponse(HTTP_OK, HGERRTYPE, bodybytes=rsp.message)
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   352
    else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   353
        raise error.ProgrammingError(b'hgweb.protocol internal failure', rsp)
36025
98a00aa0288d wireprotoserver: move error response handling out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36023
diff changeset
   354
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
   355
36102
5767664d39a5 wireprotoserver: extract SSH response handling functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36027
diff changeset
   356
def _sshv1respondbytes(fout, value):
5767664d39a5 wireprotoserver: extract SSH response handling functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36027
diff changeset
   357
    """Send a bytes response for protocol version 1."""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   358
    fout.write(b'%d\n' % len(value))
36102
5767664d39a5 wireprotoserver: extract SSH response handling functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36027
diff changeset
   359
    fout.write(value)
5767664d39a5 wireprotoserver: extract SSH response handling functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36027
diff changeset
   360
    fout.flush()
5767664d39a5 wireprotoserver: extract SSH response handling functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36027
diff changeset
   361
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
   362
36102
5767664d39a5 wireprotoserver: extract SSH response handling functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36027
diff changeset
   363
def _sshv1respondstream(fout, source):
5767664d39a5 wireprotoserver: extract SSH response handling functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36027
diff changeset
   364
    write = fout.write
5767664d39a5 wireprotoserver: extract SSH response handling functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36027
diff changeset
   365
    for chunk in source.gen:
5767664d39a5 wireprotoserver: extract SSH response handling functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36027
diff changeset
   366
        write(chunk)
5767664d39a5 wireprotoserver: extract SSH response handling functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36027
diff changeset
   367
    fout.flush()
5767664d39a5 wireprotoserver: extract SSH response handling functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36027
diff changeset
   368
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
   369
36102
5767664d39a5 wireprotoserver: extract SSH response handling functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36027
diff changeset
   370
def _sshv1respondooberror(fout, ferr, rsp):
5767664d39a5 wireprotoserver: extract SSH response handling functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36027
diff changeset
   371
    ferr.write(b'%s\n-\n' % rsp)
5767664d39a5 wireprotoserver: extract SSH response handling functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36027
diff changeset
   372
    ferr.flush()
5767664d39a5 wireprotoserver: extract SSH response handling functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36027
diff changeset
   373
    fout.write(b'\n')
5767664d39a5 wireprotoserver: extract SSH response handling functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36027
diff changeset
   374
    fout.flush()
5767664d39a5 wireprotoserver: extract SSH response handling functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36027
diff changeset
   375
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
   376
37810
856f381ad74b interfaceutil: module to stub out zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37785
diff changeset
   377
@interfaceutil.implementer(wireprototypes.baseprotocolhandler)
49037
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48966
diff changeset
   378
class sshv1protocolhandler:
36103
bf676267f64f wireprotoserver: split ssh protocol handler and server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36102
diff changeset
   379
    """Handler for requests services via version 1 of SSH protocol."""
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
   380
36103
bf676267f64f wireprotoserver: split ssh protocol handler and server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36102
diff changeset
   381
    def __init__(self, ui, fin, fout):
35910
f1efc0caeab7 wireprotoserver: make some instance attributes private
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35909
diff changeset
   382
        self._ui = ui
36103
bf676267f64f wireprotoserver: split ssh protocol handler and server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36102
diff changeset
   383
        self._fin = fin
bf676267f64f wireprotoserver: split ssh protocol handler and server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36102
diff changeset
   384
        self._fout = fout
37393
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37296
diff changeset
   385
        self._protocaps = set()
35899
1bf5263fe5cc wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35898
diff changeset
   386
35913
29759c46aa1a wireprotoserver: make name part of protocol interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35912
diff changeset
   387
    @property
29759c46aa1a wireprotoserver: make name part of protocol interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35912
diff changeset
   388
    def name(self):
36565
3cd245945ef3 wireprotoserver: move SSHV1 and SSHV2 constants to wireprototypes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36555
diff changeset
   389
        return wireprototypes.SSHV1
35913
29759c46aa1a wireprotoserver: make name part of protocol interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35912
diff changeset
   390
35899
1bf5263fe5cc wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35898
diff changeset
   391
    def getargs(self, args):
1bf5263fe5cc wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35898
diff changeset
   392
        data = {}
1bf5263fe5cc wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35898
diff changeset
   393
        keys = args.split()
49292
d44e3c45f0e4 py3: replace `pycompat.xrange` by `range`
Manuel Jacob <me@manueljacob.de>
parents: 49037
diff changeset
   394
        for n in range(len(keys)):
35910
f1efc0caeab7 wireprotoserver: make some instance attributes private
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35909
diff changeset
   395
            argline = self._fin.readline()[:-1]
35899
1bf5263fe5cc wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35898
diff changeset
   396
            arg, l = argline.split()
1bf5263fe5cc wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35898
diff changeset
   397
            if arg not in keys:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   398
                raise error.Abort(_(b"unexpected parameter %r") % arg)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   399
            if arg == b'*':
35899
1bf5263fe5cc wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35898
diff changeset
   400
                star = {}
49292
d44e3c45f0e4 py3: replace `pycompat.xrange` by `range`
Manuel Jacob <me@manueljacob.de>
parents: 49037
diff changeset
   401
                for k in range(int(l)):
35910
f1efc0caeab7 wireprotoserver: make some instance attributes private
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35909
diff changeset
   402
                    argline = self._fin.readline()[:-1]
35899
1bf5263fe5cc wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35898
diff changeset
   403
                    arg, l = argline.split()
35910
f1efc0caeab7 wireprotoserver: make some instance attributes private
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35909
diff changeset
   404
                    val = self._fin.read(int(l))
35899
1bf5263fe5cc wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35898
diff changeset
   405
                    star[arg] = val
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   406
                data[b'*'] = star
35899
1bf5263fe5cc wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35898
diff changeset
   407
            else:
35910
f1efc0caeab7 wireprotoserver: make some instance attributes private
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35909
diff changeset
   408
                val = self._fin.read(int(l))
35899
1bf5263fe5cc wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35898
diff changeset
   409
                data[arg] = val
1bf5263fe5cc wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35898
diff changeset
   410
        return [data[k] for k in keys]
1bf5263fe5cc wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35898
diff changeset
   411
37393
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37296
diff changeset
   412
    def getprotocaps(self):
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37296
diff changeset
   413
        return self._protocaps
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37296
diff changeset
   414
37414
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37393
diff changeset
   415
    def getpayload(self):
36403
b8d0761a85c7 wireproto: document the wonky push protocol for SSH
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36402
diff changeset
   416
        # We initially send an empty response. This tells the client it is
b8d0761a85c7 wireproto: document the wonky push protocol for SSH
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36402
diff changeset
   417
        # OK to start sending data. If a client sees any other response, it
b8d0761a85c7 wireproto: document the wonky push protocol for SSH
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36402
diff changeset
   418
        # interprets it as an error.
b8d0761a85c7 wireproto: document the wonky push protocol for SSH
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36402
diff changeset
   419
        _sshv1respondbytes(self._fout, b'')
b8d0761a85c7 wireproto: document the wonky push protocol for SSH
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36402
diff changeset
   420
36108
90ca4986616c wireprotoserver: rename getfile() to forwardpayload() (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36107
diff changeset
   421
        # The file is in the form:
90ca4986616c wireprotoserver: rename getfile() to forwardpayload() (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36107
diff changeset
   422
        #
90ca4986616c wireprotoserver: rename getfile() to forwardpayload() (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36107
diff changeset
   423
        # <chunk size>\n<chunk>
90ca4986616c wireprotoserver: rename getfile() to forwardpayload() (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36107
diff changeset
   424
        # ...
90ca4986616c wireprotoserver: rename getfile() to forwardpayload() (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36107
diff changeset
   425
        # 0\n
35910
f1efc0caeab7 wireprotoserver: make some instance attributes private
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35909
diff changeset
   426
        count = int(self._fin.readline())
35899
1bf5263fe5cc wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35898
diff changeset
   427
        while count:
37414
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37393
diff changeset
   428
            yield self._fin.read(count)
35910
f1efc0caeab7 wireprotoserver: make some instance attributes private
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35909
diff changeset
   429
            count = int(self._fin.readline())
35899
1bf5263fe5cc wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35898
diff changeset
   430
36104
2ad145fbde54 wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36103
diff changeset
   431
    @contextlib.contextmanager
2ad145fbde54 wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36103
diff changeset
   432
    def mayberedirectstdio(self):
2ad145fbde54 wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36103
diff changeset
   433
        yield None
2ad145fbde54 wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36103
diff changeset
   434
36107
957e773614d0 wireprotoserver: rename _client to client (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36106
diff changeset
   435
    def client(self):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   436
        client = encoding.environ.get(b'SSH_CLIENT', b'').split(b' ', 1)[0]
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   437
        return b'remote:ssh:' + client
36103
bf676267f64f wireprotoserver: split ssh protocol handler and server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36102
diff changeset
   438
36642
6e585bca962e wireproto: add transport specific capabilities in the transport
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36639
diff changeset
   439
    def addcapabilities(self, repo, caps):
37393
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37296
diff changeset
   440
        if self.name == wireprototypes.SSHV1:
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37296
diff changeset
   441
            caps.append(b'protocaps')
37056
cd0ca979a8b8 wireproto: nominally don't expose "batch" to version 2 wire transports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
   442
        caps.append(b'batch')
36642
6e585bca962e wireproto: add transport specific capabilities in the transport
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36639
diff changeset
   443
        return caps
6e585bca962e wireproto: add transport specific capabilities in the transport
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36639
diff changeset
   444
36809
66de4555cefd wireproto: formalize permissions checking as part of protocol interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36808
diff changeset
   445
    def checkperm(self, perm):
66de4555cefd wireproto: formalize permissions checking as part of protocol interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36808
diff changeset
   446
        pass
66de4555cefd wireproto: formalize permissions checking as part of protocol interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36808
diff changeset
   447
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
   448
50481
45c7bada5200 hidden: add support to explicitly access hidden changesets with SSH peers
Manuel Jacob <me@manueljacob.de>
parents: 50477
diff changeset
   449
def _runsshserver(ui, repo, fin, fout, ev, accesshidden=False):
36253
464bedc0fdb4 wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36252
diff changeset
   450
    # This function operates like a state machine of sorts. The following
464bedc0fdb4 wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36252
diff changeset
   451
    # states are defined:
464bedc0fdb4 wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36252
diff changeset
   452
    #
464bedc0fdb4 wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36252
diff changeset
   453
    # protov1-serving
464bedc0fdb4 wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36252
diff changeset
   454
    #    Server is in protocol version 1 serving mode. Commands arrive on
464bedc0fdb4 wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36252
diff changeset
   455
    #    new lines. These commands are processed in this state, one command
464bedc0fdb4 wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36252
diff changeset
   456
    #    after the other.
464bedc0fdb4 wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36252
diff changeset
   457
    #
464bedc0fdb4 wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36252
diff changeset
   458
    # shutdown
464bedc0fdb4 wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36252
diff changeset
   459
    #    The server is shutting down, possibly in reaction to a client event.
464bedc0fdb4 wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36252
diff changeset
   460
    #
464bedc0fdb4 wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36252
diff changeset
   461
    # And here are their transitions:
464bedc0fdb4 wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36252
diff changeset
   462
    #
464bedc0fdb4 wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36252
diff changeset
   463
    # protov1-serving -> shutdown
464bedc0fdb4 wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36252
diff changeset
   464
    #    When server receives an empty request or encounters another
464bedc0fdb4 wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36252
diff changeset
   465
    #    error.
464bedc0fdb4 wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36252
diff changeset
   466
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   467
    state = b'protov1-serving'
36252
3b3a987bbbaa wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36251
diff changeset
   468
    proto = sshv1protocolhandler(ui, fin, fout)
3b3a987bbbaa wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36251
diff changeset
   469
36552
e7411fb7ba7f wireprotoserver: ability to run an SSH server until an event is set
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36403
diff changeset
   470
    while not ev.is_set():
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   471
        if state == b'protov1-serving':
36252
3b3a987bbbaa wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36251
diff changeset
   472
            # Commands are issued on new lines.
3b3a987bbbaa wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36251
diff changeset
   473
            request = fin.readline()[:-1]
3b3a987bbbaa wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36251
diff changeset
   474
3b3a987bbbaa wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36251
diff changeset
   475
            # Empty lines signal to terminate the connection.
3b3a987bbbaa wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36251
diff changeset
   476
            if not request:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   477
                state = b'shutdown'
36252
3b3a987bbbaa wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36251
diff changeset
   478
                continue
3b3a987bbbaa wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36251
diff changeset
   479
37785
b4d85bc122bd wireproto: rename wireproto to wireprotov1server (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37783
diff changeset
   480
            available = wireprotov1server.commands.commandavailable(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
   481
                request, proto
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
   482
            )
36252
3b3a987bbbaa wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36251
diff changeset
   483
3b3a987bbbaa wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36251
diff changeset
   484
            # This command isn't available. Send an empty response and go
3b3a987bbbaa wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36251
diff changeset
   485
            # back to waiting for a new command.
3b3a987bbbaa wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36251
diff changeset
   486
            if not available:
3b3a987bbbaa wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36251
diff changeset
   487
                _sshv1respondbytes(fout, b'')
3b3a987bbbaa wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36251
diff changeset
   488
                continue
3b3a987bbbaa wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36251
diff changeset
   489
50481
45c7bada5200 hidden: add support to explicitly access hidden changesets with SSH peers
Manuel Jacob <me@manueljacob.de>
parents: 50477
diff changeset
   490
            rsp = wireprotov1server.dispatch(
45c7bada5200 hidden: add support to explicitly access hidden changesets with SSH peers
Manuel Jacob <me@manueljacob.de>
parents: 50477
diff changeset
   491
                repo, proto, request, accesshidden=accesshidden
45c7bada5200 hidden: add support to explicitly access hidden changesets with SSH peers
Manuel Jacob <me@manueljacob.de>
parents: 50477
diff changeset
   492
            )
42902
7e19b640c53e sshserver: flush stream after command dispatch
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42824
diff changeset
   493
            repo.ui.fout.flush()
7e19b640c53e sshserver: flush stream after command dispatch
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42824
diff changeset
   494
            repo.ui.ferr.flush()
36252
3b3a987bbbaa wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36251
diff changeset
   495
3b3a987bbbaa wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36251
diff changeset
   496
            if isinstance(rsp, bytes):
3b3a987bbbaa wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36251
diff changeset
   497
                _sshv1respondbytes(fout, rsp)
3b3a987bbbaa wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36251
diff changeset
   498
            elif isinstance(rsp, wireprototypes.bytesresponse):
3b3a987bbbaa wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36251
diff changeset
   499
                _sshv1respondbytes(fout, rsp.data)
3b3a987bbbaa wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36251
diff changeset
   500
            elif isinstance(rsp, wireprototypes.streamres):
3b3a987bbbaa wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36251
diff changeset
   501
                _sshv1respondstream(fout, rsp)
3b3a987bbbaa wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36251
diff changeset
   502
            elif isinstance(rsp, wireprototypes.streamreslegacy):
3b3a987bbbaa wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36251
diff changeset
   503
                _sshv1respondstream(fout, rsp)
3b3a987bbbaa wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36251
diff changeset
   504
            elif isinstance(rsp, wireprototypes.pushres):
3b3a987bbbaa wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36251
diff changeset
   505
                _sshv1respondbytes(fout, b'')
3b3a987bbbaa wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36251
diff changeset
   506
                _sshv1respondbytes(fout, b'%d' % rsp.res)
3b3a987bbbaa wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36251
diff changeset
   507
            elif isinstance(rsp, wireprototypes.pusherr):
3b3a987bbbaa wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36251
diff changeset
   508
                _sshv1respondbytes(fout, rsp.res)
3b3a987bbbaa wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36251
diff changeset
   509
            elif isinstance(rsp, wireprototypes.ooberror):
3b3a987bbbaa wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36251
diff changeset
   510
                _sshv1respondooberror(fout, ui.ferr, rsp.message)
3b3a987bbbaa wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36251
diff changeset
   511
            else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
   512
                raise error.ProgrammingError(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   513
                    b'unhandled response type from '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   514
                    b'wire protocol command: %s' % rsp
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
   515
                )
36252
3b3a987bbbaa wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36251
diff changeset
   516
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   517
        elif state == b'shutdown':
36252
3b3a987bbbaa wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36251
diff changeset
   518
            break
3b3a987bbbaa wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36251
diff changeset
   519
3b3a987bbbaa wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36251
diff changeset
   520
        else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
   521
            raise error.ProgrammingError(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   522
                b'unhandled ssh server state: %s' % state
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
   523
            )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
   524
36252
3b3a987bbbaa wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36251
diff changeset
   525
49037
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48966
diff changeset
   526
class sshserver:
50481
45c7bada5200 hidden: add support to explicitly access hidden changesets with SSH peers
Manuel Jacob <me@manueljacob.de>
parents: 50477
diff changeset
   527
    def __init__(self, ui, repo, logfh=None, accesshidden=False):
36103
bf676267f64f wireprotoserver: split ssh protocol handler and server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36102
diff changeset
   528
        self._ui = ui
bf676267f64f wireprotoserver: split ssh protocol handler and server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36102
diff changeset
   529
        self._repo = repo
41285
cf8677cd7286 ui: proxy protect/restorestdio() calls to update internal flag
Yuya Nishihara <yuya@tcha.org>
parents: 40075
diff changeset
   530
        self._fin, self._fout = ui.protectfinout()
50481
45c7bada5200 hidden: add support to explicitly access hidden changesets with SSH peers
Manuel Jacob <me@manueljacob.de>
parents: 50477
diff changeset
   531
        self._accesshidden = accesshidden
36103
bf676267f64f wireprotoserver: split ssh protocol handler and server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36102
diff changeset
   532
36555
7cc4a9b9732a wireprotoserver: support logging SSH server I/O to a file descriptor
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36552
diff changeset
   533
        # Log write I/O to stdout and stderr if configured.
7cc4a9b9732a wireprotoserver: support logging SSH server I/O to a file descriptor
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36552
diff changeset
   534
        if logfh:
7cc4a9b9732a wireprotoserver: support logging SSH server I/O to a file descriptor
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36552
diff changeset
   535
            self._fout = util.makeloggingfileobject(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   536
                logfh, self._fout, b'o', logdata=True
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
   537
            )
36555
7cc4a9b9732a wireprotoserver: support logging SSH server I/O to a file descriptor
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36552
diff changeset
   538
            ui.ferr = util.makeloggingfileobject(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   539
                logfh, ui.ferr, b'e', logdata=True
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42902
diff changeset
   540
            )
36555
7cc4a9b9732a wireprotoserver: support logging SSH server I/O to a file descriptor
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36552
diff changeset
   541
35899
1bf5263fe5cc wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35898
diff changeset
   542
    def serve_forever(self):
36552
e7411fb7ba7f wireprotoserver: ability to run an SSH server until an event is set
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36403
diff changeset
   543
        self.serveuntil(threading.Event())
41285
cf8677cd7286 ui: proxy protect/restorestdio() calls to update internal flag
Yuya Nishihara <yuya@tcha.org>
parents: 40075
diff changeset
   544
        self._ui.restorefinout(self._fin, self._fout)
36552
e7411fb7ba7f wireprotoserver: ability to run an SSH server until an event is set
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36403
diff changeset
   545
e7411fb7ba7f wireprotoserver: ability to run an SSH server until an event is set
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36403
diff changeset
   546
    def serveuntil(self, ev):
e7411fb7ba7f wireprotoserver: ability to run an SSH server until an event is set
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36403
diff changeset
   547
        """Serve until a threading.Event is set."""
50481
45c7bada5200 hidden: add support to explicitly access hidden changesets with SSH peers
Manuel Jacob <me@manueljacob.de>
parents: 50477
diff changeset
   548
        _runsshserver(
45c7bada5200 hidden: add support to explicitly access hidden changesets with SSH peers
Manuel Jacob <me@manueljacob.de>
parents: 50477
diff changeset
   549
            self._ui, self._repo, self._fin, self._fout, ev, self._accesshidden
45c7bada5200 hidden: add support to explicitly access hidden changesets with SSH peers
Manuel Jacob <me@manueljacob.de>
parents: 50477
diff changeset
   550
        )