annotate mercurial/wireprotov2server.py @ 39812:8e7e822e85ec

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