Mercurial > public > mercurial-scm > hg-stable
annotate mercurial/wireprotov2server.py @ 39818:c30faea8d02d
wireprotov2: advertise set of valid values for requestable fields
changesetdata, manifestdata, and filedata all allow the caller to
specify what data fields to request.
Data fields are extensible and may evolve over time. In order to
prevent clients from making requests for fields that are not
available, the client needs to know what fields are available.
This commit teaches the server to declare a set of "valid values"
for wire protocol command arguments. That set of values is exposed
in the command's capabilities descriptor. The changesetdata,
manifestdata, and filedata commands all declare their set of
available "fields."
Differential Revision: https://phab.mercurial-scm.org/D4619
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Mon, 17 Sep 2018 11:54:00 -0700 |
parents | 8e7e822e85ec |
children | d059cb669632 |
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 |
27046
37fcfe52c68c
hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
20903
diff
changeset
|
10 |
35899
1bf5263fe5cc
wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35898
diff
changeset
|
11 from .i18n import _ |
39646
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
12 from .node import ( |
39655
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
13 hex, |
39646
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
14 nullid, |
39653
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
15 nullrev, |
39646
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
16 ) |
35896
ef3a24a023ec
wireprotoserver: rename hgweb.protocol to wireprotoserver (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35750
diff
changeset
|
17 from . import ( |
39653
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
18 changegroup, |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
19 dagop, |
39646
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
20 discovery, |
37546
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
21 encoding, |
34509
e21f274cccea
hgweb: in protocol adapter, avoid control reaching end of non-void function
Augie Fackler <augie@google.com>
parents:
33842
diff
changeset
|
22 error, |
39816
ae20f52437e9
wireprotov2: advertise recognized path filter prefixes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39815
diff
changeset
|
23 narrowspec, |
34742
5a9cad0dfddb
hgweb: when unpacking args from request form, convert to bytes
Augie Fackler <augie@google.com>
parents:
34740
diff
changeset
|
24 pycompat, |
37657
23c4ddda7bbe
wireproto: expose repository formats via capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37653
diff
changeset
|
25 streamclone, |
37546
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
26 util, |
37055
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
27 wireprotoframing, |
36111
cd6ab329c5c7
wireprototypes: move wire protocol response types to new module
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36110
diff
changeset
|
28 wireprototypes, |
27046
37fcfe52c68c
hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
20903
diff
changeset
|
29 ) |
37810
856f381ad74b
interfaceutil: module to stub out zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37784
diff
changeset
|
30 from .utils import ( |
856f381ad74b
interfaceutil: module to stub out zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37784
diff
changeset
|
31 interfaceutil, |
856f381ad74b
interfaceutil: module to stub out zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37784
diff
changeset
|
32 ) |
35896
ef3a24a023ec
wireprotoserver: rename hgweb.protocol to wireprotoserver (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35750
diff
changeset
|
33 |
37725
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37724
diff
changeset
|
34 FRAMINGTYPE = b'application/mercurial-exp-framing-0005' |
11595
368cd5325348
protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents:
11594
diff
changeset
|
35 |
37644
77c9ee77687c
wireproto: rename HTTPV2 so it less like HTTP/2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37557
diff
changeset
|
36 HTTP_WIREPROTO_V2 = wireprototypes.HTTP_WIREPROTO_V2 |
36015
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
37 |
37784
ee0d5e9d77b2
wireproto: move version 2 commands dict to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37783
diff
changeset
|
38 COMMANDS = wireprototypes.commanddict() |
ee0d5e9d77b2
wireproto: move version 2 commands dict to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37783
diff
changeset
|
39 |
37545
93397c4633f6
wireproto: extract HTTP version 2 code to own module
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37535
diff
changeset
|
40 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
|
41 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
|
42 |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
43 # 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
|
44 # 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
|
45 |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
46 # 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
|
47 if not urlparts: |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
48 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
|
49 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
|
50 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
|
51 return |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
52 |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
53 if len(urlparts) == 1: |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
54 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
|
55 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
|
56 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
|
57 req.dispatchpath) |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
58 return |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
59 |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
60 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
|
61 |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
62 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
|
63 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
|
64 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
|
65 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
|
66 return |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
67 |
37051
fc5e261915b9
wireproto: require POST for all HTTPv2 requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37050
diff
changeset
|
68 if req.method != 'POST': |
fc5e261915b9
wireproto: require POST for all HTTPv2 requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37050
diff
changeset
|
69 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
|
70 res.headers[b'Allow'] = b'POST' |
fc5e261915b9
wireproto: require POST for all HTTPv2 requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37050
diff
changeset
|
71 res.setbodybytes(_('commands require POST requests')) |
fc5e261915b9
wireproto: require POST for all HTTPv2 requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37050
diff
changeset
|
72 return |
fc5e261915b9
wireproto: require POST for all HTTPv2 requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37050
diff
changeset
|
73 |
37050
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
74 # 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
|
75 # 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
|
76 # 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
|
77 # 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
|
78 try: |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
79 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
|
80 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
|
81 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
|
82 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
|
83 res.headers[k] = v |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
84 res.setbodybytes('permission denied') |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
85 return |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
86 |
37055
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
87 # 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
|
88 if command == b'debugreflect': |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
89 _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
|
90 return |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
91 |
37062
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
92 # 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
|
93 # 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
|
94 # extension. |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
95 extracommands = {'multirequest'} |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
96 |
37784
ee0d5e9d77b2
wireproto: move version 2 commands dict to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37783
diff
changeset
|
97 if command not in COMMANDS 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
|
98 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
|
99 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
|
100 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
|
101 return |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
102 |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
103 repo = rctx.repo |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
104 ui = repo.ui |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
105 |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
106 proto = httpv2protocolhandler(req, ui) |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
107 |
37784
ee0d5e9d77b2
wireproto: move version 2 commands dict to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37783
diff
changeset
|
108 if (not COMMANDS.commandavailable(command, proto) |
37062
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
109 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
|
110 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
|
111 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
|
112 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
|
113 return |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
114 |
37132
aaabd709df72
wireproto: review fixups
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37123
diff
changeset
|
115 # 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
|
116 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
|
117 res.status = b'406 Not Acceptable' |
37d7a1d18b97
wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
118 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
|
119 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
|
120 % FRAMINGTYPE) |
37053
37d7a1d18b97
wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
121 return |
37d7a1d18b97
wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
122 |
37055
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
123 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
|
124 res.status = b'415 Unsupported Media Type' |
37d7a1d18b97
wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
125 # 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
|
126 # since client does Accept it. |
37d7a1d18b97
wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
127 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
|
128 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
|
129 'value: %s\n') % FRAMINGTYPE) |
37053
37d7a1d18b97
wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
130 return |
37d7a1d18b97
wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
131 |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
132 _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
|
133 |
37055
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
134 def _processhttpv2reflectrequest(ui, repo, req, res): |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
135 """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
|
136 |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
137 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
|
138 |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
139 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
|
140 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
|
141 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
|
142 client. |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
143 """ |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
144 import json |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
145 |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
146 # 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
|
147 # 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
|
148 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
|
149 res.status = b'404 Not Found' |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
150 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
|
151 res.setbodybytes(_('debugreflect service not available')) |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
152 return |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
153 |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
154 # 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
|
155 |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
156 reactor = wireprotoframing.serverreactor() |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
157 states = [] |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
158 |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
159 while True: |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
160 frame = wireprotoframing.readframe(req.bodyfh) |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
161 |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
162 if not frame: |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
163 states.append(b'received: <no frame>') |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
164 break |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
165 |
37064
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37062
diff
changeset
|
166 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
|
167 frame.requestid, |
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37062
diff
changeset
|
168 frame.payload)) |
37055
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
169 |
37064
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37062
diff
changeset
|
170 action, meta = reactor.onframerecv(frame) |
37055
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
171 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
|
172 separators=(', ', ': '))) |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
173 |
37059
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
174 action, meta = reactor.oninputeof() |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
175 meta['action'] = action |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
176 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
|
177 |
37055
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
178 res.status = b'200 OK' |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
179 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
|
180 res.setbodybytes(b'\n'.join(states)) |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
181 |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
182 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
|
183 """Post-validation handler for HTTPv2 requests. |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
184 |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
185 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
|
186 frames for evaluation. |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
187 """ |
37059
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
188 # 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
|
189 # 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
|
190 # 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
|
191 reactor = wireprotoframing.serverreactor(deferoutput=True) |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
192 seencommand = False |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
193 |
37289
5fadc63ac99f
wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37288
diff
changeset
|
194 outstream = reactor.makeoutputstream() |
5fadc63ac99f
wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37288
diff
changeset
|
195 |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
196 while True: |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
197 frame = wireprotoframing.readframe(req.bodyfh) |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
198 if not frame: |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
199 break |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
200 |
37064
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37062
diff
changeset
|
201 action, meta = reactor.onframerecv(frame) |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
202 |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
203 if action == 'wantframe': |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
204 # 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
|
205 continue |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
206 elif action == 'runcommand': |
37062
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
207 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
|
208 reqcommand, reactor, outstream, |
5fadc63ac99f
wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37288
diff
changeset
|
209 meta, issubsequent=seencommand) |
37062
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
210 |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
211 if sentoutput: |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
212 return |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
213 |
37062
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
214 seencommand = True |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
215 |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
216 elif action == 'error': |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
217 # TODO define proper error mechanism. |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
218 res.status = b'200 OK' |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
219 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
|
220 res.setbodybytes(meta['message'] + b'\n') |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
221 return |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
222 else: |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
223 raise error.ProgrammingError( |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
224 '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
|
225 |
37059
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
226 action, meta = reactor.oninputeof() |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
227 if action == 'sendframes': |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
228 # 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
|
229 # 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
|
230 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
|
231 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
|
232 res.setbodygen(meta['framegen']) |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
233 elif action == 'noop': |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
234 pass |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
235 else: |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
236 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
|
237 % action) |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
238 |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
239 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
|
240 outstream, command, issubsequent): |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
241 """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
|
242 |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
243 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
|
244 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
|
245 """ |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
246 # 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
|
247 # 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
|
248 # 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
|
249 # 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
|
250 # 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
|
251 # by ``authedperm``. |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
252 # |
37062
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
253 # 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
|
254 # 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
|
255 # 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
|
256 # 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
|
257 # 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
|
258 # 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
|
259 # 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
|
260 |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
261 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
|
262 |
37062
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
263 if reqcommand == b'multirequest': |
37784
ee0d5e9d77b2
wireproto: move version 2 commands dict to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37783
diff
changeset
|
264 if not COMMANDS.commandavailable(command['command'], proto): |
37062
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
265 # TODO proper error mechanism |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
266 res.status = b'200 OK' |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
267 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
|
268 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
|
269 command['command']) |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
270 return True |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
271 |
37132
aaabd709df72
wireproto: review fixups
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37123
diff
changeset
|
272 # 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
|
273 assert authedperm in (b'ro', b'rw') |
37784
ee0d5e9d77b2
wireproto: move version 2 commands dict to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37783
diff
changeset
|
274 wirecommand = COMMANDS[command['command']] |
37062
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
275 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
|
276 |
37062
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
277 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
|
278 # TODO proper error mechanism |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
279 res.status = b'403 Forbidden' |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
280 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
|
281 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
|
282 'command: %s') % command['command']) |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
283 return True |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
284 |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
285 # 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
|
286 # 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
|
287 # be good enough. |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
288 |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
289 else: |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
290 # 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
|
291 if issubsequent: |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
292 # TODO proper error mechanism |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
293 res.status = b'200 OK' |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
294 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
|
295 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
|
296 'URL')) |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
297 return True |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
298 |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
299 if reqcommand != command['command']: |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
300 # TODO define proper error mechanism |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
301 res.status = b'200 OK' |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
302 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
|
303 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
|
304 return True |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
305 |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
306 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
|
307 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
|
308 |
39575
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
309 try: |
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
310 objs = dispatch(repo, proto, command['command']) |
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
311 |
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
312 action, meta = reactor.oncommandresponsereadyobjects( |
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
313 outstream, command['requestid'], objs) |
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
314 |
39815
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
315 except error.WireprotoCommandError as e: |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
316 action, meta = reactor.oncommanderror( |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
317 outstream, command['requestid'], e.message, e.messageargs) |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
318 |
39575
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
319 except Exception as e: |
37726
0c184ca594bb
wireprotov2: change behavior of error frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37725
diff
changeset
|
320 action, meta = reactor.onservererror( |
39575
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
321 outstream, command['requestid'], |
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
322 _('exception when invoking command: %s') % e) |
37058
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
323 |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
324 if action == 'sendframes': |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
325 res.setbodygen(meta['framegen']) |
37062
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
326 return True |
37059
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
327 elif action == 'noop': |
37132
aaabd709df72
wireproto: review fixups
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37123
diff
changeset
|
328 return False |
37058
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
329 else: |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
330 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
|
331 action) |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
332 |
37782
99accae4cc59
wireproto: reimplement dispatch() for version 2 server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37781
diff
changeset
|
333 def getdispatchrepo(repo, proto, command): |
99accae4cc59
wireproto: reimplement dispatch() for version 2 server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37781
diff
changeset
|
334 return repo.filtered('served') |
99accae4cc59
wireproto: reimplement dispatch() for version 2 server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37781
diff
changeset
|
335 |
99accae4cc59
wireproto: reimplement dispatch() for version 2 server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37781
diff
changeset
|
336 def dispatch(repo, proto, command): |
99accae4cc59
wireproto: reimplement dispatch() for version 2 server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37781
diff
changeset
|
337 repo = getdispatchrepo(repo, proto, command) |
99accae4cc59
wireproto: reimplement dispatch() for version 2 server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37781
diff
changeset
|
338 |
37784
ee0d5e9d77b2
wireproto: move version 2 commands dict to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37783
diff
changeset
|
339 func, spec = COMMANDS[command] |
37782
99accae4cc59
wireproto: reimplement dispatch() for version 2 server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37781
diff
changeset
|
340 args = proto.getargs(spec) |
99accae4cc59
wireproto: reimplement dispatch() for version 2 server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37781
diff
changeset
|
341 |
99accae4cc59
wireproto: reimplement dispatch() for version 2 server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37781
diff
changeset
|
342 return func(repo, proto, **args) |
99accae4cc59
wireproto: reimplement dispatch() for version 2 server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37781
diff
changeset
|
343 |
37810
856f381ad74b
interfaceutil: module to stub out zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37784
diff
changeset
|
344 @interfaceutil.implementer(wireprototypes.baseprotocolhandler) |
37296
78103e4138b1
wireproto: port protocol handler to zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37295
diff
changeset
|
345 class httpv2protocolhandler(object): |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
346 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
|
347 self._req = req |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
348 self._ui = ui |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
349 self._args = args |
37050
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
350 |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
351 @property |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
352 def name(self): |
37644
77c9ee77687c
wireproto: rename HTTPV2 so it less like HTTP/2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37557
diff
changeset
|
353 return HTTP_WIREPROTO_V2 |
37050
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
354 |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
355 def getargs(self, args): |
39815
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
356 # First look for args that were passed but aren't registered on this |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
357 # command. |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
358 extra = set(self._args) - set(args) |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
359 if extra: |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
360 raise error.WireprotoCommandError( |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
361 'unsupported argument to command: %s' % |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
362 ', '.join(sorted(extra))) |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
363 |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
364 # And look for required arguments that are missing. |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
365 missing = {a for a in args if args[a]['required']} - set(self._args) |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
366 |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
367 if missing: |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
368 raise error.WireprotoCommandError( |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
369 'missing required arguments: %s' % ', '.join(sorted(missing))) |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
370 |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
371 # Now derive the arguments to pass to the command, taking into |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
372 # account the arguments specified by the client. |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
373 data = {} |
39815
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
374 for k, meta in sorted(args.items()): |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
375 # This argument wasn't passed by the client. |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
376 if k not in self._args: |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
377 data[k] = meta['default']() |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
378 continue |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
379 |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
380 v = self._args[k] |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
381 |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
382 # Sets may be expressed as lists. Silently normalize. |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
383 if meta['type'] == 'set' and isinstance(v, list): |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
384 v = set(v) |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
385 |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
386 # TODO consider more/stronger type validation. |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
387 |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
388 data[k] = v |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
389 |
37485
0b7475ea38cf
wireproto: port heads command to wire protocol v2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37414
diff
changeset
|
390 return data |
37050
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
391 |
37393
afcfdf53e4b5
wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents:
37296
diff
changeset
|
392 def getprotocaps(self): |
afcfdf53e4b5
wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents:
37296
diff
changeset
|
393 # Protocol capabilities are currently not implemented for HTTP V2. |
afcfdf53e4b5
wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents:
37296
diff
changeset
|
394 return set() |
afcfdf53e4b5
wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents:
37296
diff
changeset
|
395 |
37414
2d965bfeb8f6
wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents:
37393
diff
changeset
|
396 def getpayload(self): |
37050
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
397 raise NotImplementedError |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
398 |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
399 @contextlib.contextmanager |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
400 def mayberedirectstdio(self): |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
401 raise NotImplementedError |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
402 |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
403 def client(self): |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
404 raise NotImplementedError |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
405 |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
406 def addcapabilities(self, repo, caps): |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
407 return caps |
37050
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
408 |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
409 def checkperm(self, perm): |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
410 raise NotImplementedError |
37546
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
411 |
37557
734515aca84d
wireproto: define and implement HTTP handshake to upgrade protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37546
diff
changeset
|
412 def httpv2apidescriptor(req, repo): |
734515aca84d
wireproto: define and implement HTTP handshake to upgrade protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37546
diff
changeset
|
413 proto = httpv2protocolhandler(req, repo.ui) |
734515aca84d
wireproto: define and implement HTTP handshake to upgrade protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37546
diff
changeset
|
414 |
734515aca84d
wireproto: define and implement HTTP handshake to upgrade protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37546
diff
changeset
|
415 return _capabilitiesv2(repo, proto) |
734515aca84d
wireproto: define and implement HTTP handshake to upgrade protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37546
diff
changeset
|
416 |
37546
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
417 def _capabilitiesv2(repo, proto): |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
418 """Obtain the set of capabilities for version 2 transports. |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
419 |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
420 These capabilities are distinct from the capabilities for version 1 |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
421 transports. |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
422 """ |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
423 compression = [] |
37783
9d818539abfa
wireproto: move supportedcompengines out of wireproto
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37782
diff
changeset
|
424 for engine in wireprototypes.supportedcompengines(repo.ui, util.SERVERROLE): |
37546
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
425 compression.append({ |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
426 b'name': engine.wireprotosupport().name, |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
427 }) |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
428 |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
429 caps = { |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
430 'commands': {}, |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
431 'compression': compression, |
37653
b2fa1591fb44
wireproto: add media type to version 2 capabilities response
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37644
diff
changeset
|
432 'framingmediatypes': [FRAMINGTYPE], |
39816
ae20f52437e9
wireprotov2: advertise recognized path filter prefixes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39815
diff
changeset
|
433 'pathfilterprefixes': set(narrowspec.VALID_PREFIXES), |
37546
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
434 } |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
435 |
37784
ee0d5e9d77b2
wireproto: move version 2 commands dict to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37783
diff
changeset
|
436 for command, entry in COMMANDS.items(): |
39817
8e7e822e85ec
wireprotov2: expose rich arguments metadata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39816
diff
changeset
|
437 args = {} |
8e7e822e85ec
wireprotov2: expose rich arguments metadata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39816
diff
changeset
|
438 |
8e7e822e85ec
wireprotov2: expose rich arguments metadata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39816
diff
changeset
|
439 for arg, meta in entry.args.items(): |
8e7e822e85ec
wireprotov2: expose rich arguments metadata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39816
diff
changeset
|
440 args[arg] = { |
8e7e822e85ec
wireprotov2: expose rich arguments metadata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39816
diff
changeset
|
441 # TODO should this be a normalized type using CBOR's |
8e7e822e85ec
wireprotov2: expose rich arguments metadata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39816
diff
changeset
|
442 # terminology? |
8e7e822e85ec
wireprotov2: expose rich arguments metadata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39816
diff
changeset
|
443 b'type': meta['type'], |
8e7e822e85ec
wireprotov2: expose rich arguments metadata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39816
diff
changeset
|
444 b'required': meta['required'], |
8e7e822e85ec
wireprotov2: expose rich arguments metadata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39816
diff
changeset
|
445 } |
8e7e822e85ec
wireprotov2: expose rich arguments metadata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39816
diff
changeset
|
446 |
8e7e822e85ec
wireprotov2: expose rich arguments metadata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39816
diff
changeset
|
447 if not meta['required']: |
8e7e822e85ec
wireprotov2: expose rich arguments metadata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39816
diff
changeset
|
448 args[arg][b'default'] = meta['default']() |
39815
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
449 |
39818
c30faea8d02d
wireprotov2: advertise set of valid values for requestable fields
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39817
diff
changeset
|
450 if meta['validvalues']: |
c30faea8d02d
wireprotov2: advertise set of valid values for requestable fields
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39817
diff
changeset
|
451 args[arg][b'validvalues'] = meta['validvalues'] |
c30faea8d02d
wireprotov2: advertise set of valid values for requestable fields
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39817
diff
changeset
|
452 |
37546
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
453 caps['commands'][command] = { |
39815
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
454 'args': args, |
37546
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
455 'permissions': [entry.permission], |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
456 } |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
457 |
37657
23c4ddda7bbe
wireproto: expose repository formats via capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37653
diff
changeset
|
458 if streamclone.allowservergeneration(repo): |
23c4ddda7bbe
wireproto: expose repository formats via capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37653
diff
changeset
|
459 caps['rawrepoformats'] = sorted(repo.requirements & |
23c4ddda7bbe
wireproto: expose repository formats via capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37653
diff
changeset
|
460 repo.supportedformats) |
23c4ddda7bbe
wireproto: expose repository formats via capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37653
diff
changeset
|
461 |
37546
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
462 return proto.addcapabilities(repo, caps) |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
463 |
39657
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
464 def builddeltarequests(store, nodes, haveparents): |
39653
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
465 """Build a series of revision delta requests against a backend store. |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
466 |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
467 Returns a list of revision numbers in the order they should be sent |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
468 and a list of ``irevisiondeltarequest`` instances to be made against |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
469 the backend store. |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
470 """ |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
471 # We sort and send nodes in DAG order because this is optimal for |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
472 # storage emission. |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
473 # TODO we may want a better storage API here - one where we can throw |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
474 # a list of nodes and delta preconditions over a figurative wall and |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
475 # have the storage backend figure it out for us. |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
476 revs = dagop.linearize({store.rev(n) for n in nodes}, store.parentrevs) |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
477 |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
478 requests = [] |
39657
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
479 seenrevs = set() |
39653
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
480 |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
481 for rev in revs: |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
482 node = store.node(rev) |
39657
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
483 parentnodes = store.parents(node) |
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
484 parentrevs = [store.rev(n) for n in parentnodes] |
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
485 deltabaserev = store.deltaparent(rev) |
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
486 deltabasenode = store.node(deltabaserev) |
39653
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
487 |
39657
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
488 # The choice of whether to send a fulltext revision or a delta and |
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
489 # what delta to send is governed by a few factors. |
39653
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
490 # |
39657
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
491 # To send a delta, we need to ensure the receiver is capable of |
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
492 # decoding it. And that requires the receiver to have the base |
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
493 # revision the delta is against. |
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
494 # |
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
495 # We can only guarantee the receiver has the base revision if |
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
496 # a) we've already sent the revision as part of this group |
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
497 # b) the receiver has indicated they already have the revision. |
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
498 # And the mechanism for "b" is the client indicating they have |
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
499 # parent revisions. So this means we can only send the delta if |
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
500 # it is sent before or it is against a delta and the receiver says |
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
501 # they have a parent. |
39653
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
502 |
39657
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
503 # We can send storage delta if it is against a revision we've sent |
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
504 # in this group. |
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
505 if deltabaserev != nullrev and deltabaserev in seenrevs: |
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
506 basenode = deltabasenode |
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
507 |
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
508 # We can send storage delta if it is against a parent revision and |
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
509 # the receiver indicates they have the parents. |
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
510 elif (deltabaserev != nullrev and deltabaserev in parentrevs |
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
511 and haveparents): |
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
512 basenode = deltabasenode |
39653
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
513 |
39657
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
514 # Otherwise the storage delta isn't appropriate. Fall back to |
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
515 # using another delta, if possible. |
39653
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
516 |
39657
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
517 # Use p1 if we've emitted it or receiver says they have it. |
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
518 elif parentrevs[0] != nullrev and ( |
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
519 parentrevs[0] in seenrevs or haveparents): |
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
520 basenode = parentnodes[0] |
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
521 |
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
522 # Use p2 if we've emitted it or receiver says they have it. |
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
523 elif parentrevs[1] != nullrev and ( |
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
524 parentrevs[1] in seenrevs or haveparents): |
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
525 basenode = parentnodes[1] |
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
526 |
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
527 # Nothing appropriate to delta against. Send the full revision. |
39653
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
528 else: |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
529 basenode = nullid |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
530 |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
531 requests.append(changegroup.revisiondeltarequest( |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
532 node=node, |
39657
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
533 p1node=parentnodes[0], |
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
534 p2node=parentnodes[1], |
39653
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
535 # Receiver deals with linknode resolution. |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
536 linknode=nullid, |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
537 basenode=basenode, |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
538 )) |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
539 |
39657
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
540 seenrevs.add(rev) |
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
541 |
39653
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
542 return revs, requests |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
543 |
37780
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
544 def wireprotocommand(name, args=None, permission='push'): |
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
545 """Decorator to declare a wire protocol command. |
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
546 |
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
547 ``name`` is the name of the wire protocol command being provided. |
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
548 |
39815
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
549 ``args`` is a dict defining arguments accepted by the command. Keys are |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
550 the argument name. Values are dicts with the following keys: |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
551 |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
552 ``type`` |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
553 The argument data type. Must be one of the following string |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
554 literals: ``bytes``, ``int``, ``list``, ``dict``, ``set``, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
555 or ``bool``. |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
556 |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
557 ``default`` |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
558 A callable returning the default value for this argument. If not |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
559 specified, ``None`` will be the default value. |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
560 |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
561 ``required`` |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
562 Bool indicating whether the argument is required. |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
563 |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
564 ``example`` |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
565 An example value for this argument. |
37780
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
566 |
39818
c30faea8d02d
wireprotov2: advertise set of valid values for requestable fields
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39817
diff
changeset
|
567 ``validvalues`` |
c30faea8d02d
wireprotov2: advertise set of valid values for requestable fields
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39817
diff
changeset
|
568 Set of recognized values for this argument. |
c30faea8d02d
wireprotov2: advertise set of valid values for requestable fields
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39817
diff
changeset
|
569 |
37780
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
570 ``permission`` defines the permission type needed to run this command. |
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
571 Can be ``push`` or ``pull``. These roughly map to read-write and read-only, |
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
572 respectively. Default is to assume command requires ``push`` permissions |
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
573 because otherwise commands not declaring their permissions could modify |
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
574 a repository that is supposed to be read-only. |
39575
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
575 |
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
576 Wire protocol commands are generators of objects to be serialized and |
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
577 sent to the client. |
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
578 |
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
579 If a command raises an uncaught exception, this will be translated into |
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
580 a command error. |
37780
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
581 """ |
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
582 transports = {k for k, v in wireprototypes.TRANSPORTS.items() |
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
583 if v['version'] == 2} |
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
584 |
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
585 if permission not in ('push', 'pull'): |
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
586 raise error.ProgrammingError('invalid wire protocol permission; ' |
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
587 'got %s; expected "push" or "pull"' % |
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
588 permission) |
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
589 |
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
590 if args is None: |
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
591 args = {} |
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
592 |
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
593 if not isinstance(args, dict): |
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
594 raise error.ProgrammingError('arguments for version 2 commands ' |
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
595 'must be declared as dicts') |
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
596 |
39815
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
597 for arg, meta in args.items(): |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
598 if arg == '*': |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
599 raise error.ProgrammingError('* argument name not allowed on ' |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
600 'version 2 commands') |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
601 |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
602 if not isinstance(meta, dict): |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
603 raise error.ProgrammingError('arguments for version 2 commands ' |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
604 'must declare metadata as a dict') |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
605 |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
606 if 'type' not in meta: |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
607 raise error.ProgrammingError('%s argument for command %s does not ' |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
608 'declare type field' % (arg, name)) |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
609 |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
610 if meta['type'] not in ('bytes', 'int', 'list', 'dict', 'set', 'bool'): |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
611 raise error.ProgrammingError('%s argument for command %s has ' |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
612 'illegal type: %s' % (arg, name, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
613 meta['type'])) |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
614 |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
615 if 'example' not in meta: |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
616 raise error.ProgrammingError('%s argument for command %s does not ' |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
617 'declare example field' % (arg, name)) |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
618 |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
619 if 'default' in meta and meta.get('required'): |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
620 raise error.ProgrammingError('%s argument for command %s is marked ' |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
621 'as required but has a default value' % |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
622 (arg, name)) |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
623 |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
624 meta.setdefault('default', lambda: None) |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
625 meta.setdefault('required', False) |
39818
c30faea8d02d
wireprotov2: advertise set of valid values for requestable fields
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39817
diff
changeset
|
626 meta.setdefault('validvalues', None) |
39815
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
627 |
37546
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
628 def register(func): |
37784
ee0d5e9d77b2
wireproto: move version 2 commands dict to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37783
diff
changeset
|
629 if name in COMMANDS: |
37780
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
630 raise error.ProgrammingError('%s command already registered ' |
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
631 'for version 2' % name) |
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
632 |
37784
ee0d5e9d77b2
wireproto: move version 2 commands dict to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37783
diff
changeset
|
633 COMMANDS[name] = wireprototypes.commandentry( |
37780
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
634 func, args=args, transports=transports, permission=permission) |
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
635 |
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
636 return func |
37546
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
637 |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
638 return register |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
639 |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
640 @wireprotocommand('branchmap', permission='pull') |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
641 def branchmapv2(repo, proto): |
39575
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
642 yield {encoding.fromlocal(k): v |
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
643 for k, v in repo.branchmap().iteritems()} |
37546
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
644 |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
645 @wireprotocommand('capabilities', permission='pull') |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
646 def capabilitiesv2(repo, proto): |
39575
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
647 yield _capabilitiesv2(repo, proto) |
37546
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
648 |
39815
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
649 @wireprotocommand( |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
650 'changesetdata', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
651 args={ |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
652 'noderange': { |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
653 'type': 'list', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
654 'example': [[b'0123456...'], [b'abcdef...']], |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
655 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
656 'nodes': { |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
657 'type': 'list', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
658 'example': [b'0123456...'], |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
659 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
660 'fields': { |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
661 'type': 'set', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
662 'default': set, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
663 'example': {b'parents', b'revision'}, |
39818
c30faea8d02d
wireprotov2: advertise set of valid values for requestable fields
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39817
diff
changeset
|
664 'validvalues': {b'bookmarks', b'parents', b'phase', b'revision'}, |
39815
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
665 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
666 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
667 permission='pull') |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
668 def changesetdata(repo, proto, noderange, nodes, fields): |
39652
399ddd3227a4
wireprotov2: add TODOs around extending changesetdata fields
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39650
diff
changeset
|
669 # TODO look for unknown fields and abort when they can't be serviced. |
39818
c30faea8d02d
wireprotov2: advertise set of valid values for requestable fields
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39817
diff
changeset
|
670 # This could probably be validated by dispatcher using validvalues. |
39652
399ddd3227a4
wireprotov2: add TODOs around extending changesetdata fields
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39650
diff
changeset
|
671 |
39646
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
672 if noderange is None and nodes is None: |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
673 raise error.WireprotoCommandError( |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
674 'noderange or nodes must be defined') |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
675 |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
676 if noderange is not None: |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
677 if len(noderange) != 2: |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
678 raise error.WireprotoCommandError( |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
679 'noderange must consist of 2 elements') |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
680 |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
681 if not noderange[1]: |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
682 raise error.WireprotoCommandError( |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
683 'heads in noderange request cannot be empty') |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
684 |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
685 cl = repo.changelog |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
686 hasnode = cl.hasnode |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
687 |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
688 seen = set() |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
689 outgoing = [] |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
690 |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
691 if nodes is not None: |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
692 outgoing.extend(n for n in nodes if hasnode(n)) |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
693 seen |= set(outgoing) |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
694 |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
695 if noderange is not None: |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
696 if noderange[0]: |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
697 common = [n for n in noderange[0] if hasnode(n)] |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
698 else: |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
699 common = [nullid] |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
700 |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
701 for n in discovery.outgoing(repo, common, noderange[1]).missing: |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
702 if n not in seen: |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
703 outgoing.append(n) |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
704 # Don't need to add to seen here because this is the final |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
705 # source of nodes and there should be no duplicates in this |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
706 # list. |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
707 |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
708 seen.clear() |
39648
c1aacb0d76ff
wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39646
diff
changeset
|
709 publishing = repo.publishing() |
39646
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
710 |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
711 if outgoing: |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
712 repo.hook('preoutgoing', throw=True, source='serve') |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
713 |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
714 yield { |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
715 b'totalitems': len(outgoing), |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
716 } |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
717 |
39648
c1aacb0d76ff
wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39646
diff
changeset
|
718 # The phases of nodes already transferred to the client may have changed |
c1aacb0d76ff
wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39646
diff
changeset
|
719 # since the client last requested data. We send phase-only records |
c1aacb0d76ff
wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39646
diff
changeset
|
720 # for these revisions, if requested. |
c1aacb0d76ff
wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39646
diff
changeset
|
721 if b'phase' in fields and noderange is not None: |
c1aacb0d76ff
wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39646
diff
changeset
|
722 # TODO skip nodes whose phase will be reflected by a node in the |
c1aacb0d76ff
wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39646
diff
changeset
|
723 # outgoing set. This is purely an optimization to reduce data |
c1aacb0d76ff
wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39646
diff
changeset
|
724 # size. |
c1aacb0d76ff
wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39646
diff
changeset
|
725 for node in noderange[0]: |
c1aacb0d76ff
wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39646
diff
changeset
|
726 yield { |
c1aacb0d76ff
wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39646
diff
changeset
|
727 b'node': node, |
c1aacb0d76ff
wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39646
diff
changeset
|
728 b'phase': b'public' if publishing else repo[node].phasestr() |
c1aacb0d76ff
wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39646
diff
changeset
|
729 } |
c1aacb0d76ff
wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39646
diff
changeset
|
730 |
39650
9dffa99f9158
wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39648
diff
changeset
|
731 nodebookmarks = {} |
9dffa99f9158
wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39648
diff
changeset
|
732 for mark, node in repo._bookmarks.items(): |
9dffa99f9158
wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39648
diff
changeset
|
733 nodebookmarks.setdefault(node, set()).add(mark) |
9dffa99f9158
wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39648
diff
changeset
|
734 |
39646
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
735 # It is already topologically sorted by revision number. |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
736 for node in outgoing: |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
737 d = { |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
738 b'node': node, |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
739 } |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
740 |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
741 if b'parents' in fields: |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
742 d[b'parents'] = cl.parents(node) |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
743 |
39648
c1aacb0d76ff
wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39646
diff
changeset
|
744 if b'phase' in fields: |
c1aacb0d76ff
wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39646
diff
changeset
|
745 if publishing: |
c1aacb0d76ff
wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39646
diff
changeset
|
746 d[b'phase'] = b'public' |
c1aacb0d76ff
wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39646
diff
changeset
|
747 else: |
c1aacb0d76ff
wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39646
diff
changeset
|
748 ctx = repo[node] |
c1aacb0d76ff
wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39646
diff
changeset
|
749 d[b'phase'] = ctx.phasestr() |
c1aacb0d76ff
wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39646
diff
changeset
|
750 |
39650
9dffa99f9158
wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39648
diff
changeset
|
751 if b'bookmarks' in fields and node in nodebookmarks: |
9dffa99f9158
wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39648
diff
changeset
|
752 d[b'bookmarks'] = sorted(nodebookmarks[node]) |
9dffa99f9158
wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39648
diff
changeset
|
753 del nodebookmarks[node] |
9dffa99f9158
wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39648
diff
changeset
|
754 |
39646
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
755 revisiondata = None |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
756 |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
757 if b'revision' in fields: |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
758 revisiondata = cl.revision(node, raw=True) |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
759 d[b'revisionsize'] = len(revisiondata) |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
760 |
39652
399ddd3227a4
wireprotov2: add TODOs around extending changesetdata fields
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39650
diff
changeset
|
761 # TODO make it possible for extensions to wrap a function or register |
399ddd3227a4
wireprotov2: add TODOs around extending changesetdata fields
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39650
diff
changeset
|
762 # a handler to service custom fields. |
399ddd3227a4
wireprotov2: add TODOs around extending changesetdata fields
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39650
diff
changeset
|
763 |
39646
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
764 yield d |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
765 |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
766 if revisiondata is not None: |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
767 yield revisiondata |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
768 |
39650
9dffa99f9158
wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39648
diff
changeset
|
769 # If requested, send bookmarks from nodes that didn't have revision |
9dffa99f9158
wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39648
diff
changeset
|
770 # data sent so receiver is aware of any bookmark updates. |
9dffa99f9158
wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39648
diff
changeset
|
771 if b'bookmarks' in fields: |
9dffa99f9158
wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39648
diff
changeset
|
772 for node, marks in sorted(nodebookmarks.iteritems()): |
9dffa99f9158
wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39648
diff
changeset
|
773 yield { |
9dffa99f9158
wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39648
diff
changeset
|
774 b'node': node, |
9dffa99f9158
wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39648
diff
changeset
|
775 b'bookmarks': sorted(marks), |
9dffa99f9158
wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39648
diff
changeset
|
776 } |
9dffa99f9158
wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39648
diff
changeset
|
777 |
39655
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
778 class FileAccessError(Exception): |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
779 """Represents an error accessing a specific file.""" |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
780 |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
781 def __init__(self, path, msg, args): |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
782 self.path = path |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
783 self.msg = msg |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
784 self.args = args |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
785 |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
786 def getfilestore(repo, proto, path): |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
787 """Obtain a file storage object for use with wire protocol. |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
788 |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
789 Exists as a standalone function so extensions can monkeypatch to add |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
790 access control. |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
791 """ |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
792 # This seems to work even if the file doesn't exist. So catch |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
793 # "empty" files and return an error. |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
794 fl = repo.file(path) |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
795 |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
796 if not len(fl): |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
797 raise FileAccessError(path, 'unknown file: %s', (path,)) |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
798 |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
799 return fl |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
800 |
39815
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
801 @wireprotocommand( |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
802 'filedata', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
803 args={ |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
804 'haveparents': { |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
805 'type': 'bool', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
806 'default': lambda: False, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
807 'example': True, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
808 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
809 'nodes': { |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
810 'type': 'list', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
811 'required': True, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
812 'example': [b'0123456...'], |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
813 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
814 'fields': { |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
815 'type': 'set', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
816 'default': set, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
817 'example': {b'parents', b'revision'}, |
39818
c30faea8d02d
wireprotov2: advertise set of valid values for requestable fields
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39817
diff
changeset
|
818 'validvalues': {b'parents', b'revision'}, |
39815
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
819 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
820 'path': { |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
821 'type': 'bytes', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
822 'required': True, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
823 'example': b'foo.txt', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
824 } |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
825 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
826 permission='pull') |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
827 def filedata(repo, proto, haveparents, nodes, fields, path): |
39655
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
828 try: |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
829 # Extensions may wish to access the protocol handler. |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
830 store = getfilestore(repo, proto, path) |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
831 except FileAccessError as e: |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
832 raise error.WireprotoCommandError(e.msg, e.args) |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
833 |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
834 # Validate requested nodes. |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
835 for node in nodes: |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
836 try: |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
837 store.rev(node) |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
838 except error.LookupError: |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
839 raise error.WireprotoCommandError('unknown file node: %s', |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
840 (hex(node),)) |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
841 |
39657
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
842 revs, requests = builddeltarequests(store, nodes, haveparents) |
39655
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
843 |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
844 yield { |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
845 b'totalitems': len(revs), |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
846 } |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
847 |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
848 if b'revision' in fields: |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
849 deltas = store.emitrevisiondeltas(requests) |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
850 else: |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
851 deltas = None |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
852 |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
853 for rev in revs: |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
854 node = store.node(rev) |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
855 |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
856 if deltas is not None: |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
857 delta = next(deltas) |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
858 else: |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
859 delta = None |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
860 |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
861 d = { |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
862 b'node': node, |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
863 } |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
864 |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
865 if b'parents' in fields: |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
866 d[b'parents'] = store.parents(node) |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
867 |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
868 if b'revision' in fields: |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
869 assert delta is not None |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
870 assert delta.flags == 0 |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
871 assert d[b'node'] == delta.node |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
872 |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
873 if delta.revision is not None: |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
874 revisiondata = delta.revision |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
875 d[b'revisionsize'] = len(revisiondata) |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
876 else: |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
877 d[b'deltabasenode'] = delta.basenode |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
878 revisiondata = delta.delta |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
879 d[b'deltasize'] = len(revisiondata) |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
880 else: |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
881 revisiondata = None |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
882 |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
883 yield d |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
884 |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
885 if revisiondata is not None: |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
886 yield revisiondata |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
887 |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
888 if deltas is not None: |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
889 try: |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
890 next(deltas) |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
891 raise error.ProgrammingError('should not have more deltas') |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
892 except GeneratorExit: |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
893 pass |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
894 |
39815
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
895 @wireprotocommand( |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
896 'heads', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
897 args={ |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
898 'publiconly': { |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
899 'type': 'bool', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
900 'default': lambda: False, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
901 'example': False, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
902 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
903 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
904 permission='pull') |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
905 def headsv2(repo, proto, publiconly): |
37546
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
906 if publiconly: |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
907 repo = repo.filtered('immutable') |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
908 |
39575
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
909 yield repo.heads() |
37546
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
910 |
39815
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
911 @wireprotocommand( |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
912 'known', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
913 args={ |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
914 'nodes': { |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
915 'type': 'list', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
916 'default': list, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
917 'example': [b'deadbeef'], |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
918 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
919 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
920 permission='pull') |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
921 def knownv2(repo, proto, nodes): |
37546
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
922 result = b''.join(b'1' if n else b'0' for n in repo.known(nodes)) |
39575
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
923 yield result |
37546
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
924 |
39815
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
925 @wireprotocommand( |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
926 'listkeys', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
927 args={ |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
928 'namespace': { |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
929 'type': 'bytes', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
930 'required': True, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
931 'example': b'ns', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
932 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
933 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
934 permission='pull') |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
935 def listkeysv2(repo, proto, namespace): |
37546
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
936 keys = repo.listkeys(encoding.tolocal(namespace)) |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
937 keys = {encoding.fromlocal(k): encoding.fromlocal(v) |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
938 for k, v in keys.iteritems()} |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
939 |
39575
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
940 yield keys |
37546
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
941 |
39815
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
942 @wireprotocommand( |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
943 'lookup', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
944 args={ |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
945 'key': { |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
946 'type': 'bytes', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
947 'required': True, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
948 'example': b'foo', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
949 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
950 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
951 permission='pull') |
37546
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
952 def lookupv2(repo, proto, key): |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
953 key = encoding.tolocal(key) |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
954 |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
955 # TODO handle exception. |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
956 node = repo.lookup(key) |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
957 |
39575
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
958 yield node |
37546
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
959 |
39815
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
960 @wireprotocommand( |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
961 'manifestdata', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
962 args={ |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
963 'nodes': { |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
964 'type': 'list', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
965 'required': True, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
966 'example': [b'0123456...'], |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
967 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
968 'haveparents': { |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
969 'type': 'bool', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
970 'default': lambda: False, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
971 'example': True, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
972 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
973 'fields': { |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
974 'type': 'set', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
975 'default': set, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
976 'example': {b'parents', b'revision'}, |
39818
c30faea8d02d
wireprotov2: advertise set of valid values for requestable fields
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39817
diff
changeset
|
977 'validvalues': {b'parents', b'revision'}, |
39815
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
978 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
979 'tree': { |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
980 'type': 'bytes', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
981 'required': True, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
982 'example': b'', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
983 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
984 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
985 permission='pull') |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
986 def manifestdata(repo, proto, haveparents, nodes, fields, tree): |
39653
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
987 store = repo.manifestlog.getstorage(tree) |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
988 |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
989 # Validate the node is known and abort on unknown revisions. |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
990 for node in nodes: |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
991 try: |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
992 store.rev(node) |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
993 except error.LookupError: |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
994 raise error.WireprotoCommandError( |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
995 'unknown node: %s', (node,)) |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
996 |
39657
aa7e312375cf
wireprotov2: let clients drive delta behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39655
diff
changeset
|
997 revs, requests = builddeltarequests(store, nodes, haveparents) |
39653
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
998 |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
999 yield { |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1000 b'totalitems': len(revs), |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1001 } |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1002 |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1003 if b'revision' in fields: |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1004 deltas = store.emitrevisiondeltas(requests) |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1005 else: |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1006 deltas = None |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1007 |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1008 for rev in revs: |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1009 node = store.node(rev) |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1010 |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1011 if deltas is not None: |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1012 delta = next(deltas) |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1013 else: |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1014 delta = None |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1015 |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1016 d = { |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1017 b'node': node, |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1018 } |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1019 |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1020 if b'parents' in fields: |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1021 d[b'parents'] = store.parents(node) |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1022 |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1023 if b'revision' in fields: |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1024 assert delta is not None |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1025 assert delta.flags == 0 |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1026 assert d[b'node'] == delta.node |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1027 |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1028 if delta.revision is not None: |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1029 revisiondata = delta.revision |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1030 d[b'revisionsize'] = len(revisiondata) |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1031 else: |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1032 d[b'deltabasenode'] = delta.basenode |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1033 revisiondata = delta.delta |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1034 d[b'deltasize'] = len(revisiondata) |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1035 else: |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1036 revisiondata = None |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1037 |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1038 yield d |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1039 |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1040 if revisiondata is not None: |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1041 yield revisiondata |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1042 |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1043 if deltas is not None: |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1044 try: |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1045 next(deltas) |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1046 raise error.ProgrammingError('should not have more deltas') |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1047 except GeneratorExit: |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1048 pass |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1049 |
39815
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1050 @wireprotocommand( |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1051 'pushkey', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1052 args={ |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1053 'namespace': { |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1054 'type': 'bytes', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1055 'required': True, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1056 'example': b'ns', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1057 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1058 'key': { |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1059 'type': 'bytes', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1060 'required': True, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1061 'example': b'key', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1062 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1063 'old': { |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1064 'type': 'bytes', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1065 'required': True, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1066 'example': b'old', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1067 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1068 'new': { |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1069 'type': 'bytes', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1070 'required': True, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1071 'example': 'new', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1072 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1073 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1074 permission='push') |
37546
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
1075 def pushkeyv2(repo, proto, namespace, key, old, new): |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
1076 # TODO handle ui output redirection |
39575
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
1077 yield repo.pushkey(encoding.tolocal(namespace), |
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
1078 encoding.tolocal(key), |
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
1079 encoding.tolocal(old), |
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
1080 encoding.tolocal(new)) |