annotate mercurial/wireprotov2server.py @ 39657:aa7e312375cf

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