mercurial/wireprotoserver.py
author Gregory Szorc <gregory.szorc@gmail.com>
Wed, 31 Jan 2018 11:09:07 -0800
changeset 35856 ef3a24a023ec
parent 35750 mercurial/hgweb/protocol.py@a39a9df7ecca
child 35857 a42455b3dbf8
permissions -rw-r--r--
wireprotoserver: rename hgweb.protocol to wireprotoserver (API) The HTTP wire protocol server / response handler is currently defined in the hgweb sub-package. That only kind of makes sense. hgweb does contain most of the HTTP server code. However, hgweb is more tailored for providing HTTP server and WSGI scaffolding and serving hgweb requests. The wire protocol is kind of its own beast. In addition, the code for HTTP and SSH wire protocol handling is actually pretty small and it needs to stay in sync to ensure parity between the transport implementations. We rename mercurial/hgweb/protocol.py to mercurial/wireprotoserver.py. The new module will eventually become the home of the SSH handler as well. .. api:: Content from mercurial.hgweb.protocol has been moved to mercurial.wireprotoserver. Differential Revision: https://phab.mercurial-scm.org/D1965
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>
d534ba1c4eb4 separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
     2
# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
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
from __future__ import absolute_import
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 20903
diff changeset
     8
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 20903
diff changeset
     9
import cgi
30764
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
    10
import struct
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 20903
diff changeset
    11
35856
ef3a24a023ec wireprotoserver: rename hgweb.protocol to wireprotoserver (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35750
diff changeset
    12
from .hgweb.common import (
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 20903
diff changeset
    13
    HTTP_OK,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 20903
diff changeset
    14
)
35856
ef3a24a023ec wireprotoserver: rename hgweb.protocol to wireprotoserver (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35750
diff changeset
    15
from . import (
34509
e21f274cccea hgweb: in protocol adapter, avoid control reaching end of non-void function
Augie Fackler <augie@google.com>
parents: 33821
diff changeset
    16
    error,
34742
5a9cad0dfddb hgweb: when unpacking args from request form, convert to bytes
Augie Fackler <augie@google.com>
parents: 34740
diff changeset
    17
    pycompat,
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 20903
diff changeset
    18
    util,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 20903
diff changeset
    19
    wireproto,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 20903
diff changeset
    20
)
35856
ef3a24a023ec wireprotoserver: rename hgweb.protocol to wireprotoserver (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35750
diff changeset
    21
28861
86db5cb55d46 pycompat: switch to util.stringio for py3 compat
timeless <timeless@mozdev.org>
parents: 28530
diff changeset
    22
stringio = util.stringio
5963
5be210afe1b8 hgweb: explicitly check if requested command exists
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5915
diff changeset
    23
28883
032c4c2f802a pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents: 28861
diff changeset
    24
urlerr = util.urlerr
032c4c2f802a pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents: 28861
diff changeset
    25
urlreq = util.urlreq
032c4c2f802a pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents: 28861
diff changeset
    26
5993
948a41e77902 hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5963
diff changeset
    27
HGTYPE = 'application/mercurial-0.1'
30764
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
    28
HGTYPE2 = 'application/mercurial-0.2'
15017
f4522df38c65 wireproto: add out-of-band error class to allow remote repo to report errors
Andrew Pritchard <andrewp@fogcreek.com>
parents: 14614
diff changeset
    29
HGERRTYPE = 'application/hg-error'
11595
368cd5325348 protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents: 11594
diff changeset
    30
30759
3f5f0c98cd18 httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30562
diff changeset
    31
def decodevaluefromheaders(req, headerprefix):
34744
0a2ef612ad50 hgweb: fix decodevaluefromheaders to always return a bytes value
Augie Fackler <augie@google.com>
parents: 34743
diff changeset
    32
    """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
    33
0a2ef612ad50 hgweb: fix decodevaluefromheaders to always return a bytes value
Augie Fackler <augie@google.com>
parents: 34743
diff changeset
    34
    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
    35
    """
30759
3f5f0c98cd18 httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30562
diff changeset
    36
    chunks = []
3f5f0c98cd18 httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30562
diff changeset
    37
    i = 1
34744
0a2ef612ad50 hgweb: fix decodevaluefromheaders to always return a bytes value
Augie Fackler <augie@google.com>
parents: 34743
diff changeset
    38
    prefix = headerprefix.upper().replace(r'-', r'_')
30759
3f5f0c98cd18 httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30562
diff changeset
    39
    while True:
34744
0a2ef612ad50 hgweb: fix decodevaluefromheaders to always return a bytes value
Augie Fackler <augie@google.com>
parents: 34743
diff changeset
    40
        v = req.env.get(r'HTTP_%s_%d' % (prefix, i))
30759
3f5f0c98cd18 httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30562
diff changeset
    41
        if v is None:
3f5f0c98cd18 httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30562
diff changeset
    42
            break
34744
0a2ef612ad50 hgweb: fix decodevaluefromheaders to always return a bytes value
Augie Fackler <augie@google.com>
parents: 34743
diff changeset
    43
        chunks.append(pycompat.bytesurl(v))
30759
3f5f0c98cd18 httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30562
diff changeset
    44
        i += 1
3f5f0c98cd18 httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30562
diff changeset
    45
3f5f0c98cd18 httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30562
diff changeset
    46
    return ''.join(chunks)
3f5f0c98cd18 httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30562
diff changeset
    47
20903
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 18352
diff changeset
    48
class webproto(wireproto.abstractserverproto):
14614
afccc64eea73 ui: use I/O descriptors internally
Idan Kamara <idankk86@gmail.com>
parents: 14494
diff changeset
    49
    def __init__(self, req, ui):
11595
368cd5325348 protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents: 11594
diff changeset
    50
        self.req = req
368cd5325348 protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents: 11594
diff changeset
    51
        self.response = ''
14614
afccc64eea73 ui: use I/O descriptors internally
Idan Kamara <idankk86@gmail.com>
parents: 14494
diff changeset
    52
        self.ui = ui
30562
b3a9ef3d30e8 protocol: declare transport protocol name
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30466
diff changeset
    53
        self.name = 'http'
b3a9ef3d30e8 protocol: declare transport protocol name
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30466
diff changeset
    54
11595
368cd5325348 protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents: 11594
diff changeset
    55
    def getargs(self, args):
14093
ce99d887585f httprepo: long arguments support (issue2126)
Steven Brown <StevenGBrown@gmail.com>
parents: 13721
diff changeset
    56
        knownargs = self._args()
11595
368cd5325348 protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents: 11594
diff changeset
    57
        data = {}
368cd5325348 protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents: 11594
diff changeset
    58
        keys = args.split()
368cd5325348 protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents: 11594
diff changeset
    59
        for k in keys:
368cd5325348 protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents: 11594
diff changeset
    60
            if k == '*':
368cd5325348 protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents: 11594
diff changeset
    61
                star = {}
14093
ce99d887585f httprepo: long arguments support (issue2126)
Steven Brown <StevenGBrown@gmail.com>
parents: 13721
diff changeset
    62
                for key in knownargs.keys():
13721
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 12704
diff changeset
    63
                    if key != 'cmd' and key not in keys:
14093
ce99d887585f httprepo: long arguments support (issue2126)
Steven Brown <StevenGBrown@gmail.com>
parents: 13721
diff changeset
    64
                        star[key] = knownargs[key][0]
11595
368cd5325348 protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents: 11594
diff changeset
    65
                data['*'] = star
368cd5325348 protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents: 11594
diff changeset
    66
            else:
14093
ce99d887585f httprepo: long arguments support (issue2126)
Steven Brown <StevenGBrown@gmail.com>
parents: 13721
diff changeset
    67
                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
    68
        return [data[k] for k in keys]
14093
ce99d887585f httprepo: long arguments support (issue2126)
Steven Brown <StevenGBrown@gmail.com>
parents: 13721
diff changeset
    69
    def _args(self):
ce99d887585f httprepo: long arguments support (issue2126)
Steven Brown <StevenGBrown@gmail.com>
parents: 13721
diff changeset
    70
        args = self.req.form.copy()
34742
5a9cad0dfddb hgweb: when unpacking args from request form, convert to bytes
Augie Fackler <augie@google.com>
parents: 34740
diff changeset
    71
        if pycompat.ispy3:
5a9cad0dfddb hgweb: when unpacking args from request form, convert to bytes
Augie Fackler <augie@google.com>
parents: 34740
diff changeset
    72
            args = {k.encode('ascii'): [v.encode('ascii') for v in vs]
5a9cad0dfddb hgweb: when unpacking args from request form, convert to bytes
Augie Fackler <augie@google.com>
parents: 34740
diff changeset
    73
                    for k, vs in args.items()}
34743
dc2bf7074147 hgweb: more "headers are native strs" cleanup
Augie Fackler <augie@google.com>
parents: 34742
diff changeset
    74
        postlen = int(self.req.env.get(r'HTTP_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
    75
        if postlen:
fd2acc5046f6 http: support sending hgargs via POST body instead of in GET or headers
Augie Fackler <augie@google.com>
parents: 27046
diff changeset
    76
            args.update(cgi.parse_qs(
fd2acc5046f6 http: support sending hgargs via POST body instead of in GET or headers
Augie Fackler <augie@google.com>
parents: 27046
diff changeset
    77
                self.req.read(postlen), keep_blank_values=True))
fd2acc5046f6 http: support sending hgargs via POST body instead of in GET or headers
Augie Fackler <augie@google.com>
parents: 27046
diff changeset
    78
            return args
30759
3f5f0c98cd18 httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30562
diff changeset
    79
34743
dc2bf7074147 hgweb: more "headers are native strs" cleanup
Augie Fackler <augie@google.com>
parents: 34742
diff changeset
    80
        argvalue = decodevaluefromheaders(self.req, r'X-HgArg')
30759
3f5f0c98cd18 httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30562
diff changeset
    81
        args.update(cgi.parse_qs(argvalue, keep_blank_values=True))
14093
ce99d887585f httprepo: long arguments support (issue2126)
Steven Brown <StevenGBrown@gmail.com>
parents: 13721
diff changeset
    82
        return args
11621
e46a8b2331a6 protocol: shuffle server methods to group send methods
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11618
diff changeset
    83
    def getfile(self, fp):
34740
b2601c5977a4 hgweb: more "http headers are native strs" cleanup
Augie Fackler <augie@google.com>
parents: 34510
diff changeset
    84
        length = int(self.req.env[r'CONTENT_LENGTH'])
33821
3c91cc0c5fde httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents: 33228
diff changeset
    85
        # 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
    86
        # minus the amount that was consumed by args.
34740
b2601c5977a4 hgweb: more "http headers are native strs" cleanup
Augie Fackler <augie@google.com>
parents: 34510
diff changeset
    87
        length -= int(self.req.env.get(r'HTTP_X_HGARGS_POST', 0))
11621
e46a8b2331a6 protocol: shuffle server methods to group send methods
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11618
diff changeset
    88
        for s in util.filechunkiter(self.req, limit=length):
e46a8b2331a6 protocol: shuffle server methods to group send methods
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11618
diff changeset
    89
            fp.write(s)
e46a8b2331a6 protocol: shuffle server methods to group send methods
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11618
diff changeset
    90
    def redirect(self):
14614
afccc64eea73 ui: use I/O descriptors internally
Idan Kamara <idankk86@gmail.com>
parents: 14494
diff changeset
    91
        self.oldio = self.ui.fout, self.ui.ferr
28861
86db5cb55d46 pycompat: switch to util.stringio for py3 compat
timeless <timeless@mozdev.org>
parents: 28530
diff changeset
    92
        self.ui.ferr = self.ui.fout = stringio()
14614
afccc64eea73 ui: use I/O descriptors internally
Idan Kamara <idankk86@gmail.com>
parents: 14494
diff changeset
    93
    def restore(self):
afccc64eea73 ui: use I/O descriptors internally
Idan Kamara <idankk86@gmail.com>
parents: 14494
diff changeset
    94
        val = self.ui.fout.getvalue()
afccc64eea73 ui: use I/O descriptors internally
Idan Kamara <idankk86@gmail.com>
parents: 14494
diff changeset
    95
        self.ui.ferr, self.ui.fout = self.oldio
afccc64eea73 ui: use I/O descriptors internally
Idan Kamara <idankk86@gmail.com>
parents: 14494
diff changeset
    96
        return val
30206
d105195436c0 wireproto: compress data from a generator
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30014
diff changeset
    97
11595
368cd5325348 protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents: 11594
diff changeset
    98
    def _client(self):
368cd5325348 protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents: 11594
diff changeset
    99
        return 'remote:%s:%s:%s' % (
368cd5325348 protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents: 11594
diff changeset
   100
            self.req.env.get('wsgi.url_scheme') or 'http',
28883
032c4c2f802a pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents: 28861
diff changeset
   101
            urlreq.quote(self.req.env.get('REMOTE_HOST', '')),
032c4c2f802a pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents: 28861
diff changeset
   102
            urlreq.quote(self.req.env.get('REMOTE_USER', '')))
11595
368cd5325348 protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents: 11594
diff changeset
   103
35750
a39a9df7ecca wireproto: split streamres into legacy and modern case
Joerg Sonnenberger <joerg@bec.de>
parents: 35705
diff changeset
   104
    def responsetype(self, prefer_uncompressed):
30764
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   105
        """Determine the appropriate response type and compression settings.
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   106
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   107
        Returns a tuple of (mediatype, compengine, engineopts).
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   108
        """
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   109
        # Determine the response media type and compression engine based
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   110
        # on the request parameters.
34743
dc2bf7074147 hgweb: more "headers are native strs" cleanup
Augie Fackler <augie@google.com>
parents: 34742
diff changeset
   111
        protocaps = decodevaluefromheaders(self.req, r'X-HgProto').split(' ')
30764
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   112
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   113
        if '0.2' in protocaps:
35750
a39a9df7ecca wireproto: split streamres into legacy and modern case
Joerg Sonnenberger <joerg@bec.de>
parents: 35705
diff changeset
   114
            # All clients are expected to support uncompressed data.
a39a9df7ecca wireproto: split streamres into legacy and modern case
Joerg Sonnenberger <joerg@bec.de>
parents: 35705
diff changeset
   115
            if prefer_uncompressed:
a39a9df7ecca wireproto: split streamres into legacy and modern case
Joerg Sonnenberger <joerg@bec.de>
parents: 35705
diff changeset
   116
                return HGTYPE2, util._noopengine(), {}
a39a9df7ecca wireproto: split streamres into legacy and modern case
Joerg Sonnenberger <joerg@bec.de>
parents: 35705
diff changeset
   117
30764
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   118
            # Default as defined by wire protocol spec.
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   119
            compformats = ['zlib', 'none']
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   120
            for cap in protocaps:
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   121
                if cap.startswith('comp='):
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   122
                    compformats = cap[5:].split(',')
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   123
                    break
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   124
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   125
            # Now find an agreed upon compression format.
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   126
            for engine in wireproto.supportedcompengines(self.ui, self,
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   127
                                                         util.SERVERROLE):
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   128
                if engine.wireprotosupport().name in compformats:
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   129
                    opts = {}
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   130
                    level = self.ui.configint('server',
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   131
                                              '%slevel' % engine.name())
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   132
                    if level is not None:
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   133
                        opts['level'] = level
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   134
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   135
                    return HGTYPE2, engine, opts
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   136
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   137
            # No mutually supported compression format. Fall back to the
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   138
            # legacy protocol.
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   139
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   140
        # Don't allow untrusted settings because disabling compression or
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   141
        # setting a very high compression level could lead to flooding
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   142
        # the server's network or CPU.
33228
35c233975b78 configitems: register the 'server.zliblevel' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 30764
diff changeset
   143
        opts = {'level': self.ui.configint('server', 'zliblevel')}
30764
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   144
        return HGTYPE, util.compengines['zlib'], opts
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   145
11595
368cd5325348 protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents: 11594
diff changeset
   146
def iscmd(cmd):
368cd5325348 protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents: 11594
diff changeset
   147
    return cmd in wireproto.commands
368cd5325348 protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents: 11594
diff changeset
   148
368cd5325348 protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents: 11594
diff changeset
   149
def call(repo, req, cmd):
14614
afccc64eea73 ui: use I/O descriptors internally
Idan Kamara <idankk86@gmail.com>
parents: 14494
diff changeset
   150
    p = webproto(req, repo.ui)
30764
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   151
35750
a39a9df7ecca wireproto: split streamres into legacy and modern case
Joerg Sonnenberger <joerg@bec.de>
parents: 35705
diff changeset
   152
    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
   153
        # 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
   154
        # 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
   155
        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
   156
        assert 0 < len(name) < 256
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   157
        yield struct.pack('B', len(name))
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   158
        yield name
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   159
35750
a39a9df7ecca wireproto: split streamres into legacy and modern case
Joerg Sonnenberger <joerg@bec.de>
parents: 35705
diff changeset
   160
        for chunk in gen:
a39a9df7ecca wireproto: split streamres into legacy and modern case
Joerg Sonnenberger <joerg@bec.de>
parents: 35705
diff changeset
   161
            yield chunk
30764
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   162
11625
cdeb861335d5 protocol: wrap non-string protocol responses in classes
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11623
diff changeset
   163
    rsp = wireproto.dispatch(repo, p, cmd)
34510
c23fa3103925 hgweb: in protocol adapter, look for bytes instances, not str
Augie Fackler <augie@google.com>
parents: 34509
diff changeset
   164
    if isinstance(rsp, bytes):
18352
e33b9b92a200 hgweb: pass the actual response body to request.response, not just the length
Mads Kiilerich <mads@kiilerich.com>
parents: 18346
diff changeset
   165
        req.respond(HTTP_OK, HGTYPE, body=rsp)
e33b9b92a200 hgweb: pass the actual response body to request.response, not just the length
Mads Kiilerich <mads@kiilerich.com>
parents: 18346
diff changeset
   166
        return []
35750
a39a9df7ecca wireproto: split streamres into legacy and modern case
Joerg Sonnenberger <joerg@bec.de>
parents: 35705
diff changeset
   167
    elif isinstance(rsp, wireproto.streamres_legacy):
a39a9df7ecca wireproto: split streamres into legacy and modern case
Joerg Sonnenberger <joerg@bec.de>
parents: 35705
diff changeset
   168
        gen = rsp.gen
a39a9df7ecca wireproto: split streamres into legacy and modern case
Joerg Sonnenberger <joerg@bec.de>
parents: 35705
diff changeset
   169
        req.respond(HTTP_OK, HGTYPE)
a39a9df7ecca wireproto: split streamres into legacy and modern case
Joerg Sonnenberger <joerg@bec.de>
parents: 35705
diff changeset
   170
        return gen
11626
2f8adc60e013 protocol: use generators instead of req.write() for hgweb stream responses
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
   171
    elif isinstance(rsp, wireproto.streamres):
35705
8cdb671dbd0b wireproto: drop support for reader interface from streamres (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34744
diff changeset
   172
        gen = rsp.gen
30466
2add671bf55b wireproto: perform chunking and compression at protocol layer (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30366
diff changeset
   173
30764
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   174
        # 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
   175
        # is here because we only compress streamres at the moment.
35750
a39a9df7ecca wireproto: split streamres into legacy and modern case
Joerg Sonnenberger <joerg@bec.de>
parents: 35705
diff changeset
   176
        mediatype, engine, engineopts = p.responsetype(rsp.prefer_uncompressed)
a39a9df7ecca wireproto: split streamres into legacy and modern case
Joerg Sonnenberger <joerg@bec.de>
parents: 35705
diff changeset
   177
        gen = engine.compressstream(gen, engineopts)
30466
2add671bf55b wireproto: perform chunking and compression at protocol layer (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30366
diff changeset
   178
35750
a39a9df7ecca wireproto: split streamres into legacy and modern case
Joerg Sonnenberger <joerg@bec.de>
parents: 35705
diff changeset
   179
        if mediatype == HGTYPE2:
a39a9df7ecca wireproto: split streamres into legacy and modern case
Joerg Sonnenberger <joerg@bec.de>
parents: 35705
diff changeset
   180
            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
   181
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30759
diff changeset
   182
        req.respond(HTTP_OK, mediatype)
30466
2add671bf55b wireproto: perform chunking and compression at protocol layer (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30366
diff changeset
   183
        return gen
11626
2f8adc60e013 protocol: use generators instead of req.write() for hgweb stream responses
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
   184
    elif isinstance(rsp, wireproto.pushres):
14614
afccc64eea73 ui: use I/O descriptors internally
Idan Kamara <idankk86@gmail.com>
parents: 14494
diff changeset
   185
        val = p.restore()
18346
6c2563b2c1c6 hgweb: use Content-Length for pushres
Mads Kiilerich <mads@kiilerich.com>
parents: 15017
diff changeset
   186
        rsp = '%d\n%s' % (rsp.res, val)
18352
e33b9b92a200 hgweb: pass the actual response body to request.response, not just the length
Mads Kiilerich <mads@kiilerich.com>
parents: 18346
diff changeset
   187
        req.respond(HTTP_OK, HGTYPE, body=rsp)
e33b9b92a200 hgweb: pass the actual response body to request.response, not just the length
Mads Kiilerich <mads@kiilerich.com>
parents: 18346
diff changeset
   188
        return []
12703
40bb5853fc4b wireproto: introduce pusherr() to deal with "unsynced changes" error
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11626
diff changeset
   189
    elif isinstance(rsp, wireproto.pusherr):
12704
ca6e2adc3e4d wireproto/http: drain the incoming bundle in case of errors
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12703
diff changeset
   190
        # drain the incoming bundle
ca6e2adc3e4d wireproto/http: drain the incoming bundle in case of errors
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12703
diff changeset
   191
        req.drain()
14614
afccc64eea73 ui: use I/O descriptors internally
Idan Kamara <idankk86@gmail.com>
parents: 14494
diff changeset
   192
        p.restore()
12703
40bb5853fc4b wireproto: introduce pusherr() to deal with "unsynced changes" error
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11626
diff changeset
   193
        rsp = '0\n%s\n' % rsp.res
18352
e33b9b92a200 hgweb: pass the actual response body to request.response, not just the length
Mads Kiilerich <mads@kiilerich.com>
parents: 18346
diff changeset
   194
        req.respond(HTTP_OK, HGTYPE, body=rsp)
e33b9b92a200 hgweb: pass the actual response body to request.response, not just the length
Mads Kiilerich <mads@kiilerich.com>
parents: 18346
diff changeset
   195
        return []
15017
f4522df38c65 wireproto: add out-of-band error class to allow remote repo to report errors
Andrew Pritchard <andrewp@fogcreek.com>
parents: 14614
diff changeset
   196
    elif isinstance(rsp, wireproto.ooberror):
f4522df38c65 wireproto: add out-of-band error class to allow remote repo to report errors
Andrew Pritchard <andrewp@fogcreek.com>
parents: 14614
diff changeset
   197
        rsp = rsp.message
18352
e33b9b92a200 hgweb: pass the actual response body to request.response, not just the length
Mads Kiilerich <mads@kiilerich.com>
parents: 18346
diff changeset
   198
        req.respond(HTTP_OK, HGERRTYPE, body=rsp)
e33b9b92a200 hgweb: pass the actual response body to request.response, not just the length
Mads Kiilerich <mads@kiilerich.com>
parents: 18346
diff changeset
   199
        return []
34509
e21f274cccea hgweb: in protocol adapter, avoid control reaching end of non-void function
Augie Fackler <augie@google.com>
parents: 33821
diff changeset
   200
    raise error.ProgrammingError('hgweb.protocol internal failure', rsp)