Mercurial > public > mercurial-scm > hg-stable
annotate mercurial/wireprotoserver.py @ 37295:45b39c69fae0
wireproto: separate commands tables for version 1 and 2 commands
We can't easily reuse existing command handlers for version 2
commands because the response types will be different. e.g. many
commands return nodes encoded as hex. Our new wire protocol is
binary safe, so we'll wish to encode nodes as binary.
We /could/ teach each command handler to look at the protocol
handler and change behavior based on the version in use. However,
this would make logic a bit unwieldy over time and would make
it harder to design a unified protocol handler interface. I think
it's better to create a clean break between version 1 and version 2
of commands on the server.
What I imagine happening is we will have separate @wireprotocommand
functions for each protocol generation. Those functions will parse the
request, dispatch to a common function to process it, then generate
the response in its own, transport-specific manner.
This commit establishes a separate table for tracking version 1
commands from version 2 commands. The HTTP server pieces have been
updated to use this new table.
Most commands are marked as both version 1 and version 2, so there is
little practical impact to this change.
A side-effect of this change is we now rely on transport registration
in wireprototypes.TRANSPORTS and certain properties of the protocol
interface. So a test had to be updated to conform.
Differential Revision: https://phab.mercurial-scm.org/D2982
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Wed, 28 Mar 2018 10:40:41 -0700 |
parents | 3d0e2cd86e05 |
children | 78103e4138b1 |
rev | line source |
---|---|
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 | 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 |
36104
2ad145fbde54
wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36103
diff
changeset
|
9 import contextlib |
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 |
35899
1bf5263fe5cc
wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35898
diff
changeset
|
11 import sys |
36552
e7411fb7ba7f
wireprotoserver: ability to run an SSH server until an event is set
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36403
diff
changeset
|
12 import threading |
27046
37fcfe52c68c
hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
20903
diff
changeset
|
13 |
35899
1bf5263fe5cc
wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35898
diff
changeset
|
14 from .i18n import _ |
35896
ef3a24a023ec
wireprotoserver: rename hgweb.protocol to wireprotoserver (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35750
diff
changeset
|
15 from . import ( |
35899
1bf5263fe5cc
wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35898
diff
changeset
|
16 encoding, |
34509
e21f274cccea
hgweb: in protocol adapter, avoid control reaching end of non-void function
Augie Fackler <augie@google.com>
parents:
33842
diff
changeset
|
17 error, |
35899
1bf5263fe5cc
wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35898
diff
changeset
|
18 hook, |
34742
5a9cad0dfddb
hgweb: when unpacking args from request form, convert to bytes
Augie Fackler <augie@google.com>
parents:
34740
diff
changeset
|
19 pycompat, |
27046
37fcfe52c68c
hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
20903
diff
changeset
|
20 util, |
37fcfe52c68c
hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
20903
diff
changeset
|
21 wireproto, |
37055
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
22 wireprotoframing, |
36111
cd6ab329c5c7
wireprototypes: move wire protocol response types to new module
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36110
diff
changeset
|
23 wireprototypes, |
27046
37fcfe52c68c
hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
20903
diff
changeset
|
24 ) |
37123
a8a902d7176e
procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
37064
diff
changeset
|
25 from .utils import ( |
a8a902d7176e
procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
37064
diff
changeset
|
26 procutil, |
a8a902d7176e
procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
37064
diff
changeset
|
27 ) |
35896
ef3a24a023ec
wireprotoserver: rename hgweb.protocol to wireprotoserver (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35750
diff
changeset
|
28 |
28861
86db5cb55d46
pycompat: switch to util.stringio for py3 compat
timeless <timeless@mozdev.org>
parents:
28530
diff
changeset
|
29 stringio = util.stringio |
5963
5be210afe1b8
hgweb: explicitly check if requested command exists
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5915
diff
changeset
|
30 |
28883
032c4c2f802a
pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents:
28861
diff
changeset
|
31 urlerr = util.urlerr |
032c4c2f802a
pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents:
28861
diff
changeset
|
32 urlreq = util.urlreq |
032c4c2f802a
pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents:
28861
diff
changeset
|
33 |
35898
1b76a9e0a9de
wireprotoserver: don't import symbol from hgweb.common
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35897
diff
changeset
|
34 HTTP_OK = 200 |
1b76a9e0a9de
wireprotoserver: don't import symbol from hgweb.common
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35897
diff
changeset
|
35 |
5993
948a41e77902
hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5963
diff
changeset
|
36 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
|
37 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
|
38 HGERRTYPE = 'application/hg-error' |
37292
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37289
diff
changeset
|
39 FRAMINGTYPE = b'application/mercurial-exp-framing-0003' |
11595
368cd5325348
protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents:
11594
diff
changeset
|
40 |
37049
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
41 HTTPV2 = wireprototypes.HTTPV2 |
36565
3cd245945ef3
wireprotoserver: move SSHV1 and SSHV2 constants to wireprototypes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36555
diff
changeset
|
42 SSHV1 = wireprototypes.SSHV1 |
3cd245945ef3
wireprotoserver: move SSHV1 and SSHV2 constants to wireprototypes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36555
diff
changeset
|
43 SSHV2 = wireprototypes.SSHV2 |
36015
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
44 |
36852
14f70c44af6c
wireprotoserver: access headers through parsed request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36821
diff
changeset
|
45 def decodevaluefromheaders(req, headerprefix): |
34744
0a2ef612ad50
hgweb: fix decodevaluefromheaders to always return a bytes value
Augie Fackler <augie@google.com>
parents:
34743
diff
changeset
|
46 """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
|
47 |
0a2ef612ad50
hgweb: fix decodevaluefromheaders to always return a bytes value
Augie Fackler <augie@google.com>
parents:
34743
diff
changeset
|
48 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
|
49 """ |
30759
3f5f0c98cd18
httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30567
diff
changeset
|
50 chunks = [] |
3f5f0c98cd18
httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30567
diff
changeset
|
51 i = 1 |
3f5f0c98cd18
httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30567
diff
changeset
|
52 while True: |
36852
14f70c44af6c
wireprotoserver: access headers through parsed request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36821
diff
changeset
|
53 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
|
54 if v is None: |
3f5f0c98cd18
httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30567
diff
changeset
|
55 break |
34744
0a2ef612ad50
hgweb: fix decodevaluefromheaders to always return a bytes value
Augie Fackler <augie@google.com>
parents:
34743
diff
changeset
|
56 chunks.append(pycompat.bytesurl(v)) |
30759
3f5f0c98cd18
httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30567
diff
changeset
|
57 i += 1 |
3f5f0c98cd18
httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30567
diff
changeset
|
58 |
3f5f0c98cd18
httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30567
diff
changeset
|
59 return ''.join(chunks) |
3f5f0c98cd18
httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30567
diff
changeset
|
60 |
36402
0c231df1ffdc
wireprototypes: move baseprotocolhandler from wireprotoserver
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36313
diff
changeset
|
61 class httpv1protocolhandler(wireprototypes.baseprotocolhandler): |
36873
a755fd3b7146
hgweb: expose URL scheme and REMOTE_* attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36868
diff
changeset
|
62 def __init__(self, req, ui, checkperm): |
36852
14f70c44af6c
wireprotoserver: access headers through parsed request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36821
diff
changeset
|
63 self._req = req |
35906
d747cf39cf70
wireprotoserver: make attributes private
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35905
diff
changeset
|
64 self._ui = ui |
36809
66de4555cefd
wireproto: formalize permissions checking as part of protocol interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36808
diff
changeset
|
65 self._checkperm = checkperm |
35913
29759c46aa1a
wireprotoserver: make name part of protocol interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35912
diff
changeset
|
66 |
29759c46aa1a
wireprotoserver: make name part of protocol interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35912
diff
changeset
|
67 @property |
29759c46aa1a
wireprotoserver: make name part of protocol interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35912
diff
changeset
|
68 def name(self): |
36261
2e07dc514073
wireprotoserver: add version to HTTP protocol name (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36260
diff
changeset
|
69 return 'http-v1' |
30567
b3a9ef3d30e8
protocol: declare transport protocol name
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30475
diff
changeset
|
70 |
11595
368cd5325348
protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents:
11594
diff
changeset
|
71 def getargs(self, args): |
14093
ce99d887585f
httprepo: long arguments support (issue2126)
Steven Brown <StevenGBrown@gmail.com>
parents:
13721
diff
changeset
|
72 knownargs = self._args() |
11595
368cd5325348
protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents:
11594
diff
changeset
|
73 data = {} |
368cd5325348
protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents:
11594
diff
changeset
|
74 keys = args.split() |
368cd5325348
protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents:
11594
diff
changeset
|
75 for k in keys: |
368cd5325348
protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents:
11594
diff
changeset
|
76 if k == '*': |
368cd5325348
protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents:
11594
diff
changeset
|
77 star = {} |
14093
ce99d887585f
httprepo: long arguments support (issue2126)
Steven Brown <StevenGBrown@gmail.com>
parents:
13721
diff
changeset
|
78 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
|
79 if key != 'cmd' and key not in keys: |
14093
ce99d887585f
httprepo: long arguments support (issue2126)
Steven Brown <StevenGBrown@gmail.com>
parents:
13721
diff
changeset
|
80 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
|
81 data['*'] = star |
368cd5325348
protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents:
11594
diff
changeset
|
82 else: |
14093
ce99d887585f
httprepo: long arguments support (issue2126)
Steven Brown <StevenGBrown@gmail.com>
parents:
13721
diff
changeset
|
83 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
|
84 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
|
85 |
14093
ce99d887585f
httprepo: long arguments support (issue2126)
Steven Brown <StevenGBrown@gmail.com>
parents:
13721
diff
changeset
|
86 def _args(self): |
36868
ec0af9c59270
hgweb: use a multidict for holding query string parameters
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36867
diff
changeset
|
87 args = self._req.qsparams.asdictoflists() |
36852
14f70c44af6c
wireprotoserver: access headers through parsed request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36821
diff
changeset
|
88 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
|
89 if postlen: |
36115
a3d42d1865f1
wireprotoserver: define and use parse_qs from urllib
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36113
diff
changeset
|
90 args.update(urlreq.parseqs( |
36863
da4e2f87167d
hgweb: expose input stream on parsed WSGI request object
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36861
diff
changeset
|
91 self._req.bodyfh.read(postlen), keep_blank_values=True)) |
28530
fd2acc5046f6
http: support sending hgargs via POST body instead of in GET or headers
Augie Fackler <augie@google.com>
parents:
27046
diff
changeset
|
92 return args |
30759
3f5f0c98cd18
httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30567
diff
changeset
|
93 |
36852
14f70c44af6c
wireprotoserver: access headers through parsed request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36821
diff
changeset
|
94 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
|
95 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
|
96 return args |
35903
49426bb4476c
wireprotoserver: add some blank lines between methods
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35900
diff
changeset
|
97 |
36108
90ca4986616c
wireprotoserver: rename getfile() to forwardpayload() (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36107
diff
changeset
|
98 def forwardpayload(self, fp): |
36853
ed0456fde625
hgweb: handle CONTENT_LENGTH
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36852
diff
changeset
|
99 # Existing clients *always* send Content-Length. |
ed0456fde625
hgweb: handle CONTENT_LENGTH
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36852
diff
changeset
|
100 length = int(self._req.headers[b'Content-Length']) |
ed0456fde625
hgweb: handle CONTENT_LENGTH
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36852
diff
changeset
|
101 |
33842
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33228
diff
changeset
|
102 # 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
|
103 # 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
|
104 length -= int(self._req.headers.get(b'X-HgArgs-Post', 0)) |
36863
da4e2f87167d
hgweb: expose input stream on parsed WSGI request object
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36861
diff
changeset
|
105 for s in util.filechunkiter(self._req.bodyfh, limit=length): |
11621
e46a8b2331a6
protocol: shuffle server methods to group send methods
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
11618
diff
changeset
|
106 fp.write(s) |
35903
49426bb4476c
wireprotoserver: add some blank lines between methods
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35900
diff
changeset
|
107 |
36104
2ad145fbde54
wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36103
diff
changeset
|
108 @contextlib.contextmanager |
2ad145fbde54
wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36103
diff
changeset
|
109 def mayberedirectstdio(self): |
2ad145fbde54
wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36103
diff
changeset
|
110 oldout = self._ui.fout |
2ad145fbde54
wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36103
diff
changeset
|
111 olderr = self._ui.ferr |
2ad145fbde54
wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36103
diff
changeset
|
112 |
2ad145fbde54
wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36103
diff
changeset
|
113 out = util.stringio() |
2ad145fbde54
wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36103
diff
changeset
|
114 |
2ad145fbde54
wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36103
diff
changeset
|
115 try: |
2ad145fbde54
wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36103
diff
changeset
|
116 self._ui.fout = out |
2ad145fbde54
wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36103
diff
changeset
|
117 self._ui.ferr = out |
2ad145fbde54
wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36103
diff
changeset
|
118 yield out |
2ad145fbde54
wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36103
diff
changeset
|
119 finally: |
2ad145fbde54
wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36103
diff
changeset
|
120 self._ui.fout = oldout |
2ad145fbde54
wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36103
diff
changeset
|
121 self._ui.ferr = olderr |
2ad145fbde54
wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36103
diff
changeset
|
122 |
36107
957e773614d0
wireprotoserver: rename _client to client (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36106
diff
changeset
|
123 def client(self): |
11595
368cd5325348
protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents:
11594
diff
changeset
|
124 return 'remote:%s:%s:%s' % ( |
36873
a755fd3b7146
hgweb: expose URL scheme and REMOTE_* attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36868
diff
changeset
|
125 self._req.urlscheme, |
a755fd3b7146
hgweb: expose URL scheme and REMOTE_* attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36868
diff
changeset
|
126 urlreq.quote(self._req.remotehost or ''), |
a755fd3b7146
hgweb: expose URL scheme and REMOTE_* attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36868
diff
changeset
|
127 urlreq.quote(self._req.remoteuser or '')) |
11595
368cd5325348
protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents:
11594
diff
changeset
|
128 |
36642
6e585bca962e
wireproto: add transport specific capabilities in the transport
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36639
diff
changeset
|
129 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
|
130 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
|
131 |
36642
6e585bca962e
wireproto: add transport specific capabilities in the transport
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36639
diff
changeset
|
132 caps.append('httpheader=%d' % |
6e585bca962e
wireproto: add transport specific capabilities in the transport
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36639
diff
changeset
|
133 repo.ui.configint('server', 'maxhttpheaderlen')) |
6e585bca962e
wireproto: add transport specific capabilities in the transport
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36639
diff
changeset
|
134 if repo.ui.configbool('experimental', 'httppostargs'): |
6e585bca962e
wireproto: add transport specific capabilities in the transport
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36639
diff
changeset
|
135 caps.append('httppostargs') |
6e585bca962e
wireproto: add transport specific capabilities in the transport
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36639
diff
changeset
|
136 |
6e585bca962e
wireproto: add transport specific capabilities in the transport
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36639
diff
changeset
|
137 # 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
|
138 # FUTURE advertise minrx and mintx after consulting config option |
6e585bca962e
wireproto: add transport specific capabilities in the transport
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36639
diff
changeset
|
139 caps.append('httpmediatype=0.1rx,0.1tx,0.2tx') |
6e585bca962e
wireproto: add transport specific capabilities in the transport
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36639
diff
changeset
|
140 |
6e585bca962e
wireproto: add transport specific capabilities in the transport
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36639
diff
changeset
|
141 compengines = wireproto.supportedcompengines(repo.ui, util.SERVERROLE) |
6e585bca962e
wireproto: add transport specific capabilities in the transport
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36639
diff
changeset
|
142 if compengines: |
6e585bca962e
wireproto: add transport specific capabilities in the transport
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36639
diff
changeset
|
143 comptypes = ','.join(urlreq.quote(e.wireprotosupport().name) |
6e585bca962e
wireproto: add transport specific capabilities in the transport
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36639
diff
changeset
|
144 for e in compengines) |
6e585bca962e
wireproto: add transport specific capabilities in the transport
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36639
diff
changeset
|
145 caps.append('compression=%s' % comptypes) |
6e585bca962e
wireproto: add transport specific capabilities in the transport
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36639
diff
changeset
|
146 |
6e585bca962e
wireproto: add transport specific capabilities in the transport
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36639
diff
changeset
|
147 return caps |
6e585bca962e
wireproto: add transport specific capabilities in the transport
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36639
diff
changeset
|
148 |
36809
66de4555cefd
wireproto: formalize permissions checking as part of protocol interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36808
diff
changeset
|
149 def checkperm(self, perm): |
66de4555cefd
wireproto: formalize permissions checking as part of protocol interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36808
diff
changeset
|
150 return self._checkperm(perm) |
66de4555cefd
wireproto: formalize permissions checking as part of protocol interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36808
diff
changeset
|
151 |
36269
72812ad205d1
wireprotoserver: return to using iscmd() method
Augie Fackler <augie@google.com>
parents:
36261
diff
changeset
|
152 # 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
|
153 # 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
|
154 # 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
|
155 # 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
|
156 def iscmd(cmd): |
368cd5325348
protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents:
11594
diff
changeset
|
157 return cmd in wireproto.commands |
368cd5325348
protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents:
11594
diff
changeset
|
158 |
36883
02bea04b4c54
hgweb: transition permissions hooks to modern request type (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36873
diff
changeset
|
159 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
|
160 """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
|
161 |
36820
158d4ecc03c8
wireprotoserver: move all wire protocol handling logic out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36818
diff
changeset
|
162 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
|
163 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
|
164 |
36818
886fba199022
hgweb: only recognize wire protocol commands from query string (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36812
diff
changeset
|
165 ``req`` is a ``parsedrequest`` instance. |
36867
a88d68dc3ee8
hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36863
diff
changeset
|
166 ``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
|
167 |
36867
a88d68dc3ee8
hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36863
diff
changeset
|
168 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
|
169 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
|
170 """ |
36820
158d4ecc03c8
wireprotoserver: move all wire protocol handling logic out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36818
diff
changeset
|
171 # 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
|
172 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
|
173 |
36809
66de4555cefd
wireproto: formalize permissions checking as part of protocol interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36808
diff
changeset
|
174 repo = rctx.repo |
66de4555cefd
wireproto: formalize permissions checking as part of protocol interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36808
diff
changeset
|
175 |
36023
cdc93fe1da77
wireprotoserver: move protocol parsing and dispatch out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36021
diff
changeset
|
176 # 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
|
177 # 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
|
178 # request. |
36868
ec0af9c59270
hgweb: use a multidict for holding query string parameters
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36867
diff
changeset
|
179 if 'cmd' not in req.qsparams: |
36867
a88d68dc3ee8
hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36863
diff
changeset
|
180 return False |
36023
cdc93fe1da77
wireprotoserver: move protocol parsing and dispatch out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36021
diff
changeset
|
181 |
36868
ec0af9c59270
hgweb: use a multidict for holding query string parameters
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36867
diff
changeset
|
182 cmd = req.qsparams['cmd'] |
36023
cdc93fe1da77
wireprotoserver: move protocol parsing and dispatch out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36021
diff
changeset
|
183 |
cdc93fe1da77
wireprotoserver: move protocol parsing and dispatch out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36021
diff
changeset
|
184 # 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
|
185 # 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
|
186 # 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
|
187 # 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
|
188 # 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
|
189 # 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
|
190 # clients. |
36269
72812ad205d1
wireprotoserver: return to using iscmd() method
Augie Fackler <augie@google.com>
parents:
36261
diff
changeset
|
191 if not iscmd(cmd): |
36867
a88d68dc3ee8
hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36863
diff
changeset
|
192 return False |
36820
158d4ecc03c8
wireprotoserver: move all wire protocol handling logic out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36818
diff
changeset
|
193 |
158d4ecc03c8
wireprotoserver: move all wire protocol handling logic out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36818
diff
changeset
|
194 # 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
|
195 # 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
|
196 # 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
|
197 # 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
|
198 if req.dispatchpath: |
36867
a88d68dc3ee8
hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36863
diff
changeset
|
199 res.status = hgwebcommon.statusmessage(404) |
a88d68dc3ee8
hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36863
diff
changeset
|
200 res.headers['Content-Type'] = HGTYPE |
a88d68dc3ee8
hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36863
diff
changeset
|
201 # 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
|
202 # is mostly for BC for now. |
a88d68dc3ee8
hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36863
diff
changeset
|
203 res.setbodybytes('0\n%s\n' % b'Not Found') |
a88d68dc3ee8
hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36863
diff
changeset
|
204 return True |
36023
cdc93fe1da77
wireprotoserver: move protocol parsing and dispatch out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36021
diff
changeset
|
205 |
36873
a755fd3b7146
hgweb: expose URL scheme and REMOTE_* attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36868
diff
changeset
|
206 proto = httpv1protocolhandler(req, repo.ui, |
36883
02bea04b4c54
hgweb: transition permissions hooks to modern request type (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36873
diff
changeset
|
207 lambda perm: checkperm(rctx, req, perm)) |
30764
e75463e3179f
protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
208 |
36820
158d4ecc03c8
wireprotoserver: move all wire protocol handling logic out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36818
diff
changeset
|
209 # 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
|
210 # 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
|
211 # 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
|
212 # 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
|
213 try: |
36873
a755fd3b7146
hgweb: expose URL scheme and REMOTE_* attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36868
diff
changeset
|
214 _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
|
215 except hgwebcommon.ErrorResponse as e: |
36867
a88d68dc3ee8
hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36863
diff
changeset
|
216 for k, v in e.headers: |
a88d68dc3ee8
hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36863
diff
changeset
|
217 res.headers[k] = v |
a88d68dc3ee8
hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36863
diff
changeset
|
218 res.status = hgwebcommon.statusmessage(e.code, pycompat.bytestr(e)) |
a88d68dc3ee8
hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36863
diff
changeset
|
219 # 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
|
220 # "unbundle." That assumption is not always valid. |
a88d68dc3ee8
hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36863
diff
changeset
|
221 res.setbodybytes('0\n%s\n' % pycompat.bytestr(e)) |
36820
158d4ecc03c8
wireprotoserver: move all wire protocol handling logic out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36818
diff
changeset
|
222 |
36867
a88d68dc3ee8
hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36863
diff
changeset
|
223 return True |
36023
cdc93fe1da77
wireprotoserver: move protocol parsing and dispatch out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36021
diff
changeset
|
224 |
37049
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
225 def handlewsgiapirequest(rctx, req, res, checkperm): |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
226 """Handle requests to /api/*.""" |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
227 assert req.dispatchparts[0] == b'api' |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
228 |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
229 repo = rctx.repo |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
230 |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
231 # This whole URL space is experimental for now. But we want to |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
232 # reserve the URL space. So, 404 all URLs if the feature isn't enabled. |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
233 if not repo.ui.configbool('experimental', 'web.apiserver'): |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
234 res.status = b'404 Not Found' |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
235 res.headers[b'Content-Type'] = b'text/plain' |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
236 res.setbodybytes(_('Experimental API server endpoint not enabled')) |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
237 return |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
238 |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
239 # The URL space is /api/<protocol>/*. The structure of URLs under varies |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
240 # by <protocol>. |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
241 |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
242 # Registered APIs are made available via config options of the name of |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
243 # the protocol. |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
244 availableapis = set() |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
245 for k, v in API_HANDLERS.items(): |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
246 section, option = v['config'] |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
247 if repo.ui.configbool(section, option): |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
248 availableapis.add(k) |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
249 |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
250 # Requests to /api/ list available APIs. |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
251 if req.dispatchparts == [b'api']: |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
252 res.status = b'200 OK' |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
253 res.headers[b'Content-Type'] = b'text/plain' |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
254 lines = [_('APIs can be accessed at /api/<name>, where <name> can be ' |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
255 'one of the following:\n')] |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
256 if availableapis: |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
257 lines.extend(sorted(availableapis)) |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
258 else: |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
259 lines.append(_('(no available APIs)\n')) |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
260 res.setbodybytes(b'\n'.join(lines)) |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
261 return |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
262 |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
263 proto = req.dispatchparts[1] |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
264 |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
265 if proto not in API_HANDLERS: |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
266 res.status = b'404 Not Found' |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
267 res.headers[b'Content-Type'] = b'text/plain' |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
268 res.setbodybytes(_('Unknown API: %s\nKnown APIs: %s') % ( |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
269 proto, b', '.join(sorted(availableapis)))) |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
270 return |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
271 |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
272 if proto not in availableapis: |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
273 res.status = b'404 Not Found' |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
274 res.headers[b'Content-Type'] = b'text/plain' |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
275 res.setbodybytes(_('API %s not enabled\n') % proto) |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
276 return |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
277 |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
278 API_HANDLERS[proto]['handler'](rctx, req, res, checkperm, |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
279 req.dispatchparts[2:]) |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
280 |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
281 def _handlehttpv2request(rctx, req, res, checkperm, urlparts): |
37050
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
282 from .hgweb import common as hgwebcommon |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
283 |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
284 # URL space looks like: <permissions>/<command>, where <permission> can |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
285 # be ``ro`` or ``rw`` to signal read-only or read-write, respectively. |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
286 |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
287 # Root URL does nothing meaningful... yet. |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
288 if not urlparts: |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
289 res.status = b'200 OK' |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
290 res.headers[b'Content-Type'] = b'text/plain' |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
291 res.setbodybytes(_('HTTP version 2 API handler')) |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
292 return |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
293 |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
294 if len(urlparts) == 1: |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
295 res.status = b'404 Not Found' |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
296 res.headers[b'Content-Type'] = b'text/plain' |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
297 res.setbodybytes(_('do not know how to process %s\n') % |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
298 req.dispatchpath) |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
299 return |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
300 |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
301 permission, command = urlparts[0:2] |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
302 |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
303 if permission not in (b'ro', b'rw'): |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
304 res.status = b'404 Not Found' |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
305 res.headers[b'Content-Type'] = b'text/plain' |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
306 res.setbodybytes(_('unknown permission: %s') % permission) |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
307 return |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
308 |
37051
fc5e261915b9
wireproto: require POST for all HTTPv2 requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37050
diff
changeset
|
309 if req.method != 'POST': |
fc5e261915b9
wireproto: require POST for all HTTPv2 requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37050
diff
changeset
|
310 res.status = b'405 Method Not Allowed' |
fc5e261915b9
wireproto: require POST for all HTTPv2 requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37050
diff
changeset
|
311 res.headers[b'Allow'] = b'POST' |
fc5e261915b9
wireproto: require POST for all HTTPv2 requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37050
diff
changeset
|
312 res.setbodybytes(_('commands require POST requests')) |
fc5e261915b9
wireproto: require POST for all HTTPv2 requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37050
diff
changeset
|
313 return |
fc5e261915b9
wireproto: require POST for all HTTPv2 requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37050
diff
changeset
|
314 |
37050
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
315 # At some point we'll want to use our own API instead of recycling the |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
316 # behavior of version 1 of the wire protocol... |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
317 # TODO return reasonable responses - not responses that overload the |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
318 # HTTP status line message for error reporting. |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
319 try: |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
320 checkperm(rctx, req, 'pull' if permission == b'ro' else 'push') |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
321 except hgwebcommon.ErrorResponse as e: |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
322 res.status = hgwebcommon.statusmessage(e.code, pycompat.bytestr(e)) |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
323 for k, v in e.headers: |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
324 res.headers[k] = v |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
325 res.setbodybytes('permission denied') |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
326 return |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
327 |
37055
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
328 # We have a special endpoint to reflect the request back at the client. |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
329 if command == b'debugreflect': |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
330 _processhttpv2reflectrequest(rctx.repo.ui, rctx.repo, req, res) |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
331 return |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
332 |
37062
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
333 # Extra commands that we handle that aren't really wire protocol |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
334 # commands. Think extra hard before making this hackery available to |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
335 # extension. |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
336 extracommands = {'multirequest'} |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
337 |
37295
45b39c69fae0
wireproto: separate commands tables for version 1 and 2 commands
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37292
diff
changeset
|
338 if command not in wireproto.commandsv2 and command not in extracommands: |
37050
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
339 res.status = b'404 Not Found' |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
340 res.headers[b'Content-Type'] = b'text/plain' |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
341 res.setbodybytes(_('unknown wire protocol command: %s\n') % command) |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
342 return |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
343 |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
344 repo = rctx.repo |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
345 ui = repo.ui |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
346 |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
347 proto = httpv2protocolhandler(req, ui) |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
348 |
37295
45b39c69fae0
wireproto: separate commands tables for version 1 and 2 commands
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37292
diff
changeset
|
349 if (not wireproto.commandsv2.commandavailable(command, proto) |
37062
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
350 and command not in extracommands): |
37050
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
351 res.status = b'404 Not Found' |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
352 res.headers[b'Content-Type'] = b'text/plain' |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
353 res.setbodybytes(_('invalid wire protocol command: %s') % command) |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
354 return |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
355 |
37132
aaabd709df72
wireproto: review fixups
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37123
diff
changeset
|
356 # TODO consider cases where proxies may add additional Accept headers. |
37054
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37053
diff
changeset
|
357 if req.headers.get(b'Accept') != FRAMINGTYPE: |
37053
37d7a1d18b97
wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
358 res.status = b'406 Not Acceptable' |
37d7a1d18b97
wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
359 res.headers[b'Content-Type'] = b'text/plain' |
37d7a1d18b97
wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
360 res.setbodybytes(_('client MUST specify Accept header with value: %s\n') |
37054
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37053
diff
changeset
|
361 % FRAMINGTYPE) |
37053
37d7a1d18b97
wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
362 return |
37d7a1d18b97
wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
363 |
37055
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
364 if req.headers.get(b'Content-Type') != FRAMINGTYPE: |
37053
37d7a1d18b97
wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
365 res.status = b'415 Unsupported Media Type' |
37d7a1d18b97
wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
366 # TODO we should send a response with appropriate media type, |
37d7a1d18b97
wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
367 # since client does Accept it. |
37d7a1d18b97
wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
368 res.headers[b'Content-Type'] = b'text/plain' |
37d7a1d18b97
wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
369 res.setbodybytes(_('client MUST send Content-Type header with ' |
37054
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37053
diff
changeset
|
370 'value: %s\n') % FRAMINGTYPE) |
37053
37d7a1d18b97
wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
371 return |
37d7a1d18b97
wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
372 |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
373 _processhttpv2request(ui, repo, req, res, permission, command, proto) |
37049
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
374 |
37055
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
375 def _processhttpv2reflectrequest(ui, repo, req, res): |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
376 """Reads unified frame protocol request and dumps out state to client. |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
377 |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
378 This special endpoint can be used to help debug the wire protocol. |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
379 |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
380 Instead of routing the request through the normal dispatch mechanism, |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
381 we instead read all frames, decode them, and feed them into our state |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
382 tracker. We then dump the log of all that activity back out to the |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
383 client. |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
384 """ |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
385 import json |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
386 |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
387 # Reflection APIs have a history of being abused, accidentally disclosing |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
388 # sensitive data, etc. So we have a config knob. |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
389 if not ui.configbool('experimental', 'web.api.debugreflect'): |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
390 res.status = b'404 Not Found' |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
391 res.headers[b'Content-Type'] = b'text/plain' |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
392 res.setbodybytes(_('debugreflect service not available')) |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
393 return |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
394 |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
395 # We assume we have a unified framing protocol request body. |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
396 |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
397 reactor = wireprotoframing.serverreactor() |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
398 states = [] |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
399 |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
400 while True: |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
401 frame = wireprotoframing.readframe(req.bodyfh) |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
402 |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
403 if not frame: |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
404 states.append(b'received: <no frame>') |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
405 break |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
406 |
37064
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37062
diff
changeset
|
407 states.append(b'received: %d %d %d %s' % (frame.typeid, frame.flags, |
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37062
diff
changeset
|
408 frame.requestid, |
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37062
diff
changeset
|
409 frame.payload)) |
37055
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
410 |
37064
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37062
diff
changeset
|
411 action, meta = reactor.onframerecv(frame) |
37055
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
412 states.append(json.dumps((action, meta), sort_keys=True, |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
413 separators=(', ', ': '))) |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
414 |
37059
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
415 action, meta = reactor.oninputeof() |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
416 meta['action'] = action |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
417 states.append(json.dumps(meta, sort_keys=True, separators=(', ',': '))) |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
418 |
37055
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
419 res.status = b'200 OK' |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
420 res.headers[b'Content-Type'] = b'text/plain' |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
421 res.setbodybytes(b'\n'.join(states)) |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
422 |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
423 def _processhttpv2request(ui, repo, req, res, authedperm, reqcommand, proto): |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
424 """Post-validation handler for HTTPv2 requests. |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
425 |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
426 Called when the HTTP request contains unified frame-based protocol |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
427 frames for evaluation. |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
428 """ |
37059
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
429 # TODO Some HTTP clients are full duplex and can receive data before |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
430 # the entire request is transmitted. Figure out a way to indicate support |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
431 # for that so we can opt into full duplex mode. |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
432 reactor = wireprotoframing.serverreactor(deferoutput=True) |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
433 seencommand = False |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
434 |
37289
5fadc63ac99f
wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37288
diff
changeset
|
435 outstream = reactor.makeoutputstream() |
5fadc63ac99f
wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37288
diff
changeset
|
436 |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
437 while True: |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
438 frame = wireprotoframing.readframe(req.bodyfh) |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
439 if not frame: |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
440 break |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
441 |
37064
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37062
diff
changeset
|
442 action, meta = reactor.onframerecv(frame) |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
443 |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
444 if action == 'wantframe': |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
445 # Need more data before we can do anything. |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
446 continue |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
447 elif action == 'runcommand': |
37062
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
448 sentoutput = _httpv2runcommand(ui, repo, req, res, authedperm, |
37289
5fadc63ac99f
wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37288
diff
changeset
|
449 reqcommand, reactor, outstream, |
5fadc63ac99f
wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37288
diff
changeset
|
450 meta, issubsequent=seencommand) |
37062
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
451 |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
452 if sentoutput: |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
453 return |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
454 |
37062
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
455 seencommand = True |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
456 |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
457 elif action == 'error': |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
458 # TODO define proper error mechanism. |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
459 res.status = b'200 OK' |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
460 res.headers[b'Content-Type'] = b'text/plain' |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
461 res.setbodybytes(meta['message'] + b'\n') |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
462 return |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
463 else: |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
464 raise error.ProgrammingError( |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
465 'unhandled action from frame processor: %s' % action) |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
466 |
37059
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
467 action, meta = reactor.oninputeof() |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
468 if action == 'sendframes': |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
469 # We assume we haven't started sending the response yet. If we're |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
470 # wrong, the response type will raise an exception. |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
471 res.status = b'200 OK' |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
472 res.headers[b'Content-Type'] = FRAMINGTYPE |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
473 res.setbodygen(meta['framegen']) |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
474 elif action == 'noop': |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
475 pass |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
476 else: |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
477 raise error.ProgrammingError('unhandled action from frame processor: %s' |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
478 % action) |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
479 |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
480 def _httpv2runcommand(ui, repo, req, res, authedperm, reqcommand, reactor, |
37289
5fadc63ac99f
wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37288
diff
changeset
|
481 outstream, command, issubsequent): |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
482 """Dispatch a wire protocol command made from HTTPv2 requests. |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
483 |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
484 The authenticated permission (``authedperm``) along with the original |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
485 command from the URL (``reqcommand``) are passed in. |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
486 """ |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
487 # We already validated that the session has permissions to perform the |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
488 # actions in ``authedperm``. In the unified frame protocol, the canonical |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
489 # command to run is expressed in a frame. However, the URL also requested |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
490 # to run a specific command. We need to be careful that the command we |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
491 # run doesn't have permissions requirements greater than what was granted |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
492 # by ``authedperm``. |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
493 # |
37062
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
494 # Our rule for this is we only allow one command per HTTP request and |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
495 # that command must match the command in the URL. However, we make |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
496 # an exception for the ``multirequest`` URL. This URL is allowed to |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
497 # execute multiple commands. We double check permissions of each command |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
498 # as it is invoked to ensure there is no privilege escalation. |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
499 # TODO consider allowing multiple commands to regular command URLs |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
500 # iff each command is the same. |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
501 |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
502 proto = httpv2protocolhandler(req, ui, args=command['args']) |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
503 |
37062
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
504 if reqcommand == b'multirequest': |
37295
45b39c69fae0
wireproto: separate commands tables for version 1 and 2 commands
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37292
diff
changeset
|
505 if not wireproto.commandsv2.commandavailable(command['command'], proto): |
37062
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
506 # TODO proper error mechanism |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
507 res.status = b'200 OK' |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
508 res.headers[b'Content-Type'] = b'text/plain' |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
509 res.setbodybytes(_('wire protocol command not available: %s') % |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
510 command['command']) |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
511 return True |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
512 |
37132
aaabd709df72
wireproto: review fixups
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37123
diff
changeset
|
513 # TODO don't use assert here, since it may be elided by -O. |
37062
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
514 assert authedperm in (b'ro', b'rw') |
37295
45b39c69fae0
wireproto: separate commands tables for version 1 and 2 commands
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37292
diff
changeset
|
515 wirecommand = wireproto.commandsv2[command['command']] |
37062
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
516 assert wirecommand.permission in ('push', 'pull') |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
517 |
37062
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
518 if authedperm == b'ro' and wirecommand.permission != 'pull': |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
519 # TODO proper error mechanism |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
520 res.status = b'403 Forbidden' |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
521 res.headers[b'Content-Type'] = b'text/plain' |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
522 res.setbodybytes(_('insufficient permissions to execute ' |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
523 'command: %s') % command['command']) |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
524 return True |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
525 |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
526 # TODO should we also call checkperm() here? Maybe not if we're going |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
527 # to overhaul that API. The granted scope from the URL check should |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
528 # be good enough. |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
529 |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
530 else: |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
531 # Don't allow multiple commands outside of ``multirequest`` URL. |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
532 if issubsequent: |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
533 # TODO proper error mechanism |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
534 res.status = b'200 OK' |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
535 res.headers[b'Content-Type'] = b'text/plain' |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
536 res.setbodybytes(_('multiple commands cannot be issued to this ' |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
537 'URL')) |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
538 return True |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
539 |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
540 if reqcommand != command['command']: |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
541 # TODO define proper error mechanism |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
542 res.status = b'200 OK' |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
543 res.headers[b'Content-Type'] = b'text/plain' |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
544 res.setbodybytes(_('command in frame must match command in URL')) |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
545 return True |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
546 |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
547 rsp = wireproto.dispatch(repo, proto, command['command']) |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
548 |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
549 res.status = b'200 OK' |
37058
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
550 res.headers[b'Content-Type'] = FRAMINGTYPE |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
551 |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
552 if isinstance(rsp, wireprototypes.bytesresponse): |
37289
5fadc63ac99f
wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37288
diff
changeset
|
553 action, meta = reactor.onbytesresponseready(outstream, |
37287
3ed344546d9e
wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37132
diff
changeset
|
554 command['requestid'], |
37060
2ec1fb9de638
wireproto: add request IDs to frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37059
diff
changeset
|
555 rsp.data) |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
556 else: |
37058
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
557 action, meta = reactor.onapplicationerror( |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
558 _('unhandled response type from wire proto command')) |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
559 |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
560 if action == 'sendframes': |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
561 res.setbodygen(meta['framegen']) |
37062
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
562 return True |
37059
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
563 elif action == 'noop': |
37132
aaabd709df72
wireproto: review fixups
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37123
diff
changeset
|
564 return False |
37058
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
565 else: |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
566 raise error.ProgrammingError('unhandled event from reactor: %s' % |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
567 action) |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
568 |
37049
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
569 # Maps API name to metadata so custom API can be registered. |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
570 API_HANDLERS = { |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
571 HTTPV2: { |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
572 'config': ('experimental', 'web.api.http-v2'), |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
573 'handler': _handlehttpv2request, |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
574 }, |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
575 } |
1cfef5693203
wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36883
diff
changeset
|
576 |
37050
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
577 class httpv2protocolhandler(wireprototypes.baseprotocolhandler): |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
578 def __init__(self, req, ui, args=None): |
37050
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
579 self._req = req |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
580 self._ui = ui |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
581 self._args = args |
37050
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
582 |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
583 @property |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
584 def name(self): |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
585 return HTTPV2 |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
586 |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
587 def getargs(self, args): |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
588 data = {} |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
589 for k in args.split(): |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
590 if k == '*': |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
591 raise NotImplementedError('do not support * args') |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
592 else: |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
593 data[k] = self._args[k] |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
594 |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
595 return [data[k] for k in args.split()] |
37050
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
596 |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
597 def forwardpayload(self, fp): |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
598 raise NotImplementedError |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
599 |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
600 @contextlib.contextmanager |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
601 def mayberedirectstdio(self): |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
602 raise NotImplementedError |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
603 |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
604 def client(self): |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
605 raise NotImplementedError |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
606 |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
607 def addcapabilities(self, repo, caps): |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
608 return caps |
37050
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
609 |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
610 def checkperm(self, perm): |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
611 raise NotImplementedError |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
612 |
36852
14f70c44af6c
wireprotoserver: access headers through parsed request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36821
diff
changeset
|
613 def _httpresponsetype(ui, req, prefer_uncompressed): |
36110
341c886e411e
wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36109
diff
changeset
|
614 """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
|
615 |
341c886e411e
wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36109
diff
changeset
|
616 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
|
617 """ |
341c886e411e
wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36109
diff
changeset
|
618 # 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
|
619 # on the request parameters. |
36852
14f70c44af6c
wireprotoserver: access headers through parsed request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36821
diff
changeset
|
620 protocaps = decodevaluefromheaders(req, 'X-HgProto').split(' ') |
36110
341c886e411e
wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36109
diff
changeset
|
621 |
341c886e411e
wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36109
diff
changeset
|
622 if '0.2' in protocaps: |
341c886e411e
wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36109
diff
changeset
|
623 # 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
|
624 if prefer_uncompressed: |
341c886e411e
wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36109
diff
changeset
|
625 return HGTYPE2, util._noopengine(), {} |
341c886e411e
wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36109
diff
changeset
|
626 |
341c886e411e
wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36109
diff
changeset
|
627 # Default as defined by wire protocol spec. |
341c886e411e
wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36109
diff
changeset
|
628 compformats = ['zlib', 'none'] |
341c886e411e
wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36109
diff
changeset
|
629 for cap in protocaps: |
341c886e411e
wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36109
diff
changeset
|
630 if cap.startswith('comp='): |
341c886e411e
wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36109
diff
changeset
|
631 compformats = cap[5:].split(',') |
341c886e411e
wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36109
diff
changeset
|
632 break |
341c886e411e
wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36109
diff
changeset
|
633 |
341c886e411e
wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36109
diff
changeset
|
634 # Now find an agreed upon compression format. |
341c886e411e
wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36109
diff
changeset
|
635 for engine in wireproto.supportedcompengines(ui, util.SERVERROLE): |
341c886e411e
wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36109
diff
changeset
|
636 if engine.wireprotosupport().name in compformats: |
341c886e411e
wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36109
diff
changeset
|
637 opts = {} |
341c886e411e
wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36109
diff
changeset
|
638 level = ui.configint('server', '%slevel' % engine.name()) |
341c886e411e
wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36109
diff
changeset
|
639 if level is not None: |
341c886e411e
wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36109
diff
changeset
|
640 opts['level'] = level |
341c886e411e
wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36109
diff
changeset
|
641 |
341c886e411e
wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36109
diff
changeset
|
642 return HGTYPE2, engine, opts |
341c886e411e
wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36109
diff
changeset
|
643 |
341c886e411e
wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36109
diff
changeset
|
644 # 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
|
645 # legacy protocol. |
341c886e411e
wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36109
diff
changeset
|
646 |
341c886e411e
wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36109
diff
changeset
|
647 # 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
|
648 # 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
|
649 # the server's network or CPU. |
341c886e411e
wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36109
diff
changeset
|
650 opts = {'level': ui.configint('server', 'zliblevel')} |
341c886e411e
wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36109
diff
changeset
|
651 return HGTYPE, util.compengines['zlib'], opts |
341c886e411e
wireprotoserver: move responsetype() out of http handler
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36109
diff
changeset
|
652 |
36873
a755fd3b7146
hgweb: expose URL scheme and REMOTE_* attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36868
diff
changeset
|
653 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
|
654 # Avoid cycle involving hg module. |
a88d68dc3ee8
hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36863
diff
changeset
|
655 from .hgweb import common as hgwebcommon |
a88d68dc3ee8
hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36863
diff
changeset
|
656 |
35750
a39a9df7ecca
wireproto: split streamres into legacy and modern case
Joerg Sonnenberger <joerg@bec.de>
parents:
35705
diff
changeset
|
657 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
|
658 # 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
|
659 # 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
|
660 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
|
661 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
|
662 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
|
663 yield name |
e75463e3179f
protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
664 |
35750
a39a9df7ecca
wireproto: split streamres into legacy and modern case
Joerg Sonnenberger <joerg@bec.de>
parents:
35705
diff
changeset
|
665 for chunk in gen: |
a39a9df7ecca
wireproto: split streamres into legacy and modern case
Joerg Sonnenberger <joerg@bec.de>
parents:
35705
diff
changeset
|
666 yield chunk |
30764
e75463e3179f
protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
667 |
36867
a88d68dc3ee8
hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36863
diff
changeset
|
668 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
|
669 if code == HTTP_OK: |
a88d68dc3ee8
hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36863
diff
changeset
|
670 res.status = '200 Script output follows' |
a88d68dc3ee8
hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36863
diff
changeset
|
671 else: |
a88d68dc3ee8
hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36863
diff
changeset
|
672 res.status = hgwebcommon.statusmessage(code) |
a88d68dc3ee8
hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36863
diff
changeset
|
673 |
a88d68dc3ee8
hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36863
diff
changeset
|
674 res.headers['Content-Type'] = contenttype |
a88d68dc3ee8
hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36863
diff
changeset
|
675 |
a88d68dc3ee8
hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36863
diff
changeset
|
676 if bodybytes is not None: |
a88d68dc3ee8
hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36863
diff
changeset
|
677 res.setbodybytes(bodybytes) |
a88d68dc3ee8
hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36863
diff
changeset
|
678 if bodygen is not None: |
a88d68dc3ee8
hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36863
diff
changeset
|
679 res.setbodygen(bodygen) |
a88d68dc3ee8
hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36863
diff
changeset
|
680 |
36021
5a56bf4180ad
wireproto: function for testing if wire protocol command is available
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36015
diff
changeset
|
681 if not wireproto.commands.commandavailable(cmd, proto): |
36867
a88d68dc3ee8
hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36863
diff
changeset
|
682 setresponse(HTTP_OK, HGERRTYPE, |
a88d68dc3ee8
hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36863
diff
changeset
|
683 _('requested wire protocol command is not available over ' |
a88d68dc3ee8
hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36863
diff
changeset
|
684 'HTTP')) |
a88d68dc3ee8
hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36863
diff
changeset
|
685 return |
36021
5a56bf4180ad
wireproto: function for testing if wire protocol command is available
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36015
diff
changeset
|
686 |
36809
66de4555cefd
wireproto: formalize permissions checking as part of protocol interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36808
diff
changeset
|
687 proto.checkperm(wireproto.commands[cmd].permission) |
36807
c638a13093cf
wireprotoserver: check permissions in main dispatch function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36806
diff
changeset
|
688 |
36806
7574c8173d5e
wireprotoserver: check if command available before calling it
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36768
diff
changeset
|
689 rsp = wireproto.dispatch(repo, proto, cmd) |
7574c8173d5e
wireprotoserver: check if command available before calling it
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36768
diff
changeset
|
690 |
34510
c23fa3103925
hgweb: in protocol adapter, look for bytes instances, not str
Augie Fackler <augie@google.com>
parents:
34509
diff
changeset
|
691 if isinstance(rsp, bytes): |
36867
a88d68dc3ee8
hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36863
diff
changeset
|
692 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
|
693 elif isinstance(rsp, wireprototypes.bytesresponse): |
36867
a88d68dc3ee8
hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36863
diff
changeset
|
694 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
|
695 elif isinstance(rsp, wireprototypes.streamreslegacy): |
36867
a88d68dc3ee8
hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36863
diff
changeset
|
696 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
|
697 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
|
698 gen = rsp.gen |
30475
2add671bf55b
wireproto: perform chunking and compression at protocol layer (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30376
diff
changeset
|
699 |
30764
e75463e3179f
protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
700 # 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
|
701 # 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
|
702 mediatype, engine, engineopts = _httpresponsetype( |
36852
14f70c44af6c
wireprotoserver: access headers through parsed request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36821
diff
changeset
|
703 repo.ui, req, rsp.prefer_uncompressed) |
35750
a39a9df7ecca
wireproto: split streamres into legacy and modern case
Joerg Sonnenberger <joerg@bec.de>
parents:
35705
diff
changeset
|
704 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
|
705 |
35750
a39a9df7ecca
wireproto: split streamres into legacy and modern case
Joerg Sonnenberger <joerg@bec.de>
parents:
35705
diff
changeset
|
706 if mediatype == HGTYPE2: |
a39a9df7ecca
wireproto: split streamres into legacy and modern case
Joerg Sonnenberger <joerg@bec.de>
parents:
35705
diff
changeset
|
707 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
|
708 |
36867
a88d68dc3ee8
hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36863
diff
changeset
|
709 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
|
710 elif isinstance(rsp, wireprototypes.pushres): |
36105
caca3ac2ac04
wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36104
diff
changeset
|
711 rsp = '%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
|
712 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
|
713 elif isinstance(rsp, wireprototypes.pusherr): |
12703
40bb5853fc4b
wireproto: introduce pusherr() to deal with "unsynced changes" error
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
11626
diff
changeset
|
714 rsp = '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
|
715 res.drain = True |
a88d68dc3ee8
hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36863
diff
changeset
|
716 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
|
717 elif isinstance(rsp, wireprototypes.ooberror): |
36867
a88d68dc3ee8
hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36863
diff
changeset
|
718 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
|
719 else: |
a88d68dc3ee8
hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36863
diff
changeset
|
720 raise error.ProgrammingError('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
|
721 |
36102
5767664d39a5
wireprotoserver: extract SSH response handling functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36027
diff
changeset
|
722 def _sshv1respondbytes(fout, value): |
5767664d39a5
wireprotoserver: extract SSH response handling functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36027
diff
changeset
|
723 """Send a bytes response for protocol version 1.""" |
5767664d39a5
wireprotoserver: extract SSH response handling functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36027
diff
changeset
|
724 fout.write('%d\n' % len(value)) |
5767664d39a5
wireprotoserver: extract SSH response handling functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36027
diff
changeset
|
725 fout.write(value) |
5767664d39a5
wireprotoserver: extract SSH response handling functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36027
diff
changeset
|
726 fout.flush() |
5767664d39a5
wireprotoserver: extract SSH response handling functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36027
diff
changeset
|
727 |
5767664d39a5
wireprotoserver: extract SSH response handling functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36027
diff
changeset
|
728 def _sshv1respondstream(fout, source): |
5767664d39a5
wireprotoserver: extract SSH response handling functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36027
diff
changeset
|
729 write = fout.write |
5767664d39a5
wireprotoserver: extract SSH response handling functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36027
diff
changeset
|
730 for chunk in source.gen: |
5767664d39a5
wireprotoserver: extract SSH response handling functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36027
diff
changeset
|
731 write(chunk) |
5767664d39a5
wireprotoserver: extract SSH response handling functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36027
diff
changeset
|
732 fout.flush() |
5767664d39a5
wireprotoserver: extract SSH response handling functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36027
diff
changeset
|
733 |
5767664d39a5
wireprotoserver: extract SSH response handling functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36027
diff
changeset
|
734 def _sshv1respondooberror(fout, ferr, rsp): |
5767664d39a5
wireprotoserver: extract SSH response handling functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36027
diff
changeset
|
735 ferr.write(b'%s\n-\n' % rsp) |
5767664d39a5
wireprotoserver: extract SSH response handling functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36027
diff
changeset
|
736 ferr.flush() |
5767664d39a5
wireprotoserver: extract SSH response handling functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36027
diff
changeset
|
737 fout.write(b'\n') |
5767664d39a5
wireprotoserver: extract SSH response handling functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36027
diff
changeset
|
738 fout.flush() |
5767664d39a5
wireprotoserver: extract SSH response handling functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36027
diff
changeset
|
739 |
36402
0c231df1ffdc
wireprototypes: move baseprotocolhandler from wireprotoserver
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36313
diff
changeset
|
740 class sshv1protocolhandler(wireprototypes.baseprotocolhandler): |
36103
bf676267f64f
wireprotoserver: split ssh protocol handler and server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36102
diff
changeset
|
741 """Handler for requests services via version 1 of SSH protocol.""" |
bf676267f64f
wireprotoserver: split ssh protocol handler and server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36102
diff
changeset
|
742 def __init__(self, ui, fin, fout): |
35910
f1efc0caeab7
wireprotoserver: make some instance attributes private
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35909
diff
changeset
|
743 self._ui = ui |
36103
bf676267f64f
wireprotoserver: split ssh protocol handler and server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36102
diff
changeset
|
744 self._fin = fin |
bf676267f64f
wireprotoserver: split ssh protocol handler and server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36102
diff
changeset
|
745 self._fout = fout |
35899
1bf5263fe5cc
wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35898
diff
changeset
|
746 |
35913
29759c46aa1a
wireprotoserver: make name part of protocol interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35912
diff
changeset
|
747 @property |
29759c46aa1a
wireprotoserver: make name part of protocol interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35912
diff
changeset
|
748 def name(self): |
36565
3cd245945ef3
wireprotoserver: move SSHV1 and SSHV2 constants to wireprototypes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36555
diff
changeset
|
749 return wireprototypes.SSHV1 |
35913
29759c46aa1a
wireprotoserver: make name part of protocol interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35912
diff
changeset
|
750 |
35899
1bf5263fe5cc
wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35898
diff
changeset
|
751 def getargs(self, args): |
1bf5263fe5cc
wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35898
diff
changeset
|
752 data = {} |
1bf5263fe5cc
wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35898
diff
changeset
|
753 keys = args.split() |
1bf5263fe5cc
wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35898
diff
changeset
|
754 for n in xrange(len(keys)): |
35910
f1efc0caeab7
wireprotoserver: make some instance attributes private
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35909
diff
changeset
|
755 argline = self._fin.readline()[:-1] |
35899
1bf5263fe5cc
wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35898
diff
changeset
|
756 arg, l = argline.split() |
1bf5263fe5cc
wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35898
diff
changeset
|
757 if arg not in keys: |
1bf5263fe5cc
wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35898
diff
changeset
|
758 raise error.Abort(_("unexpected parameter %r") % arg) |
1bf5263fe5cc
wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35898
diff
changeset
|
759 if arg == '*': |
1bf5263fe5cc
wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35898
diff
changeset
|
760 star = {} |
1bf5263fe5cc
wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35898
diff
changeset
|
761 for k in xrange(int(l)): |
35910
f1efc0caeab7
wireprotoserver: make some instance attributes private
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35909
diff
changeset
|
762 argline = self._fin.readline()[:-1] |
35899
1bf5263fe5cc
wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35898
diff
changeset
|
763 arg, l = argline.split() |
35910
f1efc0caeab7
wireprotoserver: make some instance attributes private
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35909
diff
changeset
|
764 val = self._fin.read(int(l)) |
35899
1bf5263fe5cc
wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35898
diff
changeset
|
765 star[arg] = val |
1bf5263fe5cc
wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35898
diff
changeset
|
766 data['*'] = star |
1bf5263fe5cc
wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35898
diff
changeset
|
767 else: |
35910
f1efc0caeab7
wireprotoserver: make some instance attributes private
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35909
diff
changeset
|
768 val = self._fin.read(int(l)) |
35899
1bf5263fe5cc
wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35898
diff
changeset
|
769 data[arg] = val |
1bf5263fe5cc
wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35898
diff
changeset
|
770 return [data[k] for k in keys] |
1bf5263fe5cc
wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35898
diff
changeset
|
771 |
36108
90ca4986616c
wireprotoserver: rename getfile() to forwardpayload() (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36107
diff
changeset
|
772 def forwardpayload(self, fpout): |
36403
b8d0761a85c7
wireproto: document the wonky push protocol for SSH
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36402
diff
changeset
|
773 # 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
|
774 # 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
|
775 # interprets it as an error. |
b8d0761a85c7
wireproto: document the wonky push protocol for SSH
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36402
diff
changeset
|
776 _sshv1respondbytes(self._fout, b'') |
b8d0761a85c7
wireproto: document the wonky push protocol for SSH
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36402
diff
changeset
|
777 |
36108
90ca4986616c
wireprotoserver: rename getfile() to forwardpayload() (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36107
diff
changeset
|
778 # The file is in the form: |
90ca4986616c
wireprotoserver: rename getfile() to forwardpayload() (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36107
diff
changeset
|
779 # |
90ca4986616c
wireprotoserver: rename getfile() to forwardpayload() (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36107
diff
changeset
|
780 # <chunk size>\n<chunk> |
90ca4986616c
wireprotoserver: rename getfile() to forwardpayload() (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36107
diff
changeset
|
781 # ... |
90ca4986616c
wireprotoserver: rename getfile() to forwardpayload() (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36107
diff
changeset
|
782 # 0\n |
35910
f1efc0caeab7
wireprotoserver: make some instance attributes private
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35909
diff
changeset
|
783 count = int(self._fin.readline()) |
35899
1bf5263fe5cc
wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35898
diff
changeset
|
784 while count: |
35910
f1efc0caeab7
wireprotoserver: make some instance attributes private
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35909
diff
changeset
|
785 fpout.write(self._fin.read(count)) |
f1efc0caeab7
wireprotoserver: make some instance attributes private
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35909
diff
changeset
|
786 count = int(self._fin.readline()) |
35899
1bf5263fe5cc
wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35898
diff
changeset
|
787 |
36104
2ad145fbde54
wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36103
diff
changeset
|
788 @contextlib.contextmanager |
2ad145fbde54
wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36103
diff
changeset
|
789 def mayberedirectstdio(self): |
2ad145fbde54
wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36103
diff
changeset
|
790 yield None |
2ad145fbde54
wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36103
diff
changeset
|
791 |
36107
957e773614d0
wireprotoserver: rename _client to client (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36106
diff
changeset
|
792 def client(self): |
36103
bf676267f64f
wireprotoserver: split ssh protocol handler and server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36102
diff
changeset
|
793 client = encoding.environ.get('SSH_CLIENT', '').split(' ', 1)[0] |
bf676267f64f
wireprotoserver: split ssh protocol handler and server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36102
diff
changeset
|
794 return 'remote:ssh:' + client |
bf676267f64f
wireprotoserver: split ssh protocol handler and server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36102
diff
changeset
|
795 |
36642
6e585bca962e
wireproto: add transport specific capabilities in the transport
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36639
diff
changeset
|
796 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
|
797 caps.append(b'batch') |
36642
6e585bca962e
wireproto: add transport specific capabilities in the transport
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36639
diff
changeset
|
798 return caps |
6e585bca962e
wireproto: add transport specific capabilities in the transport
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36639
diff
changeset
|
799 |
36809
66de4555cefd
wireproto: formalize permissions checking as part of protocol interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36808
diff
changeset
|
800 def checkperm(self, perm): |
66de4555cefd
wireproto: formalize permissions checking as part of protocol interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36808
diff
changeset
|
801 pass |
66de4555cefd
wireproto: formalize permissions checking as part of protocol interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36808
diff
changeset
|
802 |
36253
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
803 class sshv2protocolhandler(sshv1protocolhandler): |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
804 """Protocol handler for version 2 of the SSH protocol.""" |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
805 |
36639
af0d38f015bb
wireprotoserver: identify requests via version 2 of SSH protocol as such
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36565
diff
changeset
|
806 @property |
af0d38f015bb
wireprotoserver: identify requests via version 2 of SSH protocol as such
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36565
diff
changeset
|
807 def name(self): |
af0d38f015bb
wireprotoserver: identify requests via version 2 of SSH protocol as such
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36565
diff
changeset
|
808 return wireprototypes.SSHV2 |
af0d38f015bb
wireprotoserver: identify requests via version 2 of SSH protocol as such
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36565
diff
changeset
|
809 |
36552
e7411fb7ba7f
wireprotoserver: ability to run an SSH server until an event is set
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36403
diff
changeset
|
810 def _runsshserver(ui, repo, fin, fout, ev): |
36253
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
811 # 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
|
812 # states are defined: |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
813 # |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
814 # protov1-serving |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
815 # 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
|
816 # 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
|
817 # after the other. |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
818 # |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
819 # protov2-serving |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
820 # Server is in protocol version 2 serving mode. |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
821 # |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
822 # upgrade-initial |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
823 # The server is going to process an upgrade request. |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
824 # |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
825 # upgrade-v2-filter-legacy-handshake |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
826 # The protocol is being upgraded to version 2. The server is expecting |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
827 # the legacy handshake from version 1. |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
828 # |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
829 # upgrade-v2-finish |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
830 # The upgrade to version 2 of the protocol is imminent. |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
831 # |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
832 # shutdown |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
833 # 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
|
834 # |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
835 # And here are their transitions: |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
836 # |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
837 # protov1-serving -> shutdown |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
838 # 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
|
839 # error. |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
840 # |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
841 # protov1-serving -> upgrade-initial |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
842 # An upgrade request line was seen. |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
843 # |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
844 # upgrade-initial -> upgrade-v2-filter-legacy-handshake |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
845 # Upgrade to version 2 in progress. Server is expecting to |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
846 # process a legacy handshake. |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
847 # |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
848 # upgrade-v2-filter-legacy-handshake -> shutdown |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
849 # Client did not fulfill upgrade handshake requirements. |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
850 # |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
851 # upgrade-v2-filter-legacy-handshake -> upgrade-v2-finish |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
852 # Client fulfilled version 2 upgrade requirements. Finishing that |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
853 # upgrade. |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
854 # |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
855 # upgrade-v2-finish -> protov2-serving |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
856 # Protocol upgrade to version 2 complete. Server can now speak protocol |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
857 # version 2. |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
858 # |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
859 # protov2-serving -> protov1-serving |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
860 # Ths happens by default since protocol version 2 is the same as |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
861 # version 1 except for the handshake. |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
862 |
36252
3b3a987bbbaa
wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36251
diff
changeset
|
863 state = 'protov1-serving' |
3b3a987bbbaa
wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36251
diff
changeset
|
864 proto = sshv1protocolhandler(ui, fin, fout) |
36253
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
865 protoswitched = False |
36252
3b3a987bbbaa
wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36251
diff
changeset
|
866 |
36552
e7411fb7ba7f
wireprotoserver: ability to run an SSH server until an event is set
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36403
diff
changeset
|
867 while not ev.is_set(): |
36252
3b3a987bbbaa
wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36251
diff
changeset
|
868 if state == 'protov1-serving': |
3b3a987bbbaa
wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36251
diff
changeset
|
869 # 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
|
870 request = fin.readline()[:-1] |
3b3a987bbbaa
wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36251
diff
changeset
|
871 |
3b3a987bbbaa
wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36251
diff
changeset
|
872 # 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
|
873 if not request: |
3b3a987bbbaa
wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36251
diff
changeset
|
874 state = 'shutdown' |
3b3a987bbbaa
wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36251
diff
changeset
|
875 continue |
3b3a987bbbaa
wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36251
diff
changeset
|
876 |
36253
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
877 # It looks like a protocol upgrade request. Transition state to |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
878 # handle it. |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
879 if request.startswith(b'upgrade '): |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
880 if protoswitched: |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
881 _sshv1respondooberror(fout, ui.ferr, |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
882 b'cannot upgrade protocols multiple ' |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
883 b'times') |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
884 state = 'shutdown' |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
885 continue |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
886 |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
887 state = 'upgrade-initial' |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
888 continue |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
889 |
36252
3b3a987bbbaa
wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36251
diff
changeset
|
890 available = wireproto.commands.commandavailable(request, proto) |
3b3a987bbbaa
wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36251
diff
changeset
|
891 |
3b3a987bbbaa
wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36251
diff
changeset
|
892 # 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
|
893 # 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
|
894 if not available: |
3b3a987bbbaa
wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36251
diff
changeset
|
895 _sshv1respondbytes(fout, b'') |
3b3a987bbbaa
wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36251
diff
changeset
|
896 continue |
3b3a987bbbaa
wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36251
diff
changeset
|
897 |
3b3a987bbbaa
wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36251
diff
changeset
|
898 rsp = wireproto.dispatch(repo, proto, request) |
3b3a987bbbaa
wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36251
diff
changeset
|
899 |
3b3a987bbbaa
wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36251
diff
changeset
|
900 if isinstance(rsp, bytes): |
3b3a987bbbaa
wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36251
diff
changeset
|
901 _sshv1respondbytes(fout, rsp) |
3b3a987bbbaa
wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36251
diff
changeset
|
902 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
|
903 _sshv1respondbytes(fout, rsp.data) |
3b3a987bbbaa
wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36251
diff
changeset
|
904 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
|
905 _sshv1respondstream(fout, rsp) |
3b3a987bbbaa
wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36251
diff
changeset
|
906 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
|
907 _sshv1respondstream(fout, rsp) |
3b3a987bbbaa
wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36251
diff
changeset
|
908 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
|
909 _sshv1respondbytes(fout, b'') |
3b3a987bbbaa
wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36251
diff
changeset
|
910 _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
|
911 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
|
912 _sshv1respondbytes(fout, rsp.res) |
3b3a987bbbaa
wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36251
diff
changeset
|
913 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
|
914 _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
|
915 else: |
3b3a987bbbaa
wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36251
diff
changeset
|
916 raise error.ProgrammingError('unhandled response type from ' |
3b3a987bbbaa
wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36251
diff
changeset
|
917 'wire protocol command: %s' % rsp) |
3b3a987bbbaa
wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36251
diff
changeset
|
918 |
36253
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
919 # For now, protocol version 2 serving just goes back to version 1. |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
920 elif state == 'protov2-serving': |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
921 state = 'protov1-serving' |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
922 continue |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
923 |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
924 elif state == 'upgrade-initial': |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
925 # We should never transition into this state if we've switched |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
926 # protocols. |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
927 assert not protoswitched |
36565
3cd245945ef3
wireprotoserver: move SSHV1 and SSHV2 constants to wireprototypes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36555
diff
changeset
|
928 assert proto.name == wireprototypes.SSHV1 |
36253
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
929 |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
930 # Expected: upgrade <token> <capabilities> |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
931 # If we get something else, the request is malformed. It could be |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
932 # from a future client that has altered the upgrade line content. |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
933 # We treat this as an unknown command. |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
934 try: |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
935 token, caps = request.split(b' ')[1:] |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
936 except ValueError: |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
937 _sshv1respondbytes(fout, b'') |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
938 state = 'protov1-serving' |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
939 continue |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
940 |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
941 # Send empty response if we don't support upgrading protocols. |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
942 if not ui.configbool('experimental', 'sshserver.support-v2'): |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
943 _sshv1respondbytes(fout, b'') |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
944 state = 'protov1-serving' |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
945 continue |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
946 |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
947 try: |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
948 caps = urlreq.parseqs(caps) |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
949 except ValueError: |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
950 _sshv1respondbytes(fout, b'') |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
951 state = 'protov1-serving' |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
952 continue |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
953 |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
954 # We don't see an upgrade request to protocol version 2. Ignore |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
955 # the upgrade request. |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
956 wantedprotos = caps.get(b'proto', [b''])[0] |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
957 if SSHV2 not in wantedprotos: |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
958 _sshv1respondbytes(fout, b'') |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
959 state = 'protov1-serving' |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
960 continue |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
961 |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
962 # It looks like we can honor this upgrade request to protocol 2. |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
963 # Filter the rest of the handshake protocol request lines. |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
964 state = 'upgrade-v2-filter-legacy-handshake' |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
965 continue |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
966 |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
967 elif state == 'upgrade-v2-filter-legacy-handshake': |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
968 # Client should have sent legacy handshake after an ``upgrade`` |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
969 # request. Expected lines: |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
970 # |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
971 # hello |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
972 # between |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
973 # pairs 81 |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
974 # 0000...-0000... |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
975 |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
976 ok = True |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
977 for line in (b'hello', b'between', b'pairs 81'): |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
978 request = fin.readline()[:-1] |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
979 |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
980 if request != line: |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
981 _sshv1respondooberror(fout, ui.ferr, |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
982 b'malformed handshake protocol: ' |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
983 b'missing %s' % line) |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
984 ok = False |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
985 state = 'shutdown' |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
986 break |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
987 |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
988 if not ok: |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
989 continue |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
990 |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
991 request = fin.read(81) |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
992 if request != b'%s-%s' % (b'0' * 40, b'0' * 40): |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
993 _sshv1respondooberror(fout, ui.ferr, |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
994 b'malformed handshake protocol: ' |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
995 b'missing between argument value') |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
996 state = 'shutdown' |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
997 continue |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
998 |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
999 state = 'upgrade-v2-finish' |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
1000 continue |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
1001 |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
1002 elif state == 'upgrade-v2-finish': |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
1003 # Send the upgrade response. |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
1004 fout.write(b'upgraded %s %s\n' % (token, SSHV2)) |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
1005 servercaps = wireproto.capabilities(repo, proto) |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
1006 rsp = b'capabilities: %s' % servercaps.data |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
1007 fout.write(b'%d\n%s\n' % (len(rsp), rsp)) |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
1008 fout.flush() |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
1009 |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
1010 proto = sshv2protocolhandler(ui, fin, fout) |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
1011 protoswitched = True |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
1012 |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
1013 state = 'protov2-serving' |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
1014 continue |
464bedc0fdb4
wireprotoserver: handle SSH protocol version 2 upgrade requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36252
diff
changeset
|
1015 |
36252
3b3a987bbbaa
wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36251
diff
changeset
|
1016 elif state == 'shutdown': |
3b3a987bbbaa
wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36251
diff
changeset
|
1017 break |
3b3a987bbbaa
wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36251
diff
changeset
|
1018 |
3b3a987bbbaa
wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36251
diff
changeset
|
1019 else: |
3b3a987bbbaa
wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36251
diff
changeset
|
1020 raise error.ProgrammingError('unhandled ssh server state: %s' % |
3b3a987bbbaa
wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36251
diff
changeset
|
1021 state) |
3b3a987bbbaa
wireprotoserver: move SSH server operation to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36251
diff
changeset
|
1022 |
36103
bf676267f64f
wireprotoserver: split ssh protocol handler and server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36102
diff
changeset
|
1023 class sshserver(object): |
36555
7cc4a9b9732a
wireprotoserver: support logging SSH server I/O to a file descriptor
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36552
diff
changeset
|
1024 def __init__(self, ui, repo, logfh=None): |
36103
bf676267f64f
wireprotoserver: split ssh protocol handler and server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36102
diff
changeset
|
1025 self._ui = ui |
bf676267f64f
wireprotoserver: split ssh protocol handler and server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36102
diff
changeset
|
1026 self._repo = repo |
bf676267f64f
wireprotoserver: split ssh protocol handler and server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36102
diff
changeset
|
1027 self._fin = ui.fin |
bf676267f64f
wireprotoserver: split ssh protocol handler and server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36102
diff
changeset
|
1028 self._fout = ui.fout |
bf676267f64f
wireprotoserver: split ssh protocol handler and server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36102
diff
changeset
|
1029 |
36555
7cc4a9b9732a
wireprotoserver: support logging SSH server I/O to a file descriptor
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36552
diff
changeset
|
1030 # 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
|
1031 if logfh: |
7cc4a9b9732a
wireprotoserver: support logging SSH server I/O to a file descriptor
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36552
diff
changeset
|
1032 self._fout = util.makeloggingfileobject( |
7cc4a9b9732a
wireprotoserver: support logging SSH server I/O to a file descriptor
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36552
diff
changeset
|
1033 logfh, self._fout, 'o', logdata=True) |
7cc4a9b9732a
wireprotoserver: support logging SSH server I/O to a file descriptor
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36552
diff
changeset
|
1034 ui.ferr = util.makeloggingfileobject( |
7cc4a9b9732a
wireprotoserver: support logging SSH server I/O to a file descriptor
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36552
diff
changeset
|
1035 logfh, ui.ferr, 'e', logdata=True) |
7cc4a9b9732a
wireprotoserver: support logging SSH server I/O to a file descriptor
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36552
diff
changeset
|
1036 |
36103
bf676267f64f
wireprotoserver: split ssh protocol handler and server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36102
diff
changeset
|
1037 hook.redirect(True) |
bf676267f64f
wireprotoserver: split ssh protocol handler and server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36102
diff
changeset
|
1038 ui.fout = repo.ui.fout = ui.ferr |
bf676267f64f
wireprotoserver: split ssh protocol handler and server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36102
diff
changeset
|
1039 |
bf676267f64f
wireprotoserver: split ssh protocol handler and server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36102
diff
changeset
|
1040 # Prevent insertion/deletion of CRs |
37123
a8a902d7176e
procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
37064
diff
changeset
|
1041 procutil.setbinary(self._fin) |
a8a902d7176e
procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
37064
diff
changeset
|
1042 procutil.setbinary(self._fout) |
36103
bf676267f64f
wireprotoserver: split ssh protocol handler and server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36102
diff
changeset
|
1043 |
35899
1bf5263fe5cc
wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35898
diff
changeset
|
1044 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
|
1045 self.serveuntil(threading.Event()) |
35899
1bf5263fe5cc
wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35898
diff
changeset
|
1046 sys.exit(0) |
36552
e7411fb7ba7f
wireprotoserver: ability to run an SSH server until an event is set
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36403
diff
changeset
|
1047 |
e7411fb7ba7f
wireprotoserver: ability to run an SSH server until an event is set
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36403
diff
changeset
|
1048 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
|
1049 """Serve until a threading.Event is set.""" |
e7411fb7ba7f
wireprotoserver: ability to run an SSH server until an event is set
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36403
diff
changeset
|
1050 _runsshserver(self._ui, self._repo, self._fin, self._fout, ev) |