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