annotate mercurial/wireprotov2server.py @ 39655:0e03e6a44dee

wireprotov2: define and implement "filedata" command Continuing our trend of implementing *data commands for retrieving information about specific repository data primitives, this commit implements a command for retrieving data about an individual tracked file. The command is very similar to "manifestdata." The only significant difference is that we have a standalone function for obtaining storage for a tracked file. This is to provide a monkeypatch point for extensions to implement path-based access control. With this API available, wire protocol version 2 now exposes all data primitives necessary to implement a full clone. Of course, since "filedata" can only resolve data for a single path at a time, clients would need to issue N commands to perform a full clone. On the Firefox repository, this would be ~461k commands. We'll likely need to implement a file data retrieval command that supports multiple paths. But that can be implemented later. Differential Revision: https://phab.mercurial-scm.org/D4490
author Gregory Szorc <gregory.szorc@gmail.com>
date Wed, 05 Sep 2018 09:10:17 -0700
parents c7a7c7e844e5
children aa7e312375cf
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
36104
2ad145fbde54 wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36103
diff changeset
9 import contextlib
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 20903
diff changeset
10
35899
1bf5263fe5cc wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35898
diff changeset
11 from .i18n import _
39646
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
12 from .node import (
39655
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
13 hex,
39646
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
14 nullid,
39653
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
15 nullrev,
39646
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
16 )
35896
ef3a24a023ec wireprotoserver: rename hgweb.protocol to wireprotoserver (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35750
diff changeset
17 from . import (
39653
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
18 changegroup,
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
19 dagop,
39646
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
20 discovery,
37546
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
21 encoding,
34509
e21f274cccea hgweb: in protocol adapter, avoid control reaching end of non-void function
Augie Fackler <augie@google.com>
parents: 33842
diff changeset
22 error,
34742
5a9cad0dfddb hgweb: when unpacking args from request form, convert to bytes
Augie Fackler <augie@google.com>
parents: 34740
diff changeset
23 pycompat,
37657
23c4ddda7bbe wireproto: expose repository formats via capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37653
diff changeset
24 streamclone,
37546
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
25 util,
37055
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
26 wireprotoframing,
36111
cd6ab329c5c7 wireprototypes: move wire protocol response types to new module
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36110
diff changeset
27 wireprototypes,
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 20903
diff changeset
28 )
37810
856f381ad74b interfaceutil: module to stub out zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37784
diff changeset
29 from .utils import (
856f381ad74b interfaceutil: module to stub out zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37784
diff changeset
30 interfaceutil,
856f381ad74b interfaceutil: module to stub out zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37784
diff changeset
31 )
35896
ef3a24a023ec wireprotoserver: rename hgweb.protocol to wireprotoserver (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35750
diff changeset
32
37725
3ea8323d6f95 wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37724
diff changeset
33 FRAMINGTYPE = b'application/mercurial-exp-framing-0005'
11595
368cd5325348 protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents: 11594
diff changeset
34
37644
77c9ee77687c wireproto: rename HTTPV2 so it less like HTTP/2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37557
diff changeset
35 HTTP_WIREPROTO_V2 = wireprototypes.HTTP_WIREPROTO_V2
36015
48a3a9283f09 sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35940
diff changeset
36
37784
ee0d5e9d77b2 wireproto: move version 2 commands dict to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37783
diff changeset
37 COMMANDS = wireprototypes.commanddict()
ee0d5e9d77b2 wireproto: move version 2 commands dict to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37783
diff changeset
38
37545
93397c4633f6 wireproto: extract HTTP version 2 code to own module
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37535
diff changeset
39 def handlehttpv2request(rctx, req, res, checkperm, urlparts):
37050
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
40 from .hgweb import common as hgwebcommon
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
41
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
42 # URL space looks like: <permissions>/<command>, where <permission> can
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
43 # be ``ro`` or ``rw`` to signal read-only or read-write, respectively.
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
44
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
45 # Root URL does nothing meaningful... yet.
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
46 if not urlparts:
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
47 res.status = b'200 OK'
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
48 res.headers[b'Content-Type'] = b'text/plain'
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
49 res.setbodybytes(_('HTTP version 2 API handler'))
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
50 return
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
51
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
52 if len(urlparts) == 1:
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
53 res.status = b'404 Not Found'
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
54 res.headers[b'Content-Type'] = b'text/plain'
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
55 res.setbodybytes(_('do not know how to process %s\n') %
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
56 req.dispatchpath)
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
57 return
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
58
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
59 permission, command = urlparts[0:2]
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
60
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
61 if permission not in (b'ro', b'rw'):
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
62 res.status = b'404 Not Found'
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
63 res.headers[b'Content-Type'] = b'text/plain'
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
64 res.setbodybytes(_('unknown permission: %s') % permission)
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
65 return
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
66
37051
fc5e261915b9 wireproto: require POST for all HTTPv2 requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37050
diff changeset
67 if req.method != 'POST':
fc5e261915b9 wireproto: require POST for all HTTPv2 requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37050
diff changeset
68 res.status = b'405 Method Not Allowed'
fc5e261915b9 wireproto: require POST for all HTTPv2 requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37050
diff changeset
69 res.headers[b'Allow'] = b'POST'
fc5e261915b9 wireproto: require POST for all HTTPv2 requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37050
diff changeset
70 res.setbodybytes(_('commands require POST requests'))
fc5e261915b9 wireproto: require POST for all HTTPv2 requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37050
diff changeset
71 return
fc5e261915b9 wireproto: require POST for all HTTPv2 requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37050
diff changeset
72
37050
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
73 # At some point we'll want to use our own API instead of recycling the
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
74 # behavior of version 1 of the wire protocol...
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
75 # TODO return reasonable responses - not responses that overload the
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
76 # HTTP status line message for error reporting.
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
77 try:
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
78 checkperm(rctx, req, 'pull' if permission == b'ro' else 'push')
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
79 except hgwebcommon.ErrorResponse as e:
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
80 res.status = hgwebcommon.statusmessage(e.code, pycompat.bytestr(e))
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
81 for k, v in e.headers:
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
82 res.headers[k] = v
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
83 res.setbodybytes('permission denied')
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
84 return
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
85
37055
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
86 # We have a special endpoint to reflect the request back at the client.
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
87 if command == b'debugreflect':
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
88 _processhttpv2reflectrequest(rctx.repo.ui, rctx.repo, req, res)
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
89 return
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
90
37062
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
91 # Extra commands that we handle that aren't really wire protocol
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
92 # commands. Think extra hard before making this hackery available to
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
93 # extension.
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
94 extracommands = {'multirequest'}
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
95
37784
ee0d5e9d77b2 wireproto: move version 2 commands dict to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37783
diff changeset
96 if command not in COMMANDS and command not in extracommands:
37050
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
97 res.status = b'404 Not Found'
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
98 res.headers[b'Content-Type'] = b'text/plain'
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
99 res.setbodybytes(_('unknown wire protocol command: %s\n') % command)
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
100 return
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
101
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
102 repo = rctx.repo
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
103 ui = repo.ui
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
104
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
105 proto = httpv2protocolhandler(req, ui)
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
106
37784
ee0d5e9d77b2 wireproto: move version 2 commands dict to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37783
diff changeset
107 if (not COMMANDS.commandavailable(command, proto)
37062
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
108 and command not in extracommands):
37050
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
109 res.status = b'404 Not Found'
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
110 res.headers[b'Content-Type'] = b'text/plain'
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
111 res.setbodybytes(_('invalid wire protocol command: %s') % command)
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
112 return
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
113
37132
aaabd709df72 wireproto: review fixups
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37123
diff changeset
114 # TODO consider cases where proxies may add additional Accept headers.
37054
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
115 if req.headers.get(b'Accept') != FRAMINGTYPE:
37053
37d7a1d18b97 wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
116 res.status = b'406 Not Acceptable'
37d7a1d18b97 wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
117 res.headers[b'Content-Type'] = b'text/plain'
37d7a1d18b97 wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
118 res.setbodybytes(_('client MUST specify Accept header with value: %s\n')
37054
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
119 % FRAMINGTYPE)
37053
37d7a1d18b97 wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
120 return
37d7a1d18b97 wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
121
37055
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
122 if req.headers.get(b'Content-Type') != FRAMINGTYPE:
37053
37d7a1d18b97 wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
123 res.status = b'415 Unsupported Media Type'
37d7a1d18b97 wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
124 # TODO we should send a response with appropriate media type,
37d7a1d18b97 wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
125 # since client does Accept it.
37d7a1d18b97 wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
126 res.headers[b'Content-Type'] = b'text/plain'
37d7a1d18b97 wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
127 res.setbodybytes(_('client MUST send Content-Type header with '
37054
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
128 'value: %s\n') % FRAMINGTYPE)
37053
37d7a1d18b97 wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
129 return
37d7a1d18b97 wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
130
37057
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
131 _processhttpv2request(ui, repo, req, res, permission, command, proto)
37049
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36883
diff changeset
132
37055
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
133 def _processhttpv2reflectrequest(ui, repo, req, res):
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
134 """Reads unified frame protocol request and dumps out state to client.
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
135
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
136 This special endpoint can be used to help debug the wire protocol.
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
137
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
138 Instead of routing the request through the normal dispatch mechanism,
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
139 we instead read all frames, decode them, and feed them into our state
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
140 tracker. We then dump the log of all that activity back out to the
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
141 client.
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
142 """
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
143 import json
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
144
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
145 # Reflection APIs have a history of being abused, accidentally disclosing
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
146 # sensitive data, etc. So we have a config knob.
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
147 if not ui.configbool('experimental', 'web.api.debugreflect'):
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
148 res.status = b'404 Not Found'
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
149 res.headers[b'Content-Type'] = b'text/plain'
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
150 res.setbodybytes(_('debugreflect service not available'))
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
151 return
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
152
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
153 # We assume we have a unified framing protocol request body.
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
154
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
155 reactor = wireprotoframing.serverreactor()
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
156 states = []
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
157
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
158 while True:
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
159 frame = wireprotoframing.readframe(req.bodyfh)
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
160
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
161 if not frame:
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
162 states.append(b'received: <no frame>')
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
163 break
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
164
37064
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37062
diff changeset
165 states.append(b'received: %d %d %d %s' % (frame.typeid, frame.flags,
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37062
diff changeset
166 frame.requestid,
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37062
diff changeset
167 frame.payload))
37055
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
168
37064
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37062
diff changeset
169 action, meta = reactor.onframerecv(frame)
37055
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
170 states.append(json.dumps((action, meta), sort_keys=True,
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
171 separators=(', ', ': ')))
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
172
37059
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
173 action, meta = reactor.oninputeof()
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
174 meta['action'] = action
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
175 states.append(json.dumps(meta, sort_keys=True, separators=(', ',': ')))
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
176
37055
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
177 res.status = b'200 OK'
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
178 res.headers[b'Content-Type'] = b'text/plain'
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
179 res.setbodybytes(b'\n'.join(states))
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
180
37057
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
181 def _processhttpv2request(ui, repo, req, res, authedperm, reqcommand, proto):
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
182 """Post-validation handler for HTTPv2 requests.
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
183
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
184 Called when the HTTP request contains unified frame-based protocol
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
185 frames for evaluation.
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
186 """
37059
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
187 # TODO Some HTTP clients are full duplex and can receive data before
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
188 # the entire request is transmitted. Figure out a way to indicate support
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
189 # for that so we can opt into full duplex mode.
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
190 reactor = wireprotoframing.serverreactor(deferoutput=True)
37057
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
191 seencommand = False
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
192
37289
5fadc63ac99f wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37288
diff changeset
193 outstream = reactor.makeoutputstream()
5fadc63ac99f wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37288
diff changeset
194
37057
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
195 while True:
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
196 frame = wireprotoframing.readframe(req.bodyfh)
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
197 if not frame:
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
198 break
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
199
37064
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37062
diff changeset
200 action, meta = reactor.onframerecv(frame)
37057
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
201
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
202 if action == 'wantframe':
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
203 # Need more data before we can do anything.
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
204 continue
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
205 elif action == 'runcommand':
37062
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
206 sentoutput = _httpv2runcommand(ui, repo, req, res, authedperm,
37289
5fadc63ac99f wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37288
diff changeset
207 reqcommand, reactor, outstream,
5fadc63ac99f wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37288
diff changeset
208 meta, issubsequent=seencommand)
37062
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
209
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
210 if sentoutput:
37057
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
211 return
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
212
37062
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
213 seencommand = True
37057
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
214
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
215 elif action == 'error':
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
216 # TODO define proper error mechanism.
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
217 res.status = b'200 OK'
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
218 res.headers[b'Content-Type'] = b'text/plain'
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
219 res.setbodybytes(meta['message'] + b'\n')
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
220 return
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
221 else:
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
222 raise error.ProgrammingError(
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
223 'unhandled action from frame processor: %s' % action)
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
224
37059
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
225 action, meta = reactor.oninputeof()
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
226 if action == 'sendframes':
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
227 # We assume we haven't started sending the response yet. If we're
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
228 # wrong, the response type will raise an exception.
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
229 res.status = b'200 OK'
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
230 res.headers[b'Content-Type'] = FRAMINGTYPE
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
231 res.setbodygen(meta['framegen'])
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
232 elif action == 'noop':
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
233 pass
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
234 else:
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
235 raise error.ProgrammingError('unhandled action from frame processor: %s'
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
236 % action)
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
237
37057
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
238 def _httpv2runcommand(ui, repo, req, res, authedperm, reqcommand, reactor,
37289
5fadc63ac99f wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37288
diff changeset
239 outstream, command, issubsequent):
37057
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
240 """Dispatch a wire protocol command made from HTTPv2 requests.
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
241
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
242 The authenticated permission (``authedperm``) along with the original
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
243 command from the URL (``reqcommand``) are passed in.
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
244 """
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
245 # We already validated that the session has permissions to perform the
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
246 # actions in ``authedperm``. In the unified frame protocol, the canonical
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
247 # command to run is expressed in a frame. However, the URL also requested
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
248 # to run a specific command. We need to be careful that the command we
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
249 # run doesn't have permissions requirements greater than what was granted
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
250 # by ``authedperm``.
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
251 #
37062
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
252 # Our rule for this is we only allow one command per HTTP request and
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
253 # that command must match the command in the URL. However, we make
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
254 # an exception for the ``multirequest`` URL. This URL is allowed to
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
255 # execute multiple commands. We double check permissions of each command
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
256 # as it is invoked to ensure there is no privilege escalation.
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
257 # TODO consider allowing multiple commands to regular command URLs
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
258 # iff each command is the same.
37057
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
259
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
260 proto = httpv2protocolhandler(req, ui, args=command['args'])
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
261
37062
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
262 if reqcommand == b'multirequest':
37784
ee0d5e9d77b2 wireproto: move version 2 commands dict to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37783
diff changeset
263 if not COMMANDS.commandavailable(command['command'], proto):
37062
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
264 # TODO proper error mechanism
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
265 res.status = b'200 OK'
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
266 res.headers[b'Content-Type'] = b'text/plain'
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
267 res.setbodybytes(_('wire protocol command not available: %s') %
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
268 command['command'])
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
269 return True
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
270
37132
aaabd709df72 wireproto: review fixups
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37123
diff changeset
271 # TODO don't use assert here, since it may be elided by -O.
37062
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
272 assert authedperm in (b'ro', b'rw')
37784
ee0d5e9d77b2 wireproto: move version 2 commands dict to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37783
diff changeset
273 wirecommand = COMMANDS[command['command']]
37062
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
274 assert wirecommand.permission in ('push', 'pull')
37057
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
275
37062
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
276 if authedperm == b'ro' and wirecommand.permission != 'pull':
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
277 # TODO proper error mechanism
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
278 res.status = b'403 Forbidden'
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
279 res.headers[b'Content-Type'] = b'text/plain'
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
280 res.setbodybytes(_('insufficient permissions to execute '
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
281 'command: %s') % command['command'])
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
282 return True
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
283
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
284 # TODO should we also call checkperm() here? Maybe not if we're going
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
285 # to overhaul that API. The granted scope from the URL check should
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
286 # be good enough.
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
287
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
288 else:
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
289 # Don't allow multiple commands outside of ``multirequest`` URL.
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
290 if issubsequent:
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
291 # TODO proper error mechanism
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
292 res.status = b'200 OK'
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
293 res.headers[b'Content-Type'] = b'text/plain'
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
294 res.setbodybytes(_('multiple commands cannot be issued to this '
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
295 'URL'))
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
296 return True
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
297
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
298 if reqcommand != command['command']:
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
299 # TODO define proper error mechanism
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
300 res.status = b'200 OK'
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
301 res.headers[b'Content-Type'] = b'text/plain'
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
302 res.setbodybytes(_('command in frame must match command in URL'))
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
303 return True
37057
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
304
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
305 res.status = b'200 OK'
37058
61393f888dfe wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
306 res.headers[b'Content-Type'] = FRAMINGTYPE
37057
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
307
39575
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39467
diff changeset
308 try:
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39467
diff changeset
309 objs = dispatch(repo, proto, command['command'])
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39467
diff changeset
310
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39467
diff changeset
311 action, meta = reactor.oncommandresponsereadyobjects(
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39467
diff changeset
312 outstream, command['requestid'], objs)
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39467
diff changeset
313
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39467
diff changeset
314 except Exception as e:
37726
0c184ca594bb wireprotov2: change behavior of error frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37725
diff changeset
315 action, meta = reactor.onservererror(
39575
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39467
diff changeset
316 outstream, command['requestid'],
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39467
diff changeset
317 _('exception when invoking command: %s') % e)
37058
61393f888dfe wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
318
61393f888dfe wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
319 if action == 'sendframes':
61393f888dfe wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
320 res.setbodygen(meta['framegen'])
37062
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
321 return True
37059
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
322 elif action == 'noop':
37132
aaabd709df72 wireproto: review fixups
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37123
diff changeset
323 return False
37058
61393f888dfe wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
324 else:
61393f888dfe wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
325 raise error.ProgrammingError('unhandled event from reactor: %s' %
61393f888dfe wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
326 action)
37057
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
327
37782
99accae4cc59 wireproto: reimplement dispatch() for version 2 server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37781
diff changeset
328 def getdispatchrepo(repo, proto, command):
99accae4cc59 wireproto: reimplement dispatch() for version 2 server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37781
diff changeset
329 return repo.filtered('served')
99accae4cc59 wireproto: reimplement dispatch() for version 2 server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37781
diff changeset
330
99accae4cc59 wireproto: reimplement dispatch() for version 2 server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37781
diff changeset
331 def dispatch(repo, proto, command):
99accae4cc59 wireproto: reimplement dispatch() for version 2 server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37781
diff changeset
332 repo = getdispatchrepo(repo, proto, command)
99accae4cc59 wireproto: reimplement dispatch() for version 2 server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37781
diff changeset
333
37784
ee0d5e9d77b2 wireproto: move version 2 commands dict to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37783
diff changeset
334 func, spec = COMMANDS[command]
37782
99accae4cc59 wireproto: reimplement dispatch() for version 2 server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37781
diff changeset
335 args = proto.getargs(spec)
99accae4cc59 wireproto: reimplement dispatch() for version 2 server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37781
diff changeset
336
99accae4cc59 wireproto: reimplement dispatch() for version 2 server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37781
diff changeset
337 return func(repo, proto, **args)
99accae4cc59 wireproto: reimplement dispatch() for version 2 server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37781
diff changeset
338
37810
856f381ad74b interfaceutil: module to stub out zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37784
diff changeset
339 @interfaceutil.implementer(wireprototypes.baseprotocolhandler)
37296
78103e4138b1 wireproto: port protocol handler to zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37295
diff changeset
340 class httpv2protocolhandler(object):
37057
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
341 def __init__(self, req, ui, args=None):
37050
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
342 self._req = req
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
343 self._ui = ui
37057
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
344 self._args = args
37050
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
345
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
346 @property
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
347 def name(self):
37644
77c9ee77687c wireproto: rename HTTPV2 so it less like HTTP/2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37557
diff changeset
348 return HTTP_WIREPROTO_V2
37050
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
349
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
350 def getargs(self, args):
37057
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
351 data = {}
37535
69e46c1834ac wireproto: define and expose types of wire command arguments
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37533
diff changeset
352 for k, typ in args.items():
37057
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
353 if k == '*':
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
354 raise NotImplementedError('do not support * args')
37485
0b7475ea38cf wireproto: port heads command to wire protocol v2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37414
diff changeset
355 elif k in self._args:
37535
69e46c1834ac wireproto: define and expose types of wire command arguments
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37533
diff changeset
356 # TODO consider validating value types.
37057
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
357 data[k] = self._args[k]
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
358
37485
0b7475ea38cf wireproto: port heads command to wire protocol v2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37414
diff changeset
359 return data
37050
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
360
37393
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37296
diff changeset
361 def getprotocaps(self):
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37296
diff changeset
362 # 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
363 return set()
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37296
diff changeset
364
37414
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37393
diff changeset
365 def getpayload(self):
37050
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
366 raise NotImplementedError
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
367
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
368 @contextlib.contextmanager
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
369 def mayberedirectstdio(self):
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
370 raise NotImplementedError
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
371
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
372 def client(self):
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
373 raise NotImplementedError
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
374
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
375 def addcapabilities(self, repo, caps):
37057
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
376 return caps
37050
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
377
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
378 def checkperm(self, perm):
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37049
diff changeset
379 raise NotImplementedError
37546
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
380
37557
734515aca84d wireproto: define and implement HTTP handshake to upgrade protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
381 def httpv2apidescriptor(req, repo):
734515aca84d wireproto: define and implement HTTP handshake to upgrade protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
382 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
383
734515aca84d wireproto: define and implement HTTP handshake to upgrade protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
384 return _capabilitiesv2(repo, proto)
734515aca84d wireproto: define and implement HTTP handshake to upgrade protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
385
37546
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
386 def _capabilitiesv2(repo, proto):
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
387 """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
388
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
389 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
390 transports.
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
391 """
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
392 compression = []
37783
9d818539abfa wireproto: move supportedcompengines out of wireproto
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37782
diff changeset
393 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
394 compression.append({
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
395 b'name': engine.wireprotosupport().name,
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
396 })
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
397
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
398 caps = {
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
399 'commands': {},
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
400 'compression': compression,
37653
b2fa1591fb44 wireproto: add media type to version 2 capabilities response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37644
diff changeset
401 'framingmediatypes': [FRAMINGTYPE],
37546
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
402 }
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
403
39652
399ddd3227a4 wireprotov2: add TODOs around extending changesetdata fields
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39650
diff changeset
404 # TODO expose available changesetdata fields.
399ddd3227a4 wireprotov2: add TODOs around extending changesetdata fields
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39650
diff changeset
405
37784
ee0d5e9d77b2 wireproto: move version 2 commands dict to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37783
diff changeset
406 for command, entry in COMMANDS.items():
37546
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
407 caps['commands'][command] = {
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
408 'args': entry.args,
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
409 'permissions': [entry.permission],
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
410 }
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
411
37657
23c4ddda7bbe wireproto: expose repository formats via capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37653
diff changeset
412 if streamclone.allowservergeneration(repo):
23c4ddda7bbe wireproto: expose repository formats via capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37653
diff changeset
413 caps['rawrepoformats'] = sorted(repo.requirements &
23c4ddda7bbe wireproto: expose repository formats via capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37653
diff changeset
414 repo.supportedformats)
23c4ddda7bbe wireproto: expose repository formats via capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37653
diff changeset
415
37546
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
416 return proto.addcapabilities(repo, caps)
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
417
39653
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
418 def builddeltarequests(store, nodes):
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
419 """Build a series of revision delta requests against a backend store.
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
420
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
421 Returns a list of revision numbers in the order they should be sent
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
422 and a list of ``irevisiondeltarequest`` instances to be made against
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
423 the backend store.
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
424 """
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
425 # We sort and send nodes in DAG order because this is optimal for
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
426 # storage emission.
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
427 # TODO we may want a better storage API here - one where we can throw
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
428 # a list of nodes and delta preconditions over a figurative wall and
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
429 # have the storage backend figure it out for us.
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
430 revs = dagop.linearize({store.rev(n) for n in nodes}, store.parentrevs)
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
431
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
432 requests = []
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
433
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
434 for rev in revs:
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
435 node = store.node(rev)
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
436 parents = store.parents(node)
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
437 deltaparent = store.node(store.deltaparent(rev))
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
438
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
439 # There is a delta in storage. That means we can send the delta
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
440 # efficiently.
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
441 #
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
442 # But, the delta may be against a revision the receiver doesn't
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
443 # have (e.g. shallow clone or when the delta isn't against a parent
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
444 # revision). For now, we ignore the problem of shallow clone. As
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
445 # long as a delta exists against a parent, we send it.
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
446 # TODO allow arguments to control this behavior, as the receiver
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
447 # may not have the base revision in some scenarios.
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
448 if deltaparent != nullid and deltaparent in parents:
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
449 basenode = deltaparent
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
450
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
451 # Else there is no delta parent in storage or the delta that is
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
452 # # there isn't suitable. Let's use a delta against a parent
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
453 # revision, if possible.
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
454 #
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
455 # There is room to check if the delta parent is in the ancestry of
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
456 # this node. But there isn't an API on the manifest storage object
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
457 # for that. So ignore this case for now.
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
458
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
459 elif parents[0] != nullid:
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
460 basenode = parents[0]
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
461 elif parents[1] != nullid:
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
462 basenode = parents[1]
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
463
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
464 # No potential bases to delta against. Send a full revision.
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
465 else:
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
466 basenode = nullid
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
467
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
468 requests.append(changegroup.revisiondeltarequest(
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
469 node=node,
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
470 p1node=parents[0],
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
471 p2node=parents[1],
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
472 # Receiver deals with linknode resolution.
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
473 linknode=nullid,
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
474 basenode=basenode,
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
475 ))
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
476
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
477 return revs, requests
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
478
37780
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
479 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
480 """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
481
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
482 ``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
483
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
484 ``args`` is a dict of argument names to example values.
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
485
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
486 ``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
487 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
488 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
489 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
490 a repository that is supposed to be read-only.
39575
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39467
diff changeset
491
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39467
diff changeset
492 Wire protocol commands are generators of objects to be serialized and
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39467
diff changeset
493 sent to the client.
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39467
diff changeset
494
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39467
diff changeset
495 If a command raises an uncaught exception, this will be translated into
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39467
diff changeset
496 a command error.
37780
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
497 """
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
498 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
499 if v['version'] == 2}
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
500
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
501 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
502 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
503 '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
504 permission)
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
505
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
506 if args is None:
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
507 args = {}
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
508
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
509 if not isinstance(args, dict):
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
510 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
511 'must be declared as dicts')
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
512
37546
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
513 def register(func):
37784
ee0d5e9d77b2 wireproto: move version 2 commands dict to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37783
diff changeset
514 if name in COMMANDS:
37780
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
515 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
516 'for version 2' % name)
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
517
37784
ee0d5e9d77b2 wireproto: move version 2 commands dict to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37783
diff changeset
518 COMMANDS[name] = wireprototypes.commandentry(
37780
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
519 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
520
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
521 return func
37546
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
522
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
523 return register
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
524
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
525 @wireprotocommand('branchmap', permission='pull')
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
526 def branchmapv2(repo, proto):
39575
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39467
diff changeset
527 yield {encoding.fromlocal(k): v
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39467
diff changeset
528 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
529
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
530 @wireprotocommand('capabilities', permission='pull')
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
531 def capabilitiesv2(repo, proto):
39575
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39467
diff changeset
532 yield _capabilitiesv2(repo, proto)
37546
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
533
39646
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
534 @wireprotocommand('changesetdata',
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
535 args={
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
536 'noderange': [[b'0123456...'], [b'abcdef...']],
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
537 'nodes': [b'0123456...'],
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
538 'fields': {b'parents', b'revision'},
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
539 },
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
540 permission='pull')
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
541 def changesetdata(repo, proto, noderange=None, nodes=None, fields=None):
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
542 fields = fields or set()
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
543
39652
399ddd3227a4 wireprotov2: add TODOs around extending changesetdata fields
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39650
diff changeset
544 # TODO look for unknown fields and abort when they can't be serviced.
399ddd3227a4 wireprotov2: add TODOs around extending changesetdata fields
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39650
diff changeset
545
39646
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
546 if noderange is None and nodes is None:
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
547 raise error.WireprotoCommandError(
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
548 'noderange or nodes must be defined')
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
549
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
550 if noderange is not None:
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
551 if len(noderange) != 2:
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
552 raise error.WireprotoCommandError(
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
553 'noderange must consist of 2 elements')
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
554
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
555 if not noderange[1]:
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
556 raise error.WireprotoCommandError(
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
557 'heads in noderange request cannot be empty')
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
558
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
559 cl = repo.changelog
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
560 hasnode = cl.hasnode
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
561
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
562 seen = set()
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
563 outgoing = []
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
564
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
565 if nodes is not None:
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
566 outgoing.extend(n for n in nodes if hasnode(n))
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
567 seen |= set(outgoing)
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
568
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
569 if noderange is not None:
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
570 if noderange[0]:
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
571 common = [n for n in noderange[0] if hasnode(n)]
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
572 else:
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
573 common = [nullid]
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
574
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
575 for n in discovery.outgoing(repo, common, noderange[1]).missing:
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
576 if n not in seen:
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
577 outgoing.append(n)
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
578 # Don't need to add to seen here because this is the final
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
579 # source of nodes and there should be no duplicates in this
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
580 # list.
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
581
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
582 seen.clear()
39648
c1aacb0d76ff wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39646
diff changeset
583 publishing = repo.publishing()
39646
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
584
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
585 if outgoing:
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
586 repo.hook('preoutgoing', throw=True, source='serve')
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
587
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
588 yield {
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
589 b'totalitems': len(outgoing),
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
590 }
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
591
39648
c1aacb0d76ff wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39646
diff changeset
592 # The phases of nodes already transferred to the client may have changed
c1aacb0d76ff wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39646
diff changeset
593 # since the client last requested data. We send phase-only records
c1aacb0d76ff wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39646
diff changeset
594 # for these revisions, if requested.
c1aacb0d76ff wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39646
diff changeset
595 if b'phase' in fields and noderange is not None:
c1aacb0d76ff wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39646
diff changeset
596 # TODO skip nodes whose phase will be reflected by a node in the
c1aacb0d76ff wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39646
diff changeset
597 # outgoing set. This is purely an optimization to reduce data
c1aacb0d76ff wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39646
diff changeset
598 # size.
c1aacb0d76ff wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39646
diff changeset
599 for node in noderange[0]:
c1aacb0d76ff wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39646
diff changeset
600 yield {
c1aacb0d76ff wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39646
diff changeset
601 b'node': node,
c1aacb0d76ff wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39646
diff changeset
602 b'phase': b'public' if publishing else repo[node].phasestr()
c1aacb0d76ff wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39646
diff changeset
603 }
c1aacb0d76ff wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39646
diff changeset
604
39650
9dffa99f9158 wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39648
diff changeset
605 nodebookmarks = {}
9dffa99f9158 wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39648
diff changeset
606 for mark, node in repo._bookmarks.items():
9dffa99f9158 wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39648
diff changeset
607 nodebookmarks.setdefault(node, set()).add(mark)
9dffa99f9158 wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39648
diff changeset
608
39646
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
609 # It is already topologically sorted by revision number.
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
610 for node in outgoing:
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
611 d = {
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
612 b'node': node,
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
613 }
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
614
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
615 if b'parents' in fields:
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
616 d[b'parents'] = cl.parents(node)
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
617
39648
c1aacb0d76ff wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39646
diff changeset
618 if b'phase' in fields:
c1aacb0d76ff wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39646
diff changeset
619 if publishing:
c1aacb0d76ff wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39646
diff changeset
620 d[b'phase'] = b'public'
c1aacb0d76ff wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39646
diff changeset
621 else:
c1aacb0d76ff wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39646
diff changeset
622 ctx = repo[node]
c1aacb0d76ff wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39646
diff changeset
623 d[b'phase'] = ctx.phasestr()
c1aacb0d76ff wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39646
diff changeset
624
39650
9dffa99f9158 wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39648
diff changeset
625 if b'bookmarks' in fields and node in nodebookmarks:
9dffa99f9158 wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39648
diff changeset
626 d[b'bookmarks'] = sorted(nodebookmarks[node])
9dffa99f9158 wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39648
diff changeset
627 del nodebookmarks[node]
9dffa99f9158 wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39648
diff changeset
628
39646
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
629 revisiondata = None
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
630
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
631 if b'revision' in fields:
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
632 revisiondata = cl.revision(node, raw=True)
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
633 d[b'revisionsize'] = len(revisiondata)
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
634
39652
399ddd3227a4 wireprotov2: add TODOs around extending changesetdata fields
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39650
diff changeset
635 # TODO make it possible for extensions to wrap a function or register
399ddd3227a4 wireprotov2: add TODOs around extending changesetdata fields
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39650
diff changeset
636 # a handler to service custom fields.
399ddd3227a4 wireprotov2: add TODOs around extending changesetdata fields
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39650
diff changeset
637
39646
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
638 yield d
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
639
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
640 if revisiondata is not None:
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
641 yield revisiondata
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39575
diff changeset
642
39650
9dffa99f9158 wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39648
diff changeset
643 # If requested, send bookmarks from nodes that didn't have revision
9dffa99f9158 wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39648
diff changeset
644 # data sent so receiver is aware of any bookmark updates.
9dffa99f9158 wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39648
diff changeset
645 if b'bookmarks' in fields:
9dffa99f9158 wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39648
diff changeset
646 for node, marks in sorted(nodebookmarks.iteritems()):
9dffa99f9158 wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39648
diff changeset
647 yield {
9dffa99f9158 wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39648
diff changeset
648 b'node': node,
9dffa99f9158 wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39648
diff changeset
649 b'bookmarks': sorted(marks),
9dffa99f9158 wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39648
diff changeset
650 }
9dffa99f9158 wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39648
diff changeset
651
39655
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
652 class FileAccessError(Exception):
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
653 """Represents an error accessing a specific file."""
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
654
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
655 def __init__(self, path, msg, args):
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
656 self.path = path
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
657 self.msg = msg
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
658 self.args = args
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
659
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
660 def getfilestore(repo, proto, path):
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
661 """Obtain a file storage object for use with wire protocol.
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
662
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
663 Exists as a standalone function so extensions can monkeypatch to add
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
664 access control.
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
665 """
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
666 # This seems to work even if the file doesn't exist. So catch
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
667 # "empty" files and return an error.
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
668 fl = repo.file(path)
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
669
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
670 if not len(fl):
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
671 raise FileAccessError(path, 'unknown file: %s', (path,))
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
672
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
673 return fl
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
674
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
675 @wireprotocommand('filedata',
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
676 args={
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
677 'nodes': [b'0123456...'],
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
678 'fields': [b'parents', b'revision'],
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
679 'path': b'foo.txt',
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
680 },
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
681 permission='pull')
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
682 def filedata(repo, proto, nodes=None, fields=None, path=None):
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
683 fields = fields or set()
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
684
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
685 if nodes is None:
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
686 raise error.WireprotoCommandError('nodes argument must be defined')
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
687
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
688 if path is None:
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
689 raise error.WireprotoCommandError('path argument must be defined')
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
690
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
691 try:
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
692 # Extensions may wish to access the protocol handler.
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
693 store = getfilestore(repo, proto, path)
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
694 except FileAccessError as e:
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
695 raise error.WireprotoCommandError(e.msg, e.args)
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
696
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
697 # Validate requested nodes.
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
698 for node in nodes:
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
699 try:
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
700 store.rev(node)
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
701 except error.LookupError:
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
702 raise error.WireprotoCommandError('unknown file node: %s',
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
703 (hex(node),))
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
704
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
705 revs, requests = builddeltarequests(store, nodes)
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
706
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
707 yield {
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
708 b'totalitems': len(revs),
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
709 }
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
710
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
711 if b'revision' in fields:
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
712 deltas = store.emitrevisiondeltas(requests)
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
713 else:
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
714 deltas = None
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
715
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
716 for rev in revs:
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
717 node = store.node(rev)
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
718
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
719 if deltas is not None:
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
720 delta = next(deltas)
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
721 else:
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
722 delta = None
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
723
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
724 d = {
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
725 b'node': node,
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
726 }
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
727
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
728 if b'parents' in fields:
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
729 d[b'parents'] = store.parents(node)
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
730
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
731 if b'revision' in fields:
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
732 assert delta is not None
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
733 assert delta.flags == 0
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
734 assert d[b'node'] == delta.node
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
735
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
736 if delta.revision is not None:
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
737 revisiondata = delta.revision
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
738 d[b'revisionsize'] = len(revisiondata)
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
739 else:
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
740 d[b'deltabasenode'] = delta.basenode
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
741 revisiondata = delta.delta
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
742 d[b'deltasize'] = len(revisiondata)
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
743 else:
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
744 revisiondata = None
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
745
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
746 yield d
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
747
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
748 if revisiondata is not None:
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
749 yield revisiondata
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
750
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
751 if deltas is not None:
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
752 try:
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
753 next(deltas)
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
754 raise error.ProgrammingError('should not have more deltas')
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
755 except GeneratorExit:
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
756 pass
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39653
diff changeset
757
37546
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
758 @wireprotocommand('heads',
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
759 args={
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
760 'publiconly': False,
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
761 },
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
762 permission='pull')
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
763 def headsv2(repo, proto, publiconly=False):
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
764 if publiconly:
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
765 repo = repo.filtered('immutable')
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
766
39575
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39467
diff changeset
767 yield repo.heads()
37546
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
768
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
769 @wireprotocommand('known',
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
770 args={
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
771 'nodes': [b'deadbeef'],
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
772 },
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
773 permission='pull')
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
774 def knownv2(repo, proto, nodes=None):
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
775 nodes = nodes or []
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
776 result = b''.join(b'1' if n else b'0' for n in repo.known(nodes))
39575
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39467
diff changeset
777 yield result
37546
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
778
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
779 @wireprotocommand('listkeys',
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
780 args={
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
781 'namespace': b'ns',
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
782 },
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
783 permission='pull')
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
784 def listkeysv2(repo, proto, namespace=None):
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
785 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
786 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
787 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
788
39575
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39467
diff changeset
789 yield keys
37546
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
790
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
791 @wireprotocommand('lookup',
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
792 args={
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
793 'key': b'foo',
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
794 },
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
795 permission='pull')
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
796 def lookupv2(repo, proto, key):
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
797 key = encoding.tolocal(key)
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
798
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
799 # TODO handle exception.
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
800 node = repo.lookup(key)
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
801
39575
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39467
diff changeset
802 yield node
37546
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
803
39653
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
804 @wireprotocommand('manifestdata',
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
805 args={
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
806 'nodes': [b'0123456...'],
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
807 'fields': [b'parents', b'revision'],
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
808 'tree': b'',
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
809 },
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
810 permission='pull')
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
811 def manifestdata(repo, proto, nodes=None, fields=None, tree=None):
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
812 fields = fields or set()
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
813
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
814 if nodes is None:
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
815 raise error.WireprotoCommandError(
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
816 'nodes argument must be defined')
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
817
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
818 if tree is None:
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
819 raise error.WireprotoCommandError(
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
820 'tree argument must be defined')
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
821
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
822 store = repo.manifestlog.getstorage(tree)
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
823
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
824 # Validate the node is known and abort on unknown revisions.
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
825 for node in nodes:
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
826 try:
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
827 store.rev(node)
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
828 except error.LookupError:
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
829 raise error.WireprotoCommandError(
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
830 'unknown node: %s', (node,))
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
831
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
832 revs, requests = builddeltarequests(store, nodes)
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
833
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
834 yield {
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
835 b'totalitems': len(revs),
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
836 }
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
837
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
838 if b'revision' in fields:
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
839 deltas = store.emitrevisiondeltas(requests)
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
840 else:
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
841 deltas = None
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
842
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
843 for rev in revs:
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
844 node = store.node(rev)
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
845
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
846 if deltas is not None:
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
847 delta = next(deltas)
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
848 else:
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
849 delta = None
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
850
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
851 d = {
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
852 b'node': node,
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
853 }
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
854
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
855 if b'parents' in fields:
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
856 d[b'parents'] = store.parents(node)
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
857
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
858 if b'revision' in fields:
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
859 assert delta is not None
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
860 assert delta.flags == 0
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
861 assert d[b'node'] == delta.node
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
862
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
863 if delta.revision is not None:
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
864 revisiondata = delta.revision
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
865 d[b'revisionsize'] = len(revisiondata)
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
866 else:
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
867 d[b'deltabasenode'] = delta.basenode
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
868 revisiondata = delta.delta
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
869 d[b'deltasize'] = len(revisiondata)
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
870 else:
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
871 revisiondata = None
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
872
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
873 yield d
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
874
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
875 if revisiondata is not None:
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
876 yield revisiondata
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
877
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
878 if deltas is not None:
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
879 try:
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
880 next(deltas)
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
881 raise error.ProgrammingError('should not have more deltas')
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
882 except GeneratorExit:
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
883 pass
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39652
diff changeset
884
37546
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
885 @wireprotocommand('pushkey',
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
886 args={
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
887 'namespace': b'ns',
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
888 'key': b'key',
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
889 'old': b'old',
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
890 'new': b'new',
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
891 },
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
892 permission='push')
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
893 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
894 # TODO handle ui output redirection
39575
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39467
diff changeset
895 yield repo.pushkey(encoding.tolocal(namespace),
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39467
diff changeset
896 encoding.tolocal(key),
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39467
diff changeset
897 encoding.tolocal(old),
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39467
diff changeset
898 encoding.tolocal(new))