annotate mercurial/wireprotov2server.py @ 40094:ff47ba7a2903

tests: use NO_CHECK_EOF as heredoc limit mark to omit checking code fragments This patch uses NO_CHECK_EOF as heredoc limit mark instead of EOF, in order to avoid checking all python code fragments in test-contrib-check-code.t, because almost all of them has un-recommended implementations intentionally.
author FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
date Thu, 23 Aug 2018 12:25:54 +0900
parents 39074a35f7db
children 9b19b8ce3804
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
5598
d534ba1c4eb4 separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
1 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
d534ba1c4eb4 separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
2 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
d534ba1c4eb4 separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
3 #
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 8109
diff changeset
4 # This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9713
diff changeset
5 # GNU General Public License version 2 or any later version.
5598
d534ba1c4eb4 separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
6
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 20903
diff changeset
7 from __future__ import absolute_import
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 20903
diff changeset
8
36066
2ad145fbde54 wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36065
diff changeset
9 import contextlib
40021
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
10 import hashlib
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 20903
diff changeset
11
35859
1bf5263fe5cc wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35858
diff changeset
12 from .i18n import _
39630
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
13 from .node import (
39639
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
14 hex,
39630
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
15 nullid,
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
16 )
35856
ef3a24a023ec wireprotoserver: rename hgweb.protocol to wireprotoserver (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35750
diff changeset
17 from . import (
39630
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
18 discovery,
37546
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
19 encoding,
34509
e21f274cccea hgweb: in protocol adapter, avoid control reaching end of non-void function
Augie Fackler <augie@google.com>
parents: 33821
diff changeset
20 error,
39811
ae20f52437e9 wireprotov2: advertise recognized path filter prefixes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39810
diff changeset
21 narrowspec,
34742
5a9cad0dfddb hgweb: when unpacking args from request form, convert to bytes
Augie Fackler <augie@google.com>
parents: 34740
diff changeset
22 pycompat,
37546
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
23 util,
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
24 wireprotoframing,
36073
cd6ab329c5c7 wireprototypes: move wire protocol response types to new module
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36072
diff changeset
25 wireprototypes,
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 20903
diff changeset
26 )
37810
856f381ad74b interfaceutil: module to stub out zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37784
diff changeset
27 from .utils import (
40021
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
28 cborutil,
37810
856f381ad74b interfaceutil: module to stub out zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37784
diff changeset
29 interfaceutil,
39837
69b4a5b89dc5 py3: cast exception to bytes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39828
diff changeset
30 stringutil,
37810
856f381ad74b interfaceutil: module to stub out zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37784
diff changeset
31 )
35856
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
35976
48a3a9283f09 sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35900
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
40021
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
39 # Value inserted into cache key computation function. Change the value to
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
40 # force new cache keys for every command request. This should be done when
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
41 # there is a change to how caching works, etc.
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
42 GLOBAL_CACHE_VERSION = 1
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
43
37545
93397c4633f6 wireproto: extract HTTP version 2 code to own module
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37535
diff changeset
44 def handlehttpv2request(rctx, req, res, checkperm, urlparts):
37047
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
45 from .hgweb import common as hgwebcommon
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
46
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
47 # URL space looks like: <permissions>/<command>, where <permission> can
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
48 # be ``ro`` or ``rw`` to signal read-only or read-write, respectively.
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
49
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
50 # Root URL does nothing meaningful... yet.
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
51 if not urlparts:
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
52 res.status = b'200 OK'
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
53 res.headers[b'Content-Type'] = b'text/plain'
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
54 res.setbodybytes(_('HTTP version 2 API handler'))
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
55 return
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
56
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
57 if len(urlparts) == 1:
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
58 res.status = b'404 Not Found'
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
59 res.headers[b'Content-Type'] = b'text/plain'
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
60 res.setbodybytes(_('do not know how to process %s\n') %
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
61 req.dispatchpath)
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
62 return
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
63
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
64 permission, command = urlparts[0:2]
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
65
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
66 if permission not in (b'ro', b'rw'):
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
67 res.status = b'404 Not Found'
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
68 res.headers[b'Content-Type'] = b'text/plain'
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
69 res.setbodybytes(_('unknown permission: %s') % permission)
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
70 return
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
71
37048
fc5e261915b9 wireproto: require POST for all HTTPv2 requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37047
diff changeset
72 if req.method != 'POST':
fc5e261915b9 wireproto: require POST for all HTTPv2 requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37047
diff changeset
73 res.status = b'405 Method Not Allowed'
fc5e261915b9 wireproto: require POST for all HTTPv2 requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37047
diff changeset
74 res.headers[b'Allow'] = b'POST'
fc5e261915b9 wireproto: require POST for all HTTPv2 requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37047
diff changeset
75 res.setbodybytes(_('commands require POST requests'))
fc5e261915b9 wireproto: require POST for all HTTPv2 requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37047
diff changeset
76 return
fc5e261915b9 wireproto: require POST for all HTTPv2 requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37047
diff changeset
77
37047
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
78 # At some point we'll want to use our own API instead of recycling the
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
79 # behavior of version 1 of the wire protocol...
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
80 # TODO return reasonable responses - not responses that overload the
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
81 # HTTP status line message for error reporting.
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
82 try:
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
83 checkperm(rctx, req, 'pull' if permission == b'ro' else 'push')
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
84 except hgwebcommon.ErrorResponse as e:
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
85 res.status = hgwebcommon.statusmessage(e.code, pycompat.bytestr(e))
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
86 for k, v in e.headers:
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
87 res.headers[k] = v
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
88 res.setbodybytes('permission denied')
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
89 return
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
90
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
91 # We have a special endpoint to reflect the request back at the client.
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
92 if command == b'debugreflect':
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
93 _processhttpv2reflectrequest(rctx.repo.ui, rctx.repo, req, res)
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
94 return
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
95
37059
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
96 # Extra commands that we handle that aren't really wire protocol
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
97 # commands. Think extra hard before making this hackery available to
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
98 # extension.
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
99 extracommands = {'multirequest'}
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
100
37784
ee0d5e9d77b2 wireproto: move version 2 commands dict to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37783
diff changeset
101 if command not in COMMANDS and command not in extracommands:
37047
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
102 res.status = b'404 Not Found'
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
103 res.headers[b'Content-Type'] = b'text/plain'
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
104 res.setbodybytes(_('unknown wire protocol command: %s\n') % command)
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
105 return
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
106
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
107 repo = rctx.repo
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
108 ui = repo.ui
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
109
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
110 proto = httpv2protocolhandler(req, ui)
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
111
37784
ee0d5e9d77b2 wireproto: move version 2 commands dict to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37783
diff changeset
112 if (not COMMANDS.commandavailable(command, proto)
37059
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
113 and command not in extracommands):
37047
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
114 res.status = b'404 Not Found'
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
115 res.headers[b'Content-Type'] = b'text/plain'
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
116 res.setbodybytes(_('invalid wire protocol command: %s') % command)
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
117 return
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
118
37129
aaabd709df72 wireproto: review fixups
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37120
diff changeset
119 # TODO consider cases where proxies may add additional Accept headers.
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37050
diff changeset
120 if req.headers.get(b'Accept') != FRAMINGTYPE:
37050
37d7a1d18b97 wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37048
diff changeset
121 res.status = b'406 Not Acceptable'
37d7a1d18b97 wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37048
diff changeset
122 res.headers[b'Content-Type'] = b'text/plain'
37d7a1d18b97 wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37048
diff changeset
123 res.setbodybytes(_('client MUST specify Accept header with value: %s\n')
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37050
diff changeset
124 % FRAMINGTYPE)
37050
37d7a1d18b97 wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37048
diff changeset
125 return
37d7a1d18b97 wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37048
diff changeset
126
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
127 if req.headers.get(b'Content-Type') != FRAMINGTYPE:
37050
37d7a1d18b97 wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37048
diff changeset
128 res.status = b'415 Unsupported Media Type'
37d7a1d18b97 wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37048
diff changeset
129 # TODO we should send a response with appropriate media type,
37d7a1d18b97 wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37048
diff changeset
130 # since client does Accept it.
37d7a1d18b97 wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37048
diff changeset
131 res.headers[b'Content-Type'] = b'text/plain'
37d7a1d18b97 wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37048
diff changeset
132 res.setbodybytes(_('client MUST send Content-Type header with '
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37050
diff changeset
133 'value: %s\n') % FRAMINGTYPE)
37050
37d7a1d18b97 wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37048
diff changeset
134 return
37d7a1d18b97 wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37048
diff changeset
135
37054
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
136 _processhttpv2request(ui, repo, req, res, permission, command, proto)
37046
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36877
diff changeset
137
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
138 def _processhttpv2reflectrequest(ui, repo, req, res):
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
139 """Reads unified frame protocol request and dumps out state to client.
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
140
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
141 This special endpoint can be used to help debug the wire protocol.
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
142
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
143 Instead of routing the request through the normal dispatch mechanism,
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
144 we instead read all frames, decode them, and feed them into our state
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
145 tracker. We then dump the log of all that activity back out to the
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
146 client.
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
147 """
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
148 import json
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
149
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
150 # Reflection APIs have a history of being abused, accidentally disclosing
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
151 # sensitive data, etc. So we have a config knob.
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
152 if not ui.configbool('experimental', 'web.api.debugreflect'):
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
153 res.status = b'404 Not Found'
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
154 res.headers[b'Content-Type'] = b'text/plain'
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
155 res.setbodybytes(_('debugreflect service not available'))
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
156 return
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
157
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
158 # We assume we have a unified framing protocol request body.
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
159
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
160 reactor = wireprotoframing.serverreactor()
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
161 states = []
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
162
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
163 while True:
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
164 frame = wireprotoframing.readframe(req.bodyfh)
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
165
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
166 if not frame:
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
167 states.append(b'received: <no frame>')
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
168 break
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
169
37061
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37059
diff changeset
170 states.append(b'received: %d %d %d %s' % (frame.typeid, frame.flags,
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37059
diff changeset
171 frame.requestid,
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37059
diff changeset
172 frame.payload))
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
173
37061
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37059
diff changeset
174 action, meta = reactor.onframerecv(frame)
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
175 states.append(json.dumps((action, meta), sort_keys=True,
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
176 separators=(', ', ': ')))
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
177
37056
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
178 action, meta = reactor.oninputeof()
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
179 meta['action'] = action
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
180 states.append(json.dumps(meta, sort_keys=True, separators=(', ',': ')))
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
181
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
182 res.status = b'200 OK'
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
183 res.headers[b'Content-Type'] = b'text/plain'
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
184 res.setbodybytes(b'\n'.join(states))
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
185
37054
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
186 def _processhttpv2request(ui, repo, req, res, authedperm, reqcommand, proto):
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
187 """Post-validation handler for HTTPv2 requests.
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
188
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
189 Called when the HTTP request contains unified frame-based protocol
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
190 frames for evaluation.
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
191 """
37056
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
192 # TODO Some HTTP clients are full duplex and can receive data before
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
193 # the entire request is transmitted. Figure out a way to indicate support
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
194 # for that so we can opt into full duplex mode.
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
195 reactor = wireprotoframing.serverreactor(deferoutput=True)
37054
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
196 seencommand = False
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
197
37289
5fadc63ac99f wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37288
diff changeset
198 outstream = reactor.makeoutputstream()
5fadc63ac99f wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37288
diff changeset
199
37054
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
200 while True:
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
201 frame = wireprotoframing.readframe(req.bodyfh)
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
202 if not frame:
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
203 break
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
204
37061
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37059
diff changeset
205 action, meta = reactor.onframerecv(frame)
37054
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
206
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
207 if action == 'wantframe':
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
208 # Need more data before we can do anything.
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
209 continue
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
210 elif action == 'runcommand':
37059
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
211 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
212 reqcommand, reactor, outstream,
5fadc63ac99f wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37288
diff changeset
213 meta, issubsequent=seencommand)
37059
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
214
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
215 if sentoutput:
37054
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
216 return
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
217
37059
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
218 seencommand = True
37054
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
219
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
220 elif action == 'error':
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
221 # TODO define proper error mechanism.
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
222 res.status = b'200 OK'
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
223 res.headers[b'Content-Type'] = b'text/plain'
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
224 res.setbodybytes(meta['message'] + b'\n')
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
225 return
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
226 else:
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
227 raise error.ProgrammingError(
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
228 'unhandled action from frame processor: %s' % action)
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
229
37056
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
230 action, meta = reactor.oninputeof()
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
231 if action == 'sendframes':
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
232 # We assume we haven't started sending the response yet. If we're
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
233 # wrong, the response type will raise an exception.
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
234 res.status = b'200 OK'
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
235 res.headers[b'Content-Type'] = FRAMINGTYPE
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
236 res.setbodygen(meta['framegen'])
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
237 elif action == 'noop':
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
238 pass
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
239 else:
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
240 raise error.ProgrammingError('unhandled action from frame processor: %s'
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
241 % action)
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
242
37054
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
243 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
244 outstream, command, issubsequent):
37054
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
245 """Dispatch a wire protocol command made from HTTPv2 requests.
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
246
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
247 The authenticated permission (``authedperm``) along with the original
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
248 command from the URL (``reqcommand``) are passed in.
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
249 """
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
250 # We already validated that the session has permissions to perform the
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
251 # actions in ``authedperm``. In the unified frame protocol, the canonical
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
252 # command to run is expressed in a frame. However, the URL also requested
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
253 # to run a specific command. We need to be careful that the command we
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
254 # run doesn't have permissions requirements greater than what was granted
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
255 # by ``authedperm``.
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
256 #
37059
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
257 # Our rule for this is we only allow one command per HTTP request and
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
258 # that command must match the command in the URL. However, we make
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
259 # an exception for the ``multirequest`` URL. This URL is allowed to
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
260 # execute multiple commands. We double check permissions of each command
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
261 # as it is invoked to ensure there is no privilege escalation.
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
262 # TODO consider allowing multiple commands to regular command URLs
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
263 # iff each command is the same.
37054
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
264
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
265 proto = httpv2protocolhandler(req, ui, args=command['args'])
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
266
37059
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
267 if reqcommand == b'multirequest':
37784
ee0d5e9d77b2 wireproto: move version 2 commands dict to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37783
diff changeset
268 if not COMMANDS.commandavailable(command['command'], proto):
37059
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
269 # TODO proper error mechanism
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
270 res.status = b'200 OK'
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
271 res.headers[b'Content-Type'] = b'text/plain'
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
272 res.setbodybytes(_('wire protocol command not available: %s') %
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
273 command['command'])
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
274 return True
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
275
37129
aaabd709df72 wireproto: review fixups
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37120
diff changeset
276 # TODO don't use assert here, since it may be elided by -O.
37059
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
277 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
278 wirecommand = COMMANDS[command['command']]
37059
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
279 assert wirecommand.permission in ('push', 'pull')
37054
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
280
37059
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
281 if authedperm == b'ro' and wirecommand.permission != 'pull':
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
282 # TODO proper error mechanism
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
283 res.status = b'403 Forbidden'
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
284 res.headers[b'Content-Type'] = b'text/plain'
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
285 res.setbodybytes(_('insufficient permissions to execute '
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
286 'command: %s') % command['command'])
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
287 return True
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
288
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
289 # TODO should we also call checkperm() here? Maybe not if we're going
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
290 # to overhaul that API. The granted scope from the URL check should
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
291 # be good enough.
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
292
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
293 else:
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
294 # Don't allow multiple commands outside of ``multirequest`` URL.
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
295 if issubsequent:
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
296 # TODO proper error mechanism
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
297 res.status = b'200 OK'
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
298 res.headers[b'Content-Type'] = b'text/plain'
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
299 res.setbodybytes(_('multiple commands cannot be issued to this '
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
300 'URL'))
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
301 return True
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
302
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
303 if reqcommand != command['command']:
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
304 # TODO define proper error mechanism
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
305 res.status = b'200 OK'
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
306 res.headers[b'Content-Type'] = b'text/plain'
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
307 res.setbodybytes(_('command in frame must match command in URL'))
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
308 return True
37054
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
309
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
310 res.status = b'200 OK'
37055
61393f888dfe wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
311 res.headers[b'Content-Type'] = FRAMINGTYPE
37054
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
312
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39448
diff changeset
313 try:
40025
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40023
diff changeset
314 objs = dispatch(repo, proto, command['command'], command['redirect'])
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39448
diff changeset
315
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39448
diff changeset
316 action, meta = reactor.oncommandresponsereadyobjects(
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39448
diff changeset
317 outstream, command['requestid'], objs)
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39448
diff changeset
318
39810
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
319 except error.WireprotoCommandError as e:
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
320 action, meta = reactor.oncommanderror(
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
321 outstream, command['requestid'], e.message, e.messageargs)
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
322
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39448
diff changeset
323 except Exception as e:
37726
0c184ca594bb wireprotov2: change behavior of error frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37725
diff changeset
324 action, meta = reactor.onservererror(
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39448
diff changeset
325 outstream, command['requestid'],
39837
69b4a5b89dc5 py3: cast exception to bytes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39828
diff changeset
326 _('exception when invoking command: %s') %
69b4a5b89dc5 py3: cast exception to bytes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39828
diff changeset
327 stringutil.forcebytestr(e))
37055
61393f888dfe wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
328
61393f888dfe wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
329 if action == 'sendframes':
61393f888dfe wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
330 res.setbodygen(meta['framegen'])
37059
bbea991635d0 wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
331 return True
37056
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
332 elif action == 'noop':
37129
aaabd709df72 wireproto: review fixups
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37120
diff changeset
333 return False
37055
61393f888dfe wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
334 else:
61393f888dfe wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
335 raise error.ProgrammingError('unhandled event from reactor: %s' %
61393f888dfe wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37054
diff changeset
336 action)
37054
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
337
37782
99accae4cc59 wireproto: reimplement dispatch() for version 2 server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37781
diff changeset
338 def getdispatchrepo(repo, proto, command):
99accae4cc59 wireproto: reimplement dispatch() for version 2 server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37781
diff changeset
339 return repo.filtered('served')
99accae4cc59 wireproto: reimplement dispatch() for version 2 server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37781
diff changeset
340
40025
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40023
diff changeset
341 def dispatch(repo, proto, command, redirect):
40021
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
342 """Run a wire protocol command.
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
343
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
344 Returns an iterable of objects that will be sent to the client.
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
345 """
37782
99accae4cc59 wireproto: reimplement dispatch() for version 2 server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37781
diff changeset
346 repo = getdispatchrepo(repo, proto, command)
99accae4cc59 wireproto: reimplement dispatch() for version 2 server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37781
diff changeset
347
40021
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
348 entry = COMMANDS[command]
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
349 func = entry.func
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
350 spec = entry.args
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
351
37782
99accae4cc59 wireproto: reimplement dispatch() for version 2 server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37781
diff changeset
352 args = proto.getargs(spec)
99accae4cc59 wireproto: reimplement dispatch() for version 2 server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37781
diff changeset
353
40021
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
354 # There is some duplicate boilerplate code here for calling the command and
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
355 # emitting objects. It is either that or a lot of indented code that looks
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
356 # like a pyramid (since there are a lot of code paths that result in not
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
357 # using the cacher).
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
358 callcommand = lambda: func(repo, proto, **pycompat.strkwargs(args))
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
359
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
360 # Request is not cacheable. Don't bother instantiating a cacher.
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
361 if not entry.cachekeyfn:
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
362 for o in callcommand():
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
363 yield o
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
364 return
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
365
40025
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40023
diff changeset
366 if redirect:
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40023
diff changeset
367 redirecttargets = redirect[b'targets']
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40023
diff changeset
368 redirecthashes = redirect[b'hashes']
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40023
diff changeset
369 else:
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40023
diff changeset
370 redirecttargets = []
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40023
diff changeset
371 redirecthashes = []
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40023
diff changeset
372
40021
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
373 cacher = makeresponsecacher(repo, proto, command, args,
40025
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40023
diff changeset
374 cborutil.streamencode,
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40023
diff changeset
375 redirecttargets=redirecttargets,
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40023
diff changeset
376 redirecthashes=redirecthashes)
40021
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
377
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
378 # But we have no cacher. Do default handling.
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
379 if not cacher:
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
380 for o in callcommand():
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
381 yield o
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
382 return
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
383
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
384 with cacher:
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
385 cachekey = entry.cachekeyfn(repo, proto, cacher, **args)
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
386
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
387 # No cache key or the cacher doesn't like it. Do default handling.
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
388 if cachekey is None or not cacher.setcachekey(cachekey):
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
389 for o in callcommand():
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
390 yield o
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
391 return
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
392
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
393 # Serve it from the cache, if possible.
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
394 cached = cacher.lookup()
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
395
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
396 if cached:
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
397 for o in cached['objs']:
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
398 yield o
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
399 return
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
400
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
401 # Else call the command and feed its output into the cacher, allowing
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
402 # the cacher to buffer/mutate objects as it desires.
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
403 for o in callcommand():
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
404 for o in cacher.onobject(o):
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
405 yield o
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
406
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
407 for o in cacher.onfinished():
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
408 yield o
37782
99accae4cc59 wireproto: reimplement dispatch() for version 2 server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37781
diff changeset
409
37810
856f381ad74b interfaceutil: module to stub out zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37784
diff changeset
410 @interfaceutil.implementer(wireprototypes.baseprotocolhandler)
37296
78103e4138b1 wireproto: port protocol handler to zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37295
diff changeset
411 class httpv2protocolhandler(object):
37054
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
412 def __init__(self, req, ui, args=None):
37047
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
413 self._req = req
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
414 self._ui = ui
37054
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
415 self._args = args
37047
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
416
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
417 @property
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
418 def name(self):
37644
77c9ee77687c wireproto: rename HTTPV2 so it less like HTTP/2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37557
diff changeset
419 return HTTP_WIREPROTO_V2
37047
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
420
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
421 def getargs(self, args):
39810
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
422 # First look for args that were passed but aren't registered on this
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
423 # command.
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
424 extra = set(self._args) - set(args)
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
425 if extra:
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
426 raise error.WireprotoCommandError(
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
427 'unsupported argument to command: %s' %
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
428 ', '.join(sorted(extra)))
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
429
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
430 # And look for required arguments that are missing.
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
431 missing = {a for a in args if args[a]['required']} - set(self._args)
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
432
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
433 if missing:
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
434 raise error.WireprotoCommandError(
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
435 'missing required arguments: %s' % ', '.join(sorted(missing)))
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
436
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
437 # Now derive the arguments to pass to the command, taking into
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
438 # account the arguments specified by the client.
37054
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
439 data = {}
39810
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
440 for k, meta in sorted(args.items()):
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
441 # This argument wasn't passed by the client.
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
442 if k not in self._args:
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
443 data[k] = meta['default']()
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
444 continue
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
445
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
446 v = self._args[k]
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
447
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
448 # Sets may be expressed as lists. Silently normalize.
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
449 if meta['type'] == 'set' and isinstance(v, list):
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
450 v = set(v)
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
451
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
452 # TODO consider more/stronger type validation.
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
453
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
454 data[k] = v
37054
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
455
37485
0b7475ea38cf wireproto: port heads command to wire protocol v2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37414
diff changeset
456 return data
37047
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
457
37393
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37296
diff changeset
458 def getprotocaps(self):
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37296
diff changeset
459 # 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
460 return set()
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37296
diff changeset
461
37414
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37393
diff changeset
462 def getpayload(self):
37047
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
463 raise NotImplementedError
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
464
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
465 @contextlib.contextmanager
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
466 def mayberedirectstdio(self):
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
467 raise NotImplementedError
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
468
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
469 def client(self):
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
470 raise NotImplementedError
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
471
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
472 def addcapabilities(self, repo, caps):
37054
e7a012b60d6e wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37053
diff changeset
473 return caps
37047
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
474
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
475 def checkperm(self, perm):
fddcb51b5084 wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
476 raise NotImplementedError
37546
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
477
37557
734515aca84d wireproto: define and implement HTTP handshake to upgrade protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
478 def httpv2apidescriptor(req, repo):
734515aca84d wireproto: define and implement HTTP handshake to upgrade protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
479 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
480
734515aca84d wireproto: define and implement HTTP handshake to upgrade protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
481 return _capabilitiesv2(repo, proto)
734515aca84d wireproto: define and implement HTTP handshake to upgrade protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
482
37546
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
483 def _capabilitiesv2(repo, proto):
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
484 """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
485
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
486 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
487 transports.
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
488 """
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
489 compression = []
37783
9d818539abfa wireproto: move supportedcompengines out of wireproto
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37782
diff changeset
490 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
491 compression.append({
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
492 b'name': engine.wireprotosupport().name,
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
493 })
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
494
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
495 caps = {
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
496 'commands': {},
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
497 'compression': compression,
37653
b2fa1591fb44 wireproto: add media type to version 2 capabilities response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37644
diff changeset
498 'framingmediatypes': [FRAMINGTYPE],
39811
ae20f52437e9 wireprotov2: advertise recognized path filter prefixes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39810
diff changeset
499 'pathfilterprefixes': set(narrowspec.VALID_PREFIXES),
37546
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
500 }
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
501
37784
ee0d5e9d77b2 wireproto: move version 2 commands dict to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37783
diff changeset
502 for command, entry in COMMANDS.items():
39812
8e7e822e85ec wireprotov2: expose rich arguments metadata
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39811
diff changeset
503 args = {}
8e7e822e85ec wireprotov2: expose rich arguments metadata
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39811
diff changeset
504
8e7e822e85ec wireprotov2: expose rich arguments metadata
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39811
diff changeset
505 for arg, meta in entry.args.items():
8e7e822e85ec wireprotov2: expose rich arguments metadata
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39811
diff changeset
506 args[arg] = {
8e7e822e85ec wireprotov2: expose rich arguments metadata
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39811
diff changeset
507 # TODO should this be a normalized type using CBOR's
8e7e822e85ec wireprotov2: expose rich arguments metadata
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39811
diff changeset
508 # terminology?
8e7e822e85ec wireprotov2: expose rich arguments metadata
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39811
diff changeset
509 b'type': meta['type'],
8e7e822e85ec wireprotov2: expose rich arguments metadata
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39811
diff changeset
510 b'required': meta['required'],
8e7e822e85ec wireprotov2: expose rich arguments metadata
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39811
diff changeset
511 }
8e7e822e85ec wireprotov2: expose rich arguments metadata
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39811
diff changeset
512
8e7e822e85ec wireprotov2: expose rich arguments metadata
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39811
diff changeset
513 if not meta['required']:
8e7e822e85ec wireprotov2: expose rich arguments metadata
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39811
diff changeset
514 args[arg][b'default'] = meta['default']()
39810
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
515
39813
c30faea8d02d wireprotov2: advertise set of valid values for requestable fields
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39812
diff changeset
516 if meta['validvalues']:
c30faea8d02d wireprotov2: advertise set of valid values for requestable fields
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39812
diff changeset
517 args[arg][b'validvalues'] = meta['validvalues']
c30faea8d02d wireprotov2: advertise set of valid values for requestable fields
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39812
diff changeset
518
37546
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
519 caps['commands'][command] = {
39810
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
520 'args': args,
37546
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
521 'permissions': [entry.permission],
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
40049
39074a35f7db wireprotov2: always advertise raw repo requirements
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40025
diff changeset
524 caps['rawrepoformats'] = sorted(repo.requirements &
39074a35f7db wireprotov2: always advertise raw repo requirements
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40025
diff changeset
525 repo.supportedformats)
37657
23c4ddda7bbe wireproto: expose repository formats via capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37653
diff changeset
526
40023
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
527 targets = getadvertisedredirecttargets(repo, proto)
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
528 if targets:
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
529 caps[b'redirect'] = {
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
530 b'targets': [],
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
531 b'hashes': [b'sha256', b'sha1'],
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
532 }
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
533
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
534 for target in targets:
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
535 entry = {
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
536 b'name': target['name'],
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
537 b'protocol': target['protocol'],
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
538 b'uris': target['uris'],
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
539 }
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
540
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
541 for key in ('snirequired', 'tlsversions'):
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
542 if key in target:
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
543 entry[key] = target[key]
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
544
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
545 caps[b'redirect'][b'targets'].append(entry)
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
546
37546
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
547 return proto.addcapabilities(repo, caps)
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
548
40023
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
549 def getadvertisedredirecttargets(repo, proto):
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
550 """Obtain a list of content redirect targets.
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
551
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
552 Returns a list containing potential redirect targets that will be
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
553 advertised in capabilities data. Each dict MUST have the following
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
554 keys:
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
555
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
556 name
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
557 The name of this redirect target. This is the identifier clients use
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
558 to refer to a target. It is transferred as part of every command
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
559 request.
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
560
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
561 protocol
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
562 Network protocol used by this target. Typically this is the string
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
563 in front of the ``://`` in a URL. e.g. ``https``.
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
564
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
565 uris
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
566 List of representative URIs for this target. Clients can use the
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
567 URIs to test parsing for compatibility or for ordering preference
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
568 for which target to use.
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
569
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
570 The following optional keys are recognized:
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
571
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
572 snirequired
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
573 Bool indicating if Server Name Indication (SNI) is required to
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
574 connect to this target.
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
575
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
576 tlsversions
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
577 List of bytes indicating which TLS versions are supported by this
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
578 target.
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
579
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
580 By default, clients reflect the target order advertised by servers
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
581 and servers will use the first client-advertised target when picking
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
582 a redirect target. So targets should be advertised in the order the
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
583 server prefers they be used.
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
584 """
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
585 return []
10cf8b116dd8 wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40021
diff changeset
586
40021
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
587 def wireprotocommand(name, args=None, permission='push', cachekeyfn=None):
37780
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
588 """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
589
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
590 ``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
591
39810
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
592 ``args`` is a dict defining arguments accepted by the command. Keys are
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
593 the argument name. Values are dicts with the following keys:
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
594
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
595 ``type``
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
596 The argument data type. Must be one of the following string
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
597 literals: ``bytes``, ``int``, ``list``, ``dict``, ``set``,
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
598 or ``bool``.
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
599
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
600 ``default``
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
601 A callable returning the default value for this argument. If not
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
602 specified, ``None`` will be the default value.
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
603
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
604 ``example``
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
605 An example value for this argument.
37780
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
606
39813
c30faea8d02d wireprotov2: advertise set of valid values for requestable fields
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39812
diff changeset
607 ``validvalues``
c30faea8d02d wireprotov2: advertise set of valid values for requestable fields
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39812
diff changeset
608 Set of recognized values for this argument.
c30faea8d02d wireprotov2: advertise set of valid values for requestable fields
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39812
diff changeset
609
37780
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
610 ``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
611 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
612 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
613 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
614 a repository that is supposed to be read-only.
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39448
diff changeset
615
40021
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
616 ``cachekeyfn`` defines an optional callable that can derive the
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
617 cache key for this request.
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
618
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39448
diff changeset
619 Wire protocol commands are generators of objects to be serialized and
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39448
diff changeset
620 sent to the client.
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39448
diff changeset
621
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39448
diff changeset
622 If a command raises an uncaught exception, this will be translated into
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39448
diff changeset
623 a command error.
40021
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
624
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
625 All commands can opt in to being cacheable by defining a function
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
626 (``cachekeyfn``) that is called to derive a cache key. This function
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
627 receives the same arguments as the command itself plus a ``cacher``
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
628 argument containing the active cacher for the request and returns a bytes
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
629 containing the key in a cache the response to this command may be cached
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
630 under.
37780
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
631 """
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
632 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
633 if v['version'] == 2}
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
634
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
635 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
636 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
637 '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
638 permission)
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
639
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
640 if args is None:
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
641 args = {}
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
642
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
643 if not isinstance(args, dict):
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
644 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
645 'must be declared as dicts')
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
646
39810
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
647 for arg, meta in args.items():
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
648 if arg == '*':
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
649 raise error.ProgrammingError('* argument name not allowed on '
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
650 'version 2 commands')
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
651
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
652 if not isinstance(meta, dict):
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
653 raise error.ProgrammingError('arguments for version 2 commands '
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
654 'must declare metadata as a dict')
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
655
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
656 if 'type' not in meta:
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
657 raise error.ProgrammingError('%s argument for command %s does not '
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
658 'declare type field' % (arg, name))
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
659
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
660 if meta['type'] not in ('bytes', 'int', 'list', 'dict', 'set', 'bool'):
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
661 raise error.ProgrammingError('%s argument for command %s has '
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
662 'illegal type: %s' % (arg, name,
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
663 meta['type']))
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
664
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
665 if 'example' not in meta:
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
666 raise error.ProgrammingError('%s argument for command %s does not '
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
667 'declare example field' % (arg, name))
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
668
39995
582676acaf6d wireprotov2: derive "required" from presence of default value
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39864
diff changeset
669 meta['required'] = 'default' not in meta
39810
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
670
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
671 meta.setdefault('default', lambda: None)
39813
c30faea8d02d wireprotov2: advertise set of valid values for requestable fields
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39812
diff changeset
672 meta.setdefault('validvalues', None)
39810
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
673
37546
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
674 def register(func):
37784
ee0d5e9d77b2 wireproto: move version 2 commands dict to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37783
diff changeset
675 if name in COMMANDS:
37780
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
676 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
677 'for version 2' % name)
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
678
37784
ee0d5e9d77b2 wireproto: move version 2 commands dict to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37783
diff changeset
679 COMMANDS[name] = wireprototypes.commandentry(
40021
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
680 func, args=args, transports=transports, permission=permission,
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
681 cachekeyfn=cachekeyfn)
37780
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
682
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
683 return func
37546
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
684
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
685 return register
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
686
40021
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
687 def makecommandcachekeyfn(command, localversion=None, allargs=False):
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
688 """Construct a cache key derivation function with common features.
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
689
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
690 By default, the cache key is a hash of:
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
691
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
692 * The command name.
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
693 * A global cache version number.
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
694 * A local cache version number (passed via ``localversion``).
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
695 * All the arguments passed to the command.
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
696 * The media type used.
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
697 * Wire protocol version string.
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
698 * The repository path.
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
699 """
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
700 if not allargs:
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
701 raise error.ProgrammingError('only allargs=True is currently supported')
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
702
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
703 if localversion is None:
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
704 raise error.ProgrammingError('must set localversion argument value')
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
705
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
706 def cachekeyfn(repo, proto, cacher, **args):
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
707 spec = COMMANDS[command]
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
708
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
709 # Commands that mutate the repo can not be cached.
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
710 if spec.permission == 'push':
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
711 return None
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
712
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
713 # TODO config option to disable caching.
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
714
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
715 # Our key derivation strategy is to construct a data structure
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
716 # holding everything that could influence cacheability and to hash
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
717 # the CBOR representation of that. Using CBOR seems like it might
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
718 # be overkill. However, simpler hashing mechanisms are prone to
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
719 # duplicate input issues. e.g. if you just concatenate two values,
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
720 # "foo"+"bar" is identical to "fo"+"obar". Using CBOR provides
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
721 # "padding" between values and prevents these problems.
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
722
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
723 # Seed the hash with various data.
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
724 state = {
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
725 # To invalidate all cache keys.
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
726 b'globalversion': GLOBAL_CACHE_VERSION,
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
727 # More granular cache key invalidation.
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
728 b'localversion': localversion,
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
729 # Cache keys are segmented by command.
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
730 b'command': pycompat.sysbytes(command),
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
731 # Throw in the media type and API version strings so changes
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
732 # to exchange semantics invalid cache.
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
733 b'mediatype': FRAMINGTYPE,
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
734 b'version': HTTP_WIREPROTO_V2,
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
735 # So same requests for different repos don't share cache keys.
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
736 b'repo': repo.root,
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
737 }
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
738
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
739 # The arguments passed to us will have already been normalized.
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
740 # Default values will be set, etc. This is important because it
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
741 # means that it doesn't matter if clients send an explicit argument
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
742 # or rely on the default value: it will all normalize to the same
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
743 # set of arguments on the server and therefore the same cache key.
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
744 #
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
745 # Arguments by their very nature must support being encoded to CBOR.
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
746 # And the CBOR encoder is deterministic. So we hash the arguments
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
747 # by feeding the CBOR of their representation into the hasher.
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
748 if allargs:
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
749 state[b'args'] = pycompat.byteskwargs(args)
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
750
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
751 cacher.adjustcachekeystate(state)
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
752
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
753 hasher = hashlib.sha1()
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
754 for chunk in cborutil.streamencode(state):
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
755 hasher.update(chunk)
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
756
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
757 return pycompat.sysbytes(hasher.hexdigest())
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
758
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
759 return cachekeyfn
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
760
40025
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40023
diff changeset
761 def makeresponsecacher(repo, proto, command, args, objencoderfn,
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40023
diff changeset
762 redirecttargets, redirecthashes):
40021
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
763 """Construct a cacher for a cacheable command.
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
764
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
765 Returns an ``iwireprotocolcommandcacher`` instance.
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
766
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
767 Extensions can monkeypatch this function to provide custom caching
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
768 backends.
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
769 """
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
770 return None
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
771
37546
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
772 @wireprotocommand('branchmap', permission='pull')
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
773 def branchmapv2(repo, proto):
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39448
diff changeset
774 yield {encoding.fromlocal(k): v
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39448
diff changeset
775 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
776
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
777 @wireprotocommand('capabilities', permission='pull')
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
778 def capabilitiesv2(repo, proto):
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39448
diff changeset
779 yield _capabilitiesv2(repo, proto)
37546
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
780
39810
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
781 @wireprotocommand(
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
782 'changesetdata',
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
783 args={
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
784 'noderange': {
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
785 'type': 'list',
39995
582676acaf6d wireprotov2: derive "required" from presence of default value
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39864
diff changeset
786 'default': lambda: None,
39810
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
787 'example': [[b'0123456...'], [b'abcdef...']],
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
788 },
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
789 'nodes': {
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
790 'type': 'list',
39995
582676acaf6d wireprotov2: derive "required" from presence of default value
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39864
diff changeset
791 'default': lambda: None,
39810
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
792 'example': [b'0123456...'],
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
793 },
39815
d3d333ab167a wireprotov2: teach changesetdata to fetch ancestors until depth
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39814
diff changeset
794 'nodesdepth': {
d3d333ab167a wireprotov2: teach changesetdata to fetch ancestors until depth
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39814
diff changeset
795 'type': 'int',
39995
582676acaf6d wireprotov2: derive "required" from presence of default value
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39864
diff changeset
796 'default': lambda: None,
39815
d3d333ab167a wireprotov2: teach changesetdata to fetch ancestors until depth
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39814
diff changeset
797 'example': 10,
d3d333ab167a wireprotov2: teach changesetdata to fetch ancestors until depth
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39814
diff changeset
798 },
39810
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
799 'fields': {
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
800 'type': 'set',
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
801 'default': set,
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
802 'example': {b'parents', b'revision'},
39813
c30faea8d02d wireprotov2: advertise set of valid values for requestable fields
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39812
diff changeset
803 'validvalues': {b'bookmarks', b'parents', b'phase', b'revision'},
39810
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
804 },
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
805 },
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
806 permission='pull')
39815
d3d333ab167a wireprotov2: teach changesetdata to fetch ancestors until depth
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39814
diff changeset
807 def changesetdata(repo, proto, noderange, nodes, nodesdepth, fields):
39636
399ddd3227a4 wireprotov2: add TODOs around extending changesetdata fields
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39634
diff changeset
808 # TODO look for unknown fields and abort when they can't be serviced.
39813
c30faea8d02d wireprotov2: advertise set of valid values for requestable fields
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39812
diff changeset
809 # This could probably be validated by dispatcher using validvalues.
39636
399ddd3227a4 wireprotov2: add TODOs around extending changesetdata fields
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39634
diff changeset
810
39630
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
811 if noderange is None and nodes is None:
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
812 raise error.WireprotoCommandError(
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
813 'noderange or nodes must be defined')
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
814
39815
d3d333ab167a wireprotov2: teach changesetdata to fetch ancestors until depth
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39814
diff changeset
815 if nodesdepth is not None and nodes is None:
d3d333ab167a wireprotov2: teach changesetdata to fetch ancestors until depth
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39814
diff changeset
816 raise error.WireprotoCommandError(
d3d333ab167a wireprotov2: teach changesetdata to fetch ancestors until depth
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39814
diff changeset
817 'nodesdepth requires the nodes argument')
d3d333ab167a wireprotov2: teach changesetdata to fetch ancestors until depth
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39814
diff changeset
818
39630
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
819 if noderange is not None:
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
820 if len(noderange) != 2:
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
821 raise error.WireprotoCommandError(
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
822 'noderange must consist of 2 elements')
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
823
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
824 if not noderange[1]:
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
825 raise error.WireprotoCommandError(
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
826 'heads in noderange request cannot be empty')
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
827
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
828 cl = repo.changelog
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
829 hasnode = cl.hasnode
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
830
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
831 seen = set()
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
832 outgoing = []
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
833
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
834 if nodes is not None:
39815
d3d333ab167a wireprotov2: teach changesetdata to fetch ancestors until depth
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39814
diff changeset
835 outgoing = [n for n in nodes if hasnode(n)]
d3d333ab167a wireprotov2: teach changesetdata to fetch ancestors until depth
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39814
diff changeset
836
d3d333ab167a wireprotov2: teach changesetdata to fetch ancestors until depth
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39814
diff changeset
837 if nodesdepth:
d3d333ab167a wireprotov2: teach changesetdata to fetch ancestors until depth
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39814
diff changeset
838 outgoing = [cl.node(r) for r in
d3d333ab167a wireprotov2: teach changesetdata to fetch ancestors until depth
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39814
diff changeset
839 repo.revs(b'ancestors(%ln, %d)', outgoing,
d3d333ab167a wireprotov2: teach changesetdata to fetch ancestors until depth
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39814
diff changeset
840 nodesdepth - 1)]
d3d333ab167a wireprotov2: teach changesetdata to fetch ancestors until depth
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39814
diff changeset
841
39630
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
842 seen |= set(outgoing)
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
843
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
844 if noderange is not None:
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
845 if noderange[0]:
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
846 common = [n for n in noderange[0] if hasnode(n)]
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
847 else:
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
848 common = [nullid]
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
849
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
850 for n in discovery.outgoing(repo, common, noderange[1]).missing:
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
851 if n not in seen:
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
852 outgoing.append(n)
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
853 # Don't need to add to seen here because this is the final
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
854 # source of nodes and there should be no duplicates in this
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
855 # list.
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
856
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
857 seen.clear()
39632
c1aacb0d76ff wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39630
diff changeset
858 publishing = repo.publishing()
39630
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
859
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
860 if outgoing:
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
861 repo.hook('preoutgoing', throw=True, source='serve')
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
862
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
863 yield {
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
864 b'totalitems': len(outgoing),
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
865 }
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
866
39632
c1aacb0d76ff wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39630
diff changeset
867 # The phases of nodes already transferred to the client may have changed
c1aacb0d76ff wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39630
diff changeset
868 # since the client last requested data. We send phase-only records
c1aacb0d76ff wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39630
diff changeset
869 # for these revisions, if requested.
c1aacb0d76ff wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39630
diff changeset
870 if b'phase' in fields and noderange is not None:
c1aacb0d76ff wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39630
diff changeset
871 # TODO skip nodes whose phase will be reflected by a node in the
c1aacb0d76ff wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39630
diff changeset
872 # outgoing set. This is purely an optimization to reduce data
c1aacb0d76ff wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39630
diff changeset
873 # size.
c1aacb0d76ff wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39630
diff changeset
874 for node in noderange[0]:
c1aacb0d76ff wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39630
diff changeset
875 yield {
c1aacb0d76ff wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39630
diff changeset
876 b'node': node,
c1aacb0d76ff wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39630
diff changeset
877 b'phase': b'public' if publishing else repo[node].phasestr()
c1aacb0d76ff wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39630
diff changeset
878 }
c1aacb0d76ff wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39630
diff changeset
879
39634
9dffa99f9158 wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39632
diff changeset
880 nodebookmarks = {}
9dffa99f9158 wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39632
diff changeset
881 for mark, node in repo._bookmarks.items():
9dffa99f9158 wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39632
diff changeset
882 nodebookmarks.setdefault(node, set()).add(mark)
9dffa99f9158 wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39632
diff changeset
883
39630
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
884 # It is already topologically sorted by revision number.
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
885 for node in outgoing:
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
886 d = {
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
887 b'node': node,
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
888 }
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
889
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
890 if b'parents' in fields:
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
891 d[b'parents'] = cl.parents(node)
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
892
39632
c1aacb0d76ff wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39630
diff changeset
893 if b'phase' in fields:
c1aacb0d76ff wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39630
diff changeset
894 if publishing:
c1aacb0d76ff wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39630
diff changeset
895 d[b'phase'] = b'public'
c1aacb0d76ff wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39630
diff changeset
896 else:
c1aacb0d76ff wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39630
diff changeset
897 ctx = repo[node]
c1aacb0d76ff wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39630
diff changeset
898 d[b'phase'] = ctx.phasestr()
c1aacb0d76ff wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39630
diff changeset
899
39634
9dffa99f9158 wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39632
diff changeset
900 if b'bookmarks' in fields and node in nodebookmarks:
9dffa99f9158 wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39632
diff changeset
901 d[b'bookmarks'] = sorted(nodebookmarks[node])
9dffa99f9158 wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39632
diff changeset
902 del nodebookmarks[node]
9dffa99f9158 wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39632
diff changeset
903
39814
d059cb669632 wireprotov2: allow multiple fields to follow revision maps
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39813
diff changeset
904 followingmeta = []
d059cb669632 wireprotov2: allow multiple fields to follow revision maps
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39813
diff changeset
905 followingdata = []
39630
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
906
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
907 if b'revision' in fields:
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
908 revisiondata = cl.revision(node, raw=True)
39814
d059cb669632 wireprotov2: allow multiple fields to follow revision maps
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39813
diff changeset
909 followingmeta.append((b'revision', len(revisiondata)))
d059cb669632 wireprotov2: allow multiple fields to follow revision maps
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39813
diff changeset
910 followingdata.append(revisiondata)
39630
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
911
39636
399ddd3227a4 wireprotov2: add TODOs around extending changesetdata fields
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39634
diff changeset
912 # TODO make it possible for extensions to wrap a function or register
399ddd3227a4 wireprotov2: add TODOs around extending changesetdata fields
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39634
diff changeset
913 # a handler to service custom fields.
399ddd3227a4 wireprotov2: add TODOs around extending changesetdata fields
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39634
diff changeset
914
39814
d059cb669632 wireprotov2: allow multiple fields to follow revision maps
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39813
diff changeset
915 if followingmeta:
d059cb669632 wireprotov2: allow multiple fields to follow revision maps
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39813
diff changeset
916 d[b'fieldsfollowing'] = followingmeta
d059cb669632 wireprotov2: allow multiple fields to follow revision maps
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39813
diff changeset
917
39630
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
918 yield d
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
919
39814
d059cb669632 wireprotov2: allow multiple fields to follow revision maps
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39813
diff changeset
920 for extra in followingdata:
d059cb669632 wireprotov2: allow multiple fields to follow revision maps
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39813
diff changeset
921 yield extra
39630
9c2c77c73f23 wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
922
39634
9dffa99f9158 wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39632
diff changeset
923 # If requested, send bookmarks from nodes that didn't have revision
9dffa99f9158 wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39632
diff changeset
924 # data sent so receiver is aware of any bookmark updates.
9dffa99f9158 wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39632
diff changeset
925 if b'bookmarks' in fields:
9dffa99f9158 wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39632
diff changeset
926 for node, marks in sorted(nodebookmarks.iteritems()):
9dffa99f9158 wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39632
diff changeset
927 yield {
9dffa99f9158 wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39632
diff changeset
928 b'node': node,
9dffa99f9158 wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39632
diff changeset
929 b'bookmarks': sorted(marks),
9dffa99f9158 wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39632
diff changeset
930 }
9dffa99f9158 wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39632
diff changeset
931
39639
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
932 class FileAccessError(Exception):
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
933 """Represents an error accessing a specific file."""
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
934
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
935 def __init__(self, path, msg, args):
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
936 self.path = path
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
937 self.msg = msg
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
938 self.args = args
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
939
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
940 def getfilestore(repo, proto, path):
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
941 """Obtain a file storage object for use with wire protocol.
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
942
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
943 Exists as a standalone function so extensions can monkeypatch to add
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
944 access control.
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
945 """
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
946 # This seems to work even if the file doesn't exist. So catch
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
947 # "empty" files and return an error.
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
948 fl = repo.file(path)
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
949
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
950 if not len(fl):
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
951 raise FileAccessError(path, 'unknown file: %s', (path,))
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
952
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
953 return fl
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
954
39810
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
955 @wireprotocommand(
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
956 'filedata',
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
957 args={
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
958 'haveparents': {
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
959 'type': 'bool',
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
960 'default': lambda: False,
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
961 'example': True,
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
962 },
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
963 'nodes': {
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
964 'type': 'list',
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
965 'example': [b'0123456...'],
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
966 },
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
967 'fields': {
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
968 'type': 'set',
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
969 'default': set,
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
970 'example': {b'parents', b'revision'},
39813
c30faea8d02d wireprotov2: advertise set of valid values for requestable fields
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39812
diff changeset
971 'validvalues': {b'parents', b'revision'},
39810
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
972 },
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
973 'path': {
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
974 'type': 'bytes',
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
975 'example': b'foo.txt',
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
976 }
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
977 },
40021
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
978 permission='pull',
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
979 # TODO censoring a file revision won't invalidate the cache.
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
980 # Figure out a way to take censoring into account when deriving
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
981 # the cache key.
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
982 cachekeyfn=makecommandcachekeyfn('filedata', 1, allargs=True))
39810
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
983 def filedata(repo, proto, haveparents, nodes, fields, path):
39639
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
984 try:
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
985 # Extensions may wish to access the protocol handler.
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
986 store = getfilestore(repo, proto, path)
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
987 except FileAccessError as e:
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
988 raise error.WireprotoCommandError(e.msg, e.args)
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
989
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
990 # Validate requested nodes.
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
991 for node in nodes:
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
992 try:
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
993 store.rev(node)
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
994 except error.LookupError:
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
995 raise error.WireprotoCommandError('unknown file node: %s',
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
996 (hex(node),))
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
997
39864
7b752bf08435 wireprotov2server: port to emitrevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39837
diff changeset
998 revisions = store.emitrevisions(nodes,
7b752bf08435 wireprotov2server: port to emitrevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39837
diff changeset
999 revisiondata=b'revision' in fields,
7b752bf08435 wireprotov2server: port to emitrevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39837
diff changeset
1000 assumehaveparentrevisions=haveparents)
39639
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
1001
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
1002 yield {
39864
7b752bf08435 wireprotov2server: port to emitrevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39837
diff changeset
1003 b'totalitems': len(nodes),
39639
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
1004 }
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
1005
39864
7b752bf08435 wireprotov2server: port to emitrevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39837
diff changeset
1006 for revision in revisions:
39639
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
1007 d = {
39864
7b752bf08435 wireprotov2server: port to emitrevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39837
diff changeset
1008 b'node': revision.node,
39639
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
1009 }
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
1010
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
1011 if b'parents' in fields:
39864
7b752bf08435 wireprotov2server: port to emitrevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39837
diff changeset
1012 d[b'parents'] = [revision.p1node, revision.p2node]
39639
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
1013
39814
d059cb669632 wireprotov2: allow multiple fields to follow revision maps
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39813
diff changeset
1014 followingmeta = []
d059cb669632 wireprotov2: allow multiple fields to follow revision maps
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39813
diff changeset
1015 followingdata = []
d059cb669632 wireprotov2: allow multiple fields to follow revision maps
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39813
diff changeset
1016
39639
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
1017 if b'revision' in fields:
39864
7b752bf08435 wireprotov2server: port to emitrevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39837
diff changeset
1018 if revision.revision is not None:
7b752bf08435 wireprotov2server: port to emitrevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39837
diff changeset
1019 followingmeta.append((b'revision', len(revision.revision)))
7b752bf08435 wireprotov2server: port to emitrevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39837
diff changeset
1020 followingdata.append(revision.revision)
39639
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
1021 else:
39864
7b752bf08435 wireprotov2server: port to emitrevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39837
diff changeset
1022 d[b'deltabasenode'] = revision.basenode
7b752bf08435 wireprotov2server: port to emitrevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39837
diff changeset
1023 followingmeta.append((b'delta', len(revision.delta)))
7b752bf08435 wireprotov2server: port to emitrevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39837
diff changeset
1024 followingdata.append(revision.delta)
39814
d059cb669632 wireprotov2: allow multiple fields to follow revision maps
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39813
diff changeset
1025
d059cb669632 wireprotov2: allow multiple fields to follow revision maps
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39813
diff changeset
1026 if followingmeta:
d059cb669632 wireprotov2: allow multiple fields to follow revision maps
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39813
diff changeset
1027 d[b'fieldsfollowing'] = followingmeta
39639
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
1028
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
1029 yield d
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
1030
39814
d059cb669632 wireprotov2: allow multiple fields to follow revision maps
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39813
diff changeset
1031 for extra in followingdata:
d059cb669632 wireprotov2: allow multiple fields to follow revision maps
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39813
diff changeset
1032 yield extra
39639
0e03e6a44dee wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39637
diff changeset
1033
39810
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1034 @wireprotocommand(
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1035 'heads',
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1036 args={
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1037 'publiconly': {
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1038 'type': 'bool',
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1039 'default': lambda: False,
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1040 'example': False,
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1041 },
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1042 },
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1043 permission='pull')
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1044 def headsv2(repo, proto, publiconly):
37546
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
1045 if publiconly:
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
1046 repo = repo.filtered('immutable')
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
1047
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39448
diff changeset
1048 yield repo.heads()
37546
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
1049
39810
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1050 @wireprotocommand(
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1051 'known',
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1052 args={
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1053 'nodes': {
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1054 'type': 'list',
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1055 'default': list,
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1056 'example': [b'deadbeef'],
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1057 },
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1058 },
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1059 permission='pull')
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1060 def knownv2(repo, proto, nodes):
37546
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
1061 result = b''.join(b'1' if n else b'0' for n in repo.known(nodes))
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39448
diff changeset
1062 yield result
37546
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
1063
39810
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1064 @wireprotocommand(
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1065 'listkeys',
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1066 args={
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1067 'namespace': {
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1068 'type': 'bytes',
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1069 'example': b'ns',
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1070 },
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1071 },
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1072 permission='pull')
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1073 def listkeysv2(repo, proto, namespace):
37546
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
1074 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
1075 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
1076 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
1077
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39448
diff changeset
1078 yield keys
37546
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
1079
39810
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1080 @wireprotocommand(
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1081 'lookup',
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1082 args={
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1083 'key': {
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1084 'type': 'bytes',
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1085 'example': b'foo',
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1086 },
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1087 },
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1088 permission='pull')
37546
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
1089 def lookupv2(repo, proto, key):
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
1090 key = encoding.tolocal(key)
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
1091
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
1092 # TODO handle exception.
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
1093 node = repo.lookup(key)
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
1094
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39448
diff changeset
1095 yield node
37546
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
1096
39810
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1097 @wireprotocommand(
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1098 'manifestdata',
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1099 args={
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1100 'nodes': {
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1101 'type': 'list',
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1102 'example': [b'0123456...'],
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1103 },
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1104 'haveparents': {
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1105 'type': 'bool',
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1106 'default': lambda: False,
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1107 'example': True,
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1108 },
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1109 'fields': {
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1110 'type': 'set',
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1111 'default': set,
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1112 'example': {b'parents', b'revision'},
39813
c30faea8d02d wireprotov2: advertise set of valid values for requestable fields
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39812
diff changeset
1113 'validvalues': {b'parents', b'revision'},
39810
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1114 },
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1115 'tree': {
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1116 'type': 'bytes',
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1117 'example': b'',
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1118 },
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1119 },
40021
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
1120 permission='pull',
c537144fdbef wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39995
diff changeset
1121 cachekeyfn=makecommandcachekeyfn('manifestdata', 1, allargs=True))
39810
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1122 def manifestdata(repo, proto, haveparents, nodes, fields, tree):
39637
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39636
diff changeset
1123 store = repo.manifestlog.getstorage(tree)
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39636
diff changeset
1124
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39636
diff changeset
1125 # Validate the node is known and abort on unknown revisions.
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39636
diff changeset
1126 for node in nodes:
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39636
diff changeset
1127 try:
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39636
diff changeset
1128 store.rev(node)
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39636
diff changeset
1129 except error.LookupError:
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39636
diff changeset
1130 raise error.WireprotoCommandError(
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39636
diff changeset
1131 'unknown node: %s', (node,))
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39636
diff changeset
1132
39864
7b752bf08435 wireprotov2server: port to emitrevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39837
diff changeset
1133 revisions = store.emitrevisions(nodes,
7b752bf08435 wireprotov2server: port to emitrevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39837
diff changeset
1134 revisiondata=b'revision' in fields,
7b752bf08435 wireprotov2server: port to emitrevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39837
diff changeset
1135 assumehaveparentrevisions=haveparents)
39637
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39636
diff changeset
1136
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39636
diff changeset
1137 yield {
39864
7b752bf08435 wireprotov2server: port to emitrevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39837
diff changeset
1138 b'totalitems': len(nodes),
39637
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39636
diff changeset
1139 }
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39636
diff changeset
1140
39864
7b752bf08435 wireprotov2server: port to emitrevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39837
diff changeset
1141 for revision in revisions:
39637
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39636
diff changeset
1142 d = {
39864
7b752bf08435 wireprotov2server: port to emitrevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39837
diff changeset
1143 b'node': revision.node,
39637
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39636
diff changeset
1144 }
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39636
diff changeset
1145
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39636
diff changeset
1146 if b'parents' in fields:
39864
7b752bf08435 wireprotov2server: port to emitrevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39837
diff changeset
1147 d[b'parents'] = [revision.p1node, revision.p2node]
39637
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39636
diff changeset
1148
39814
d059cb669632 wireprotov2: allow multiple fields to follow revision maps
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39813
diff changeset
1149 followingmeta = []
d059cb669632 wireprotov2: allow multiple fields to follow revision maps
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39813
diff changeset
1150 followingdata = []
d059cb669632 wireprotov2: allow multiple fields to follow revision maps
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39813
diff changeset
1151
39637
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39636
diff changeset
1152 if b'revision' in fields:
39864
7b752bf08435 wireprotov2server: port to emitrevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39837
diff changeset
1153 if revision.revision is not None:
7b752bf08435 wireprotov2server: port to emitrevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39837
diff changeset
1154 followingmeta.append((b'revision', len(revision.revision)))
7b752bf08435 wireprotov2server: port to emitrevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39837
diff changeset
1155 followingdata.append(revision.revision)
39637
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39636
diff changeset
1156 else:
39864
7b752bf08435 wireprotov2server: port to emitrevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39837
diff changeset
1157 d[b'deltabasenode'] = revision.basenode
7b752bf08435 wireprotov2server: port to emitrevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39837
diff changeset
1158 followingmeta.append((b'delta', len(revision.delta)))
7b752bf08435 wireprotov2server: port to emitrevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39837
diff changeset
1159 followingdata.append(revision.delta)
39814
d059cb669632 wireprotov2: allow multiple fields to follow revision maps
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39813
diff changeset
1160
d059cb669632 wireprotov2: allow multiple fields to follow revision maps
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39813
diff changeset
1161 if followingmeta:
d059cb669632 wireprotov2: allow multiple fields to follow revision maps
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39813
diff changeset
1162 d[b'fieldsfollowing'] = followingmeta
39637
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39636
diff changeset
1163
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39636
diff changeset
1164 yield d
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39636
diff changeset
1165
39814
d059cb669632 wireprotov2: allow multiple fields to follow revision maps
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39813
diff changeset
1166 for extra in followingdata:
d059cb669632 wireprotov2: allow multiple fields to follow revision maps
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39813
diff changeset
1167 yield extra
39637
c7a7c7e844e5 wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39636
diff changeset
1168
39810
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1169 @wireprotocommand(
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1170 'pushkey',
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1171 args={
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1172 'namespace': {
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1173 'type': 'bytes',
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1174 'example': b'ns',
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1175 },
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1176 'key': {
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1177 'type': 'bytes',
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1178 'example': b'key',
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1179 },
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1180 'old': {
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1181 'type': 'bytes',
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1182 'example': b'old',
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1183 },
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1184 'new': {
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1185 'type': 'bytes',
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1186 'example': 'new',
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1187 },
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1188 },
0b61d21f05cc wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39641
diff changeset
1189 permission='push')
37546
3a2367e6c6f2 wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37545
diff changeset
1190 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
1191 # TODO handle ui output redirection
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39448
diff changeset
1192 yield repo.pushkey(encoding.tolocal(namespace),
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39448
diff changeset
1193 encoding.tolocal(key),
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39448
diff changeset
1194 encoding.tolocal(old),
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39448
diff changeset
1195 encoding.tolocal(new))