Mercurial > public > mercurial-scm > hg-stable
annotate mercurial/wireprotov2server.py @ 42824:2c4f656c8e9f
interfaceutil: move to interfaces/
Now that we have a dedicated folder for interfaces, let's move interfaceutil
there.
Differential Revision: https://phab.mercurial-scm.org/D6742
author | Pulkit Goyal <pulkit@yandex-team.ru> |
---|---|
date | Sun, 18 Aug 2019 02:28:42 +0300 |
parents | da643cadec90 |
children | 2372284d9457 |
rev | line source |
---|---|
5598
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
1 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net> |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
2 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com> |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
3 # |
8225
46293a0c7e9f
updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents:
8109
diff
changeset
|
4 # This software may be used and distributed according to the terms of the |
10263 | 5 # GNU General Public License version 2 or any later version. |
5598
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
6 |
27046
37fcfe52c68c
hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
20903
diff
changeset
|
7 from __future__ import absolute_import |
37fcfe52c68c
hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
20903
diff
changeset
|
8 |
40178
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
9 import collections |
36104
2ad145fbde54
wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36103
diff
changeset
|
10 import contextlib |
40022
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
11 import hashlib |
27046
37fcfe52c68c
hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
20903
diff
changeset
|
12 |
35899
1bf5263fe5cc
wireprotoserver: move sshserver into module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35898
diff
changeset
|
13 from .i18n import _ |
39646
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
14 from .node import ( |
39655
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
15 hex, |
39646
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
16 nullid, |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
17 ) |
35896
ef3a24a023ec
wireprotoserver: rename hgweb.protocol to wireprotoserver (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35750
diff
changeset
|
18 from . import ( |
39646
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
19 discovery, |
37546
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
20 encoding, |
34509
e21f274cccea
hgweb: in protocol adapter, avoid control reaching end of non-void function
Augie Fackler <augie@google.com>
parents:
33842
diff
changeset
|
21 error, |
40178
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
22 match as matchmod, |
39816
ae20f52437e9
wireprotov2: advertise recognized path filter prefixes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39815
diff
changeset
|
23 narrowspec, |
34742
5a9cad0dfddb
hgweb: when unpacking args from request form, convert to bytes
Augie Fackler <augie@google.com>
parents:
34740
diff
changeset
|
24 pycompat, |
40329
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
25 streamclone, |
41425
e82288a9556c
wireprotov2server: use our JSON encoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
41399
diff
changeset
|
26 templatefilters, |
40329
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
27 util, |
37055
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
28 wireprotoframing, |
36111
cd6ab329c5c7
wireprototypes: move wire protocol response types to new module
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36110
diff
changeset
|
29 wireprototypes, |
27046
37fcfe52c68c
hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
20903
diff
changeset
|
30 ) |
42824
2c4f656c8e9f
interfaceutil: move to interfaces/
Pulkit Goyal <pulkit@yandex-team.ru>
parents:
42790
diff
changeset
|
31 from .interfaces import ( |
2c4f656c8e9f
interfaceutil: move to interfaces/
Pulkit Goyal <pulkit@yandex-team.ru>
parents:
42790
diff
changeset
|
32 util as interfaceutil, |
2c4f656c8e9f
interfaceutil: move to interfaces/
Pulkit Goyal <pulkit@yandex-team.ru>
parents:
42790
diff
changeset
|
33 ) |
37810
856f381ad74b
interfaceutil: module to stub out zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37784
diff
changeset
|
34 from .utils import ( |
40022
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
35 cborutil, |
39842
69b4a5b89dc5
py3: cast exception to bytes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39833
diff
changeset
|
36 stringutil, |
37810
856f381ad74b
interfaceutil: module to stub out zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37784
diff
changeset
|
37 ) |
35896
ef3a24a023ec
wireprotoserver: rename hgweb.protocol to wireprotoserver (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35750
diff
changeset
|
38 |
40133
762ef19a07e3
wireprotov2: send protocol settings frame from client
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40130
diff
changeset
|
39 FRAMINGTYPE = b'application/mercurial-exp-framing-0006' |
11595
368cd5325348
protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents:
11594
diff
changeset
|
40 |
37644
77c9ee77687c
wireproto: rename HTTPV2 so it less like HTTP/2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37557
diff
changeset
|
41 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
|
42 |
37784
ee0d5e9d77b2
wireproto: move version 2 commands dict to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37783
diff
changeset
|
43 COMMANDS = wireprototypes.commanddict() |
ee0d5e9d77b2
wireproto: move version 2 commands dict to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37783
diff
changeset
|
44 |
40022
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
45 # Value inserted into cache key computation function. Change the value to |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
46 # force new cache keys for every command request. This should be done when |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
47 # there is a change to how caching works, etc. |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
48 GLOBAL_CACHE_VERSION = 1 |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
49 |
37545
93397c4633f6
wireproto: extract HTTP version 2 code to own module
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37535
diff
changeset
|
50 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
|
51 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
|
52 |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
53 # 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
|
54 # 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
|
55 |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
56 # 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
|
57 if not urlparts: |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
58 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
|
59 res.headers[b'Content-Type'] = b'text/plain' |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
60 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
|
61 return |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
62 |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
63 if len(urlparts) == 1: |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
64 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
|
65 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
|
66 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
|
67 req.dispatchpath) |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
68 return |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
69 |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
70 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
|
71 |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
72 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
|
73 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
|
74 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
|
75 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
|
76 return |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
77 |
37051
fc5e261915b9
wireproto: require POST for all HTTPv2 requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37050
diff
changeset
|
78 if req.method != 'POST': |
fc5e261915b9
wireproto: require POST for all HTTPv2 requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37050
diff
changeset
|
79 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
|
80 res.headers[b'Allow'] = b'POST' |
fc5e261915b9
wireproto: require POST for all HTTPv2 requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37050
diff
changeset
|
81 res.setbodybytes(_('commands require POST requests')) |
fc5e261915b9
wireproto: require POST for all HTTPv2 requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37050
diff
changeset
|
82 return |
fc5e261915b9
wireproto: require POST for all HTTPv2 requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37050
diff
changeset
|
83 |
37050
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
84 # 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
|
85 # 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
|
86 # 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
|
87 # 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
|
88 try: |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
89 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
|
90 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
|
91 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
|
92 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
|
93 res.headers[k] = v |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
94 res.setbodybytes('permission denied') |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
95 return |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
96 |
37055
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
97 # 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
|
98 if command == b'debugreflect': |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
99 _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
|
100 return |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
101 |
37062
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
102 # 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
|
103 # 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
|
104 # extension. |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
105 extracommands = {'multirequest'} |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
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 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
|
108 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
|
109 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
|
110 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
|
111 return |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
112 |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
113 repo = rctx.repo |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
114 ui = repo.ui |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
115 |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
116 proto = httpv2protocolhandler(req, ui) |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
117 |
37784
ee0d5e9d77b2
wireproto: move version 2 commands dict to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37783
diff
changeset
|
118 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
|
119 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
|
120 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
|
121 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
|
122 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
|
123 return |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
124 |
37132
aaabd709df72
wireproto: review fixups
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37123
diff
changeset
|
125 # 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
|
126 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
|
127 res.status = b'406 Not Acceptable' |
37d7a1d18b97
wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
128 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
|
129 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
|
130 % FRAMINGTYPE) |
37053
37d7a1d18b97
wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
131 return |
37d7a1d18b97
wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
132 |
37055
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
133 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
|
134 res.status = b'415 Unsupported Media Type' |
37d7a1d18b97
wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
135 # 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
|
136 # since client does Accept it. |
37d7a1d18b97
wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
137 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
|
138 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
|
139 'value: %s\n') % FRAMINGTYPE) |
37053
37d7a1d18b97
wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
140 return |
37d7a1d18b97
wireproto: define content negotiation for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
141 |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
142 _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
|
143 |
37055
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
144 def _processhttpv2reflectrequest(ui, repo, req, res): |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
145 """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
|
146 |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
147 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
|
148 |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
149 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
|
150 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
|
151 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
|
152 client. |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
153 """ |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
154 # 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
|
155 # 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
|
156 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
|
157 res.status = b'404 Not Found' |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
158 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
|
159 res.setbodybytes(_('debugreflect service not available')) |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
160 return |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
161 |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
162 # 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
|
163 |
40130
293835e0fff7
wireprotov2: pass ui into clientreactor and serverreactor
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40123
diff
changeset
|
164 reactor = wireprotoframing.serverreactor(ui) |
37055
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
165 states = [] |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
166 |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
167 while True: |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
168 frame = wireprotoframing.readframe(req.bodyfh) |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
169 |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
170 if not frame: |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
171 states.append(b'received: <no frame>') |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
172 break |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
173 |
37064
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37062
diff
changeset
|
174 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
|
175 frame.requestid, |
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37062
diff
changeset
|
176 frame.payload)) |
37055
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
177 |
37064
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37062
diff
changeset
|
178 action, meta = reactor.onframerecv(frame) |
41425
e82288a9556c
wireprotov2server: use our JSON encoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
41399
diff
changeset
|
179 states.append(templatefilters.json((action, meta))) |
37055
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
180 |
37059
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
181 action, meta = reactor.oninputeof() |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
182 meta['action'] = action |
41425
e82288a9556c
wireprotov2server: use our JSON encoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
41399
diff
changeset
|
183 states.append(templatefilters.json(meta)) |
37059
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
184 |
37055
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
185 res.status = b'200 OK' |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
186 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
|
187 res.setbodybytes(b'\n'.join(states)) |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37054
diff
changeset
|
188 |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
189 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
|
190 """Post-validation handler for HTTPv2 requests. |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
191 |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
192 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
|
193 frames for evaluation. |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
194 """ |
37059
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
195 # 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
|
196 # 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
|
197 # for that so we can opt into full duplex mode. |
40130
293835e0fff7
wireprotov2: pass ui into clientreactor and serverreactor
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40123
diff
changeset
|
198 reactor = wireprotoframing.serverreactor(ui, deferoutput=True) |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
199 seencommand = False |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
200 |
40138
b5bf3dd6ec5b
wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40133
diff
changeset
|
201 outstream = None |
37289
5fadc63ac99f
wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37288
diff
changeset
|
202 |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
203 while True: |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
204 frame = wireprotoframing.readframe(req.bodyfh) |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
205 if not frame: |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
206 break |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
207 |
37064
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37062
diff
changeset
|
208 action, meta = reactor.onframerecv(frame) |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
209 |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
210 if action == 'wantframe': |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
211 # 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
|
212 continue |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
213 elif action == 'runcommand': |
40138
b5bf3dd6ec5b
wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40133
diff
changeset
|
214 # Defer creating output stream because we need to wait for |
b5bf3dd6ec5b
wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40133
diff
changeset
|
215 # protocol settings frames so proper encoding can be applied. |
b5bf3dd6ec5b
wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40133
diff
changeset
|
216 if not outstream: |
b5bf3dd6ec5b
wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40133
diff
changeset
|
217 outstream = reactor.makeoutputstream() |
b5bf3dd6ec5b
wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40133
diff
changeset
|
218 |
37062
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
219 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
|
220 reqcommand, reactor, outstream, |
5fadc63ac99f
wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37288
diff
changeset
|
221 meta, issubsequent=seencommand) |
37062
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
222 |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
223 if sentoutput: |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
224 return |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
225 |
37062
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
226 seencommand = True |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
227 |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
228 elif action == 'error': |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
229 # TODO define proper error mechanism. |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
230 res.status = b'200 OK' |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
231 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
|
232 res.setbodybytes(meta['message'] + b'\n') |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
233 return |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
234 else: |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
235 raise error.ProgrammingError( |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
236 '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
|
237 |
37059
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
238 action, meta = reactor.oninputeof() |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
239 if action == 'sendframes': |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
240 # 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
|
241 # 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
|
242 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
|
243 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
|
244 res.setbodygen(meta['framegen']) |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
245 elif action == 'noop': |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
246 pass |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
247 else: |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
248 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
|
249 % action) |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
250 |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
251 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
|
252 outstream, command, issubsequent): |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
253 """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
|
254 |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
255 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
|
256 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
|
257 """ |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
258 # 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
|
259 # 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
|
260 # 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
|
261 # 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
|
262 # 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
|
263 # by ``authedperm``. |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
264 # |
37062
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
265 # 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
|
266 # 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
|
267 # 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
|
268 # 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
|
269 # 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
|
270 # 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
|
271 # 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
|
272 |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
273 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
|
274 |
37062
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
275 if reqcommand == b'multirequest': |
37784
ee0d5e9d77b2
wireproto: move version 2 commands dict to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37783
diff
changeset
|
276 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
|
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'200 OK' |
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(_('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
|
281 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 |
37132
aaabd709df72
wireproto: review fixups
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37123
diff
changeset
|
284 # 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
|
285 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
|
286 wirecommand = COMMANDS[command['command']] |
37062
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
287 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
|
288 |
37062
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
289 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
|
290 # TODO proper error mechanism |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
291 res.status = b'403 Forbidden' |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
292 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
|
293 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
|
294 'command: %s') % command['command']) |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
295 return True |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
296 |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
297 # 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
|
298 # 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
|
299 # be good enough. |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
300 |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
301 else: |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
302 # 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
|
303 if issubsequent: |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
304 # TODO proper error mechanism |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
305 res.status = b'200 OK' |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
306 res.headers[b'Content-Type'] = b'text/plain' |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
307 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
|
308 'URL')) |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
309 return True |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
310 |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
311 if reqcommand != command['command']: |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
312 # TODO define proper error mechanism |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
313 res.status = b'200 OK' |
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
314 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
|
315 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
|
316 return True |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
317 |
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
318 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
|
319 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
|
320 |
39575
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
321 try: |
40026
b099e6032f38
wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
322 objs = dispatch(repo, proto, command['command'], command['redirect']) |
39575
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
323 |
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
324 action, meta = reactor.oncommandresponsereadyobjects( |
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
325 outstream, command['requestid'], objs) |
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
326 |
39815
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
327 except error.WireprotoCommandError as e: |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
328 action, meta = reactor.oncommanderror( |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
329 outstream, command['requestid'], e.message, e.messageargs) |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
330 |
39575
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
331 except Exception as e: |
37726
0c184ca594bb
wireprotov2: change behavior of error frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37725
diff
changeset
|
332 action, meta = reactor.onservererror( |
39575
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
333 outstream, command['requestid'], |
39842
69b4a5b89dc5
py3: cast exception to bytes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39833
diff
changeset
|
334 _('exception when invoking command: %s') % |
69b4a5b89dc5
py3: cast exception to bytes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39833
diff
changeset
|
335 stringutil.forcebytestr(e)) |
37058
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
336 |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
337 if action == 'sendframes': |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
338 res.setbodygen(meta['framegen']) |
37062
bbea991635d0
wireproto: service multiple command requests per HTTP request
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
339 return True |
37059
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
340 elif action == 'noop': |
37132
aaabd709df72
wireproto: review fixups
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37123
diff
changeset
|
341 return False |
37058
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
342 else: |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
343 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
|
344 action) |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
345 |
37782
99accae4cc59
wireproto: reimplement dispatch() for version 2 server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37781
diff
changeset
|
346 def getdispatchrepo(repo, proto, command): |
41845
d6569f1e9b37
server: allow customizing the default repo filter
Joerg Sonnenberger <joerg@bec.de>
parents:
41425
diff
changeset
|
347 viewconfig = repo.ui.config('server', 'view') |
d6569f1e9b37
server: allow customizing the default repo filter
Joerg Sonnenberger <joerg@bec.de>
parents:
41425
diff
changeset
|
348 return repo.filtered(viewconfig) |
37782
99accae4cc59
wireproto: reimplement dispatch() for version 2 server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37781
diff
changeset
|
349 |
40026
b099e6032f38
wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
350 def dispatch(repo, proto, command, redirect): |
40022
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
351 """Run a wire protocol command. |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
352 |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
353 Returns an iterable of objects that will be sent to the client. |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
354 """ |
37782
99accae4cc59
wireproto: reimplement dispatch() for version 2 server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37781
diff
changeset
|
355 repo = getdispatchrepo(repo, proto, command) |
99accae4cc59
wireproto: reimplement dispatch() for version 2 server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37781
diff
changeset
|
356 |
40022
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
357 entry = COMMANDS[command] |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
358 func = entry.func |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
359 spec = entry.args |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
360 |
37782
99accae4cc59
wireproto: reimplement dispatch() for version 2 server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37781
diff
changeset
|
361 args = proto.getargs(spec) |
99accae4cc59
wireproto: reimplement dispatch() for version 2 server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37781
diff
changeset
|
362 |
40022
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
363 # There is some duplicate boilerplate code here for calling the command and |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
364 # emitting objects. It is either that or a lot of indented code that looks |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
365 # like a pyramid (since there are a lot of code paths that result in not |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
366 # using the cacher). |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
367 callcommand = lambda: func(repo, proto, **pycompat.strkwargs(args)) |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
368 |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
369 # Request is not cacheable. Don't bother instantiating a cacher. |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
370 if not entry.cachekeyfn: |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
371 for o in callcommand(): |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
372 yield o |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
373 return |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
374 |
40026
b099e6032f38
wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
375 if redirect: |
b099e6032f38
wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
376 redirecttargets = redirect[b'targets'] |
b099e6032f38
wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
377 redirecthashes = redirect[b'hashes'] |
b099e6032f38
wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
378 else: |
b099e6032f38
wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
379 redirecttargets = [] |
b099e6032f38
wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
380 redirecthashes = [] |
b099e6032f38
wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
381 |
40022
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
382 cacher = makeresponsecacher(repo, proto, command, args, |
40026
b099e6032f38
wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
383 cborutil.streamencode, |
b099e6032f38
wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
384 redirecttargets=redirecttargets, |
b099e6032f38
wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
385 redirecthashes=redirecthashes) |
40022
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
386 |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
387 # But we have no cacher. Do default handling. |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
388 if not cacher: |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
389 for o in callcommand(): |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
390 yield o |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
391 return |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
392 |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
393 with cacher: |
41398
56fcbac62f67
wireprotov2server: use pycompat.strkwargs when calling cachekeyfn
Gregory Szorc <gregory.szorc@gmail.com>
parents:
41216
diff
changeset
|
394 cachekey = entry.cachekeyfn(repo, proto, cacher, |
56fcbac62f67
wireprotov2server: use pycompat.strkwargs when calling cachekeyfn
Gregory Szorc <gregory.szorc@gmail.com>
parents:
41216
diff
changeset
|
395 **pycompat.strkwargs(args)) |
40022
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
396 |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
397 # No cache key or the cacher doesn't like it. Do default handling. |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
398 if cachekey is None or not cacher.setcachekey(cachekey): |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
399 for o in callcommand(): |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
400 yield o |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
401 return |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
402 |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
403 # Serve it from the cache, if possible. |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
404 cached = cacher.lookup() |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
405 |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
406 if cached: |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
407 for o in cached['objs']: |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
408 yield o |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
409 return |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
410 |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
411 # Else call the command and feed its output into the cacher, allowing |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
412 # the cacher to buffer/mutate objects as it desires. |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
413 for o in callcommand(): |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
414 for o in cacher.onobject(o): |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
415 yield o |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
416 |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
417 for o in cacher.onfinished(): |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
418 yield o |
37782
99accae4cc59
wireproto: reimplement dispatch() for version 2 server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37781
diff
changeset
|
419 |
37810
856f381ad74b
interfaceutil: module to stub out zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37784
diff
changeset
|
420 @interfaceutil.implementer(wireprototypes.baseprotocolhandler) |
37296
78103e4138b1
wireproto: port protocol handler to zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37295
diff
changeset
|
421 class httpv2protocolhandler(object): |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
422 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
|
423 self._req = req |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
424 self._ui = ui |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
425 self._args = args |
37050
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
426 |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
427 @property |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
428 def name(self): |
37644
77c9ee77687c
wireproto: rename HTTPV2 so it less like HTTP/2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37557
diff
changeset
|
429 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
|
430 |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
431 def getargs(self, args): |
39815
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
432 # First look for args that were passed but aren't registered on this |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
433 # command. |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
434 extra = set(self._args) - set(args) |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
435 if extra: |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
436 raise error.WireprotoCommandError( |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
437 'unsupported argument to command: %s' % |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
438 ', '.join(sorted(extra))) |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
439 |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
440 # And look for required arguments that are missing. |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
441 missing = {a for a in args if args[a]['required']} - set(self._args) |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
442 |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
443 if missing: |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
444 raise error.WireprotoCommandError( |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
445 'missing required arguments: %s' % ', '.join(sorted(missing))) |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
446 |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
447 # Now derive the arguments to pass to the command, taking into |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
448 # account the arguments specified by the client. |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
449 data = {} |
39815
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
450 for k, meta in sorted(args.items()): |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
451 # This argument wasn't passed by the client. |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
452 if k not in self._args: |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
453 data[k] = meta['default']() |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
454 continue |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
455 |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
456 v = self._args[k] |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
457 |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
458 # Sets may be expressed as lists. Silently normalize. |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
459 if meta['type'] == 'set' and isinstance(v, list): |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
460 v = set(v) |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
461 |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
462 # TODO consider more/stronger type validation. |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
463 |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
464 data[k] = v |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
465 |
37485
0b7475ea38cf
wireproto: port heads command to wire protocol v2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37414
diff
changeset
|
466 return data |
37050
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
467 |
37393
afcfdf53e4b5
wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents:
37296
diff
changeset
|
468 def getprotocaps(self): |
afcfdf53e4b5
wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents:
37296
diff
changeset
|
469 # 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
|
470 return set() |
afcfdf53e4b5
wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents:
37296
diff
changeset
|
471 |
37414
2d965bfeb8f6
wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents:
37393
diff
changeset
|
472 def getpayload(self): |
37050
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
473 raise NotImplementedError |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
474 |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
475 @contextlib.contextmanager |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
476 def mayberedirectstdio(self): |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
477 raise NotImplementedError |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
478 |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
479 def client(self): |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
480 raise NotImplementedError |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
481 |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
482 def addcapabilities(self, repo, caps): |
37057
e7a012b60d6e
wireproto: implement basic command dispatching for HTTPv2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
483 return caps |
37050
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
484 |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
485 def checkperm(self, perm): |
fddcb51b5084
wireproto: define permissions-based routing of HTTPv2 wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37049
diff
changeset
|
486 raise NotImplementedError |
37546
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
487 |
37557
734515aca84d
wireproto: define and implement HTTP handshake to upgrade protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37546
diff
changeset
|
488 def httpv2apidescriptor(req, repo): |
734515aca84d
wireproto: define and implement HTTP handshake to upgrade protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37546
diff
changeset
|
489 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
|
490 |
734515aca84d
wireproto: define and implement HTTP handshake to upgrade protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37546
diff
changeset
|
491 return _capabilitiesv2(repo, proto) |
734515aca84d
wireproto: define and implement HTTP handshake to upgrade protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37546
diff
changeset
|
492 |
37546
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
493 def _capabilitiesv2(repo, proto): |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
494 """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
|
495 |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
496 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
|
497 transports. |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
498 """ |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
499 caps = { |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
500 'commands': {}, |
37653
b2fa1591fb44
wireproto: add media type to version 2 capabilities response
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37644
diff
changeset
|
501 'framingmediatypes': [FRAMINGTYPE], |
39816
ae20f52437e9
wireprotov2: advertise recognized path filter prefixes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39815
diff
changeset
|
502 'pathfilterprefixes': set(narrowspec.VALID_PREFIXES), |
37546
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
503 } |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
504 |
37784
ee0d5e9d77b2
wireproto: move version 2 commands dict to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37783
diff
changeset
|
505 for command, entry in COMMANDS.items(): |
39817
8e7e822e85ec
wireprotov2: expose rich arguments metadata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39816
diff
changeset
|
506 args = {} |
8e7e822e85ec
wireprotov2: expose rich arguments metadata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39816
diff
changeset
|
507 |
8e7e822e85ec
wireprotov2: expose rich arguments metadata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39816
diff
changeset
|
508 for arg, meta in entry.args.items(): |
8e7e822e85ec
wireprotov2: expose rich arguments metadata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39816
diff
changeset
|
509 args[arg] = { |
8e7e822e85ec
wireprotov2: expose rich arguments metadata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39816
diff
changeset
|
510 # TODO should this be a normalized type using CBOR's |
8e7e822e85ec
wireprotov2: expose rich arguments metadata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39816
diff
changeset
|
511 # terminology? |
8e7e822e85ec
wireprotov2: expose rich arguments metadata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39816
diff
changeset
|
512 b'type': meta['type'], |
8e7e822e85ec
wireprotov2: expose rich arguments metadata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39816
diff
changeset
|
513 b'required': meta['required'], |
8e7e822e85ec
wireprotov2: expose rich arguments metadata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39816
diff
changeset
|
514 } |
8e7e822e85ec
wireprotov2: expose rich arguments metadata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39816
diff
changeset
|
515 |
8e7e822e85ec
wireprotov2: expose rich arguments metadata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39816
diff
changeset
|
516 if not meta['required']: |
8e7e822e85ec
wireprotov2: expose rich arguments metadata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39816
diff
changeset
|
517 args[arg][b'default'] = meta['default']() |
39815
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
518 |
39818
c30faea8d02d
wireprotov2: advertise set of valid values for requestable fields
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39817
diff
changeset
|
519 if meta['validvalues']: |
c30faea8d02d
wireprotov2: advertise set of valid values for requestable fields
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39817
diff
changeset
|
520 args[arg][b'validvalues'] = meta['validvalues'] |
c30faea8d02d
wireprotov2: advertise set of valid values for requestable fields
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39817
diff
changeset
|
521 |
40329
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
522 # TODO this type of check should be defined in a per-command callback. |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
523 if (command == b'rawstorefiledata' |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
524 and not streamclone.allowservergeneration(repo)): |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
525 continue |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
526 |
37546
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
527 caps['commands'][command] = { |
39815
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
528 'args': args, |
37546
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
529 'permissions': [entry.permission], |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
530 } |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
531 |
40172
30f70d11c224
wireprotov2: advertise recommended batch size for requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40138
diff
changeset
|
532 if entry.extracapabilitiesfn: |
30f70d11c224
wireprotov2: advertise recommended batch size for requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40138
diff
changeset
|
533 extracaps = entry.extracapabilitiesfn(repo, proto) |
30f70d11c224
wireprotov2: advertise recommended batch size for requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40138
diff
changeset
|
534 caps['commands'][command].update(extracaps) |
30f70d11c224
wireprotov2: advertise recommended batch size for requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40138
diff
changeset
|
535 |
40050
39074a35f7db
wireprotov2: always advertise raw repo requirements
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40026
diff
changeset
|
536 caps['rawrepoformats'] = sorted(repo.requirements & |
39074a35f7db
wireprotov2: always advertise raw repo requirements
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40026
diff
changeset
|
537 repo.supportedformats) |
37657
23c4ddda7bbe
wireproto: expose repository formats via capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37653
diff
changeset
|
538 |
40024
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
539 targets = getadvertisedredirecttargets(repo, proto) |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
540 if targets: |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
541 caps[b'redirect'] = { |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
542 b'targets': [], |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
543 b'hashes': [b'sha256', b'sha1'], |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
544 } |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
545 |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
546 for target in targets: |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
547 entry = { |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
548 b'name': target['name'], |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
549 b'protocol': target['protocol'], |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
550 b'uris': target['uris'], |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
551 } |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
552 |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
553 for key in ('snirequired', 'tlsversions'): |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
554 if key in target: |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
555 entry[key] = target[key] |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
556 |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
557 caps[b'redirect'][b'targets'].append(entry) |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
558 |
37546
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
559 return proto.addcapabilities(repo, caps) |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
560 |
40024
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
561 def getadvertisedredirecttargets(repo, proto): |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
562 """Obtain a list of content redirect targets. |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
563 |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
564 Returns a list containing potential redirect targets that will be |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
565 advertised in capabilities data. Each dict MUST have the following |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
566 keys: |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
567 |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
568 name |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
569 The name of this redirect target. This is the identifier clients use |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
570 to refer to a target. It is transferred as part of every command |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
571 request. |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
572 |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
573 protocol |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
574 Network protocol used by this target. Typically this is the string |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
575 in front of the ``://`` in a URL. e.g. ``https``. |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
576 |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
577 uris |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
578 List of representative URIs for this target. Clients can use the |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
579 URIs to test parsing for compatibility or for ordering preference |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
580 for which target to use. |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
581 |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
582 The following optional keys are recognized: |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
583 |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
584 snirequired |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
585 Bool indicating if Server Name Indication (SNI) is required to |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
586 connect to this target. |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
587 |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
588 tlsversions |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
589 List of bytes indicating which TLS versions are supported by this |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
590 target. |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
591 |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
592 By default, clients reflect the target order advertised by servers |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
593 and servers will use the first client-advertised target when picking |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
594 a redirect target. So targets should be advertised in the order the |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
595 server prefers they be used. |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
596 """ |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
597 return [] |
10cf8b116dd8
wireprotov2: advertise redirect targets in capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40022
diff
changeset
|
598 |
40172
30f70d11c224
wireprotov2: advertise recommended batch size for requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40138
diff
changeset
|
599 def wireprotocommand(name, args=None, permission='push', cachekeyfn=None, |
30f70d11c224
wireprotov2: advertise recommended batch size for requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40138
diff
changeset
|
600 extracapabilitiesfn=None): |
37780
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
601 """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
|
602 |
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
603 ``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
|
604 |
39815
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
605 ``args`` is a dict defining arguments accepted by the command. Keys are |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
606 the argument name. Values are dicts with the following keys: |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
607 |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
608 ``type`` |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
609 The argument data type. Must be one of the following string |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
610 literals: ``bytes``, ``int``, ``list``, ``dict``, ``set``, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
611 or ``bool``. |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
612 |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
613 ``default`` |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
614 A callable returning the default value for this argument. If not |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
615 specified, ``None`` will be the default value. |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
616 |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
617 ``example`` |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
618 An example value for this argument. |
37780
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
619 |
39818
c30faea8d02d
wireprotov2: advertise set of valid values for requestable fields
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39817
diff
changeset
|
620 ``validvalues`` |
c30faea8d02d
wireprotov2: advertise set of valid values for requestable fields
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39817
diff
changeset
|
621 Set of recognized values for this argument. |
c30faea8d02d
wireprotov2: advertise set of valid values for requestable fields
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39817
diff
changeset
|
622 |
37780
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
623 ``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
|
624 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
|
625 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
|
626 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
|
627 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
|
628 |
40022
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
629 ``cachekeyfn`` defines an optional callable that can derive the |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
630 cache key for this request. |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
631 |
40172
30f70d11c224
wireprotov2: advertise recommended batch size for requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40138
diff
changeset
|
632 ``extracapabilitiesfn`` defines an optional callable that defines extra |
30f70d11c224
wireprotov2: advertise recommended batch size for requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40138
diff
changeset
|
633 command capabilities/parameters that are advertised next to the command |
30f70d11c224
wireprotov2: advertise recommended batch size for requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40138
diff
changeset
|
634 in the capabilities data structure describing the server. The callable |
30f70d11c224
wireprotov2: advertise recommended batch size for requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40138
diff
changeset
|
635 receives as arguments the repository and protocol objects. It returns |
30f70d11c224
wireprotov2: advertise recommended batch size for requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40138
diff
changeset
|
636 a dict of extra fields to add to the command descriptor. |
30f70d11c224
wireprotov2: advertise recommended batch size for requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40138
diff
changeset
|
637 |
39575
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
638 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
|
639 sent to the client. |
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
640 |
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
641 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
|
642 a command error. |
40022
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
643 |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
644 All commands can opt in to being cacheable by defining a function |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
645 (``cachekeyfn``) that is called to derive a cache key. This function |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
646 receives the same arguments as the command itself plus a ``cacher`` |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
647 argument containing the active cacher for the request and returns a bytes |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
648 containing the key in a cache the response to this command may be cached |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
649 under. |
37780
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
650 """ |
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
651 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
|
652 if v['version'] == 2} |
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
653 |
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
654 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
|
655 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
|
656 '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
|
657 permission) |
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
658 |
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
659 if args is None: |
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
660 args = {} |
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
661 |
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
662 if not isinstance(args, dict): |
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
663 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
|
664 'must be declared as dicts') |
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
665 |
39815
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
666 for arg, meta in args.items(): |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
667 if arg == '*': |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
668 raise error.ProgrammingError('* argument name not allowed on ' |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
669 'version 2 commands') |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
670 |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
671 if not isinstance(meta, dict): |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
672 raise error.ProgrammingError('arguments for version 2 commands ' |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
673 'must declare metadata as a dict') |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
674 |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
675 if 'type' not in meta: |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
676 raise error.ProgrammingError('%s argument for command %s does not ' |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
677 'declare type field' % (arg, name)) |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
678 |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
679 if meta['type'] not in ('bytes', 'int', 'list', 'dict', 'set', 'bool'): |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
680 raise error.ProgrammingError('%s argument for command %s has ' |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
681 'illegal type: %s' % (arg, name, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
682 meta['type'])) |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
683 |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
684 if 'example' not in meta: |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
685 raise error.ProgrammingError('%s argument for command %s does not ' |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
686 'declare example field' % (arg, name)) |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
687 |
39996
582676acaf6d
wireprotov2: derive "required" from presence of default value
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39869
diff
changeset
|
688 meta['required'] = 'default' not in meta |
39815
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
689 |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
690 meta.setdefault('default', lambda: None) |
39818
c30faea8d02d
wireprotov2: advertise set of valid values for requestable fields
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39817
diff
changeset
|
691 meta.setdefault('validvalues', None) |
39815
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
692 |
37546
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
693 def register(func): |
37784
ee0d5e9d77b2
wireproto: move version 2 commands dict to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37783
diff
changeset
|
694 if name in COMMANDS: |
37780
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
695 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
|
696 'for version 2' % name) |
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
697 |
37784
ee0d5e9d77b2
wireproto: move version 2 commands dict to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37783
diff
changeset
|
698 COMMANDS[name] = wireprototypes.commandentry( |
40022
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
699 func, args=args, transports=transports, permission=permission, |
40172
30f70d11c224
wireprotov2: advertise recommended batch size for requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40138
diff
changeset
|
700 cachekeyfn=cachekeyfn, extracapabilitiesfn=extracapabilitiesfn) |
37780
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
701 |
8acd3a9ac4fd
wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37728
diff
changeset
|
702 return func |
37546
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
703 |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
704 return register |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
705 |
40022
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
706 def makecommandcachekeyfn(command, localversion=None, allargs=False): |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
707 """Construct a cache key derivation function with common features. |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
708 |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
709 By default, the cache key is a hash of: |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
710 |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
711 * The command name. |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
712 * A global cache version number. |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
713 * A local cache version number (passed via ``localversion``). |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
714 * All the arguments passed to the command. |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
715 * The media type used. |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
716 * Wire protocol version string. |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
717 * The repository path. |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
718 """ |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
719 if not allargs: |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
720 raise error.ProgrammingError('only allargs=True is currently supported') |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
721 |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
722 if localversion is None: |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
723 raise error.ProgrammingError('must set localversion argument value') |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
724 |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
725 def cachekeyfn(repo, proto, cacher, **args): |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
726 spec = COMMANDS[command] |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
727 |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
728 # Commands that mutate the repo can not be cached. |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
729 if spec.permission == 'push': |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
730 return None |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
731 |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
732 # TODO config option to disable caching. |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
733 |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
734 # Our key derivation strategy is to construct a data structure |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
735 # holding everything that could influence cacheability and to hash |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
736 # the CBOR representation of that. Using CBOR seems like it might |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
737 # be overkill. However, simpler hashing mechanisms are prone to |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
738 # duplicate input issues. e.g. if you just concatenate two values, |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
739 # "foo"+"bar" is identical to "fo"+"obar". Using CBOR provides |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
740 # "padding" between values and prevents these problems. |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
741 |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
742 # Seed the hash with various data. |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
743 state = { |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
744 # To invalidate all cache keys. |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
745 b'globalversion': GLOBAL_CACHE_VERSION, |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
746 # More granular cache key invalidation. |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
747 b'localversion': localversion, |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
748 # Cache keys are segmented by command. |
41399
e053053ceba7
wireprotov2server: don't attempt to cast command name
Gregory Szorc <gregory.szorc@gmail.com>
parents:
41398
diff
changeset
|
749 b'command': command, |
40022
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
750 # Throw in the media type and API version strings so changes |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
751 # to exchange semantics invalid cache. |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
752 b'mediatype': FRAMINGTYPE, |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
753 b'version': HTTP_WIREPROTO_V2, |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
754 # So same requests for different repos don't share cache keys. |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
755 b'repo': repo.root, |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
756 } |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
757 |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
758 # The arguments passed to us will have already been normalized. |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
759 # Default values will be set, etc. This is important because it |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
760 # means that it doesn't matter if clients send an explicit argument |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
761 # or rely on the default value: it will all normalize to the same |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
762 # set of arguments on the server and therefore the same cache key. |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
763 # |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
764 # Arguments by their very nature must support being encoded to CBOR. |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
765 # And the CBOR encoder is deterministic. So we hash the arguments |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
766 # by feeding the CBOR of their representation into the hasher. |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
767 if allargs: |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
768 state[b'args'] = pycompat.byteskwargs(args) |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
769 |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
770 cacher.adjustcachekeystate(state) |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
771 |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
772 hasher = hashlib.sha1() |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
773 for chunk in cborutil.streamencode(state): |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
774 hasher.update(chunk) |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
775 |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
776 return pycompat.sysbytes(hasher.hexdigest()) |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
777 |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
778 return cachekeyfn |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
779 |
40026
b099e6032f38
wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
780 def makeresponsecacher(repo, proto, command, args, objencoderfn, |
b099e6032f38
wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
781 redirecttargets, redirecthashes): |
40022
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
782 """Construct a cacher for a cacheable command. |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
783 |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
784 Returns an ``iwireprotocolcommandcacher`` instance. |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
785 |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
786 Extensions can monkeypatch this function to provide custom caching |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
787 backends. |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
788 """ |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
789 return None |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
790 |
40176
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
791 def resolvenodes(repo, revisions): |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
792 """Resolve nodes from a revisions specifier data structure.""" |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
793 cl = repo.changelog |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
794 clhasnode = cl.hasnode |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
795 |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
796 seen = set() |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
797 nodes = [] |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
798 |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
799 if not isinstance(revisions, list): |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
800 raise error.WireprotoCommandError('revisions must be defined as an ' |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
801 'array') |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
802 |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
803 for spec in revisions: |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
804 if b'type' not in spec: |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
805 raise error.WireprotoCommandError( |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
806 'type key not present in revision specifier') |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
807 |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
808 typ = spec[b'type'] |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
809 |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
810 if typ == b'changesetexplicit': |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
811 if b'nodes' not in spec: |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
812 raise error.WireprotoCommandError( |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
813 'nodes key not present in changesetexplicit revision ' |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
814 'specifier') |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
815 |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
816 for node in spec[b'nodes']: |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
817 if node not in seen: |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
818 nodes.append(node) |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
819 seen.add(node) |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
820 |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
821 elif typ == b'changesetexplicitdepth': |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
822 for key in (b'nodes', b'depth'): |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
823 if key not in spec: |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
824 raise error.WireprotoCommandError( |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
825 '%s key not present in changesetexplicitdepth revision ' |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
826 'specifier', (key,)) |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
827 |
41216
5cc5a5561c3f
revset: remove a rare usage of "%d" for a non-revision item
Boris Feld <boris.feld@octobus.net>
parents:
40942
diff
changeset
|
828 for rev in repo.revs(b'ancestors(%ln, %s)', spec[b'nodes'], |
40176
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
829 spec[b'depth'] - 1): |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
830 node = cl.node(rev) |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
831 |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
832 if node not in seen: |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
833 nodes.append(node) |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
834 seen.add(node) |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
835 |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
836 elif typ == b'changesetdagrange': |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
837 for key in (b'roots', b'heads'): |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
838 if key not in spec: |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
839 raise error.WireprotoCommandError( |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
840 '%s key not present in changesetdagrange revision ' |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
841 'specifier', (key,)) |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
842 |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
843 if not spec[b'heads']: |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
844 raise error.WireprotoCommandError( |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
845 'heads key in changesetdagrange cannot be empty') |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
846 |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
847 if spec[b'roots']: |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
848 common = [n for n in spec[b'roots'] if clhasnode(n)] |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
849 else: |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
850 common = [nullid] |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
851 |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
852 for n in discovery.outgoing(repo, common, spec[b'heads']).missing: |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
853 if n not in seen: |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
854 nodes.append(n) |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
855 seen.add(n) |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
856 |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
857 else: |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
858 raise error.WireprotoCommandError( |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
859 'unknown revision specifier type: %s', (typ,)) |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
860 |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
861 return nodes |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
862 |
37546
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
863 @wireprotocommand('branchmap', permission='pull') |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
864 def branchmapv2(repo, proto): |
39575
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
865 yield {encoding.fromlocal(k): v |
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
866 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
|
867 |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
868 @wireprotocommand('capabilities', permission='pull') |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
869 def capabilitiesv2(repo, proto): |
39575
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
870 yield _capabilitiesv2(repo, proto) |
37546
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
871 |
39815
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
872 @wireprotocommand( |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
873 'changesetdata', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
874 args={ |
40176
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
875 'revisions': { |
39815
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
876 'type': 'list', |
40176
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
877 'example': [{ |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
878 b'type': b'changesetexplicit', |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
879 b'nodes': [b'abcdef...'], |
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
880 }], |
39820
d3d333ab167a
wireprotov2: teach changesetdata to fetch ancestors until depth
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39819
diff
changeset
|
881 }, |
39815
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
882 'fields': { |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
883 'type': 'set', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
884 'default': set, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
885 'example': {b'parents', b'revision'}, |
39818
c30faea8d02d
wireprotov2: advertise set of valid values for requestable fields
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39817
diff
changeset
|
886 'validvalues': {b'bookmarks', b'parents', b'phase', b'revision'}, |
39815
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
887 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
888 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
889 permission='pull') |
40176
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
890 def changesetdata(repo, proto, revisions, fields): |
39652
399ddd3227a4
wireprotov2: add TODOs around extending changesetdata fields
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39650
diff
changeset
|
891 # TODO look for unknown fields and abort when they can't be serviced. |
39818
c30faea8d02d
wireprotov2: advertise set of valid values for requestable fields
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39817
diff
changeset
|
892 # This could probably be validated by dispatcher using validvalues. |
39652
399ddd3227a4
wireprotov2: add TODOs around extending changesetdata fields
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39650
diff
changeset
|
893 |
39646
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
894 cl = repo.changelog |
40176
41263df08109
wireprotov2: change how revisions are specified to changesetdata
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40175
diff
changeset
|
895 outgoing = resolvenodes(repo, revisions) |
39648
c1aacb0d76ff
wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39646
diff
changeset
|
896 publishing = repo.publishing() |
39646
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
897 |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
898 if outgoing: |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
899 repo.hook('preoutgoing', throw=True, source='serve') |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
900 |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
901 yield { |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
902 b'totalitems': len(outgoing), |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
903 } |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
904 |
39648
c1aacb0d76ff
wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39646
diff
changeset
|
905 # 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
|
906 # 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
|
907 # for these revisions, if requested. |
40175
6c42409691ec
wireprotov2: stop sending phase updates for base revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40172
diff
changeset
|
908 # TODO actually do this. We'll probably want to emit phase heads |
6c42409691ec
wireprotov2: stop sending phase updates for base revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40172
diff
changeset
|
909 # in the ancestry set of the outgoing revisions. This will ensure |
6c42409691ec
wireprotov2: stop sending phase updates for base revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40172
diff
changeset
|
910 # that phase updates within that set are seen. |
6c42409691ec
wireprotov2: stop sending phase updates for base revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40172
diff
changeset
|
911 if b'phase' in fields: |
6c42409691ec
wireprotov2: stop sending phase updates for base revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40172
diff
changeset
|
912 pass |
39648
c1aacb0d76ff
wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39646
diff
changeset
|
913 |
39650
9dffa99f9158
wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39648
diff
changeset
|
914 nodebookmarks = {} |
9dffa99f9158
wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39648
diff
changeset
|
915 for mark, node in repo._bookmarks.items(): |
9dffa99f9158
wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39648
diff
changeset
|
916 nodebookmarks.setdefault(node, set()).add(mark) |
9dffa99f9158
wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39648
diff
changeset
|
917 |
39646
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
918 # 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
|
919 for node in outgoing: |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
920 d = { |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
921 b'node': node, |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
922 } |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
923 |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
924 if b'parents' in fields: |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
925 d[b'parents'] = cl.parents(node) |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
926 |
39648
c1aacb0d76ff
wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39646
diff
changeset
|
927 if b'phase' in fields: |
c1aacb0d76ff
wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39646
diff
changeset
|
928 if publishing: |
c1aacb0d76ff
wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39646
diff
changeset
|
929 d[b'phase'] = b'public' |
c1aacb0d76ff
wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39646
diff
changeset
|
930 else: |
c1aacb0d76ff
wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39646
diff
changeset
|
931 ctx = repo[node] |
c1aacb0d76ff
wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39646
diff
changeset
|
932 d[b'phase'] = ctx.phasestr() |
c1aacb0d76ff
wireprotov2: add phases to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39646
diff
changeset
|
933 |
39650
9dffa99f9158
wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39648
diff
changeset
|
934 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
|
935 d[b'bookmarks'] = sorted(nodebookmarks[node]) |
9dffa99f9158
wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39648
diff
changeset
|
936 del nodebookmarks[node] |
9dffa99f9158
wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39648
diff
changeset
|
937 |
39819
d059cb669632
wireprotov2: allow multiple fields to follow revision maps
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39818
diff
changeset
|
938 followingmeta = [] |
d059cb669632
wireprotov2: allow multiple fields to follow revision maps
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39818
diff
changeset
|
939 followingdata = [] |
39646
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
940 |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
941 if b'revision' in fields: |
42790
da643cadec90
rawdata: update caller in wireprotov2server
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
41845
diff
changeset
|
942 revisiondata = cl.rawdata(node) |
39819
d059cb669632
wireprotov2: allow multiple fields to follow revision maps
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39818
diff
changeset
|
943 followingmeta.append((b'revision', len(revisiondata))) |
d059cb669632
wireprotov2: allow multiple fields to follow revision maps
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39818
diff
changeset
|
944 followingdata.append(revisiondata) |
39646
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
945 |
39652
399ddd3227a4
wireprotov2: add TODOs around extending changesetdata fields
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39650
diff
changeset
|
946 # 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
|
947 # a handler to service custom fields. |
399ddd3227a4
wireprotov2: add TODOs around extending changesetdata fields
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39650
diff
changeset
|
948 |
39819
d059cb669632
wireprotov2: allow multiple fields to follow revision maps
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39818
diff
changeset
|
949 if followingmeta: |
d059cb669632
wireprotov2: allow multiple fields to follow revision maps
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39818
diff
changeset
|
950 d[b'fieldsfollowing'] = followingmeta |
d059cb669632
wireprotov2: allow multiple fields to follow revision maps
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39818
diff
changeset
|
951 |
39646
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
952 yield d |
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
953 |
39819
d059cb669632
wireprotov2: allow multiple fields to follow revision maps
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39818
diff
changeset
|
954 for extra in followingdata: |
d059cb669632
wireprotov2: allow multiple fields to follow revision maps
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39818
diff
changeset
|
955 yield extra |
39646
9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39575
diff
changeset
|
956 |
39650
9dffa99f9158
wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39648
diff
changeset
|
957 # 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
|
958 # 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
|
959 if b'bookmarks' in fields: |
9dffa99f9158
wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39648
diff
changeset
|
960 for node, marks in sorted(nodebookmarks.iteritems()): |
9dffa99f9158
wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39648
diff
changeset
|
961 yield { |
9dffa99f9158
wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39648
diff
changeset
|
962 b'node': node, |
9dffa99f9158
wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39648
diff
changeset
|
963 b'bookmarks': sorted(marks), |
9dffa99f9158
wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39648
diff
changeset
|
964 } |
9dffa99f9158
wireprotov2: add bookmarks to "changesetdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39648
diff
changeset
|
965 |
39655
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
966 class FileAccessError(Exception): |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
967 """Represents an error accessing a specific file.""" |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
968 |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
969 def __init__(self, path, msg, args): |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
970 self.path = path |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
971 self.msg = msg |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
972 self.args = args |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
973 |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
974 def getfilestore(repo, proto, path): |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
975 """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
|
976 |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
977 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
|
978 access control. |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
979 """ |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
980 # 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
|
981 # "empty" files and return an error. |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
982 fl = repo.file(path) |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
983 |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
984 if not len(fl): |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
985 raise FileAccessError(path, 'unknown file: %s', (path,)) |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
986 |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
987 return fl |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
988 |
40941
3ed77780f4a6
wireprotov2: send linknodes to emitfilerevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40692
diff
changeset
|
989 def emitfilerevisions(repo, path, revisions, linknodes, fields): |
40177
41e2633bcd00
wireprotov2: extract file object emission to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40176
diff
changeset
|
990 for revision in revisions: |
41e2633bcd00
wireprotov2: extract file object emission to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40176
diff
changeset
|
991 d = { |
41e2633bcd00
wireprotov2: extract file object emission to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40176
diff
changeset
|
992 b'node': revision.node, |
41e2633bcd00
wireprotov2: extract file object emission to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40176
diff
changeset
|
993 } |
41e2633bcd00
wireprotov2: extract file object emission to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40176
diff
changeset
|
994 |
41e2633bcd00
wireprotov2: extract file object emission to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40176
diff
changeset
|
995 if b'parents' in fields: |
41e2633bcd00
wireprotov2: extract file object emission to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40176
diff
changeset
|
996 d[b'parents'] = [revision.p1node, revision.p2node] |
41e2633bcd00
wireprotov2: extract file object emission to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40176
diff
changeset
|
997 |
40391
abbd077965c0
wireprotov2: support exposing linknode of file revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40329
diff
changeset
|
998 if b'linknode' in fields: |
40941
3ed77780f4a6
wireprotov2: send linknodes to emitfilerevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40692
diff
changeset
|
999 d[b'linknode'] = linknodes[revision.node] |
40391
abbd077965c0
wireprotov2: support exposing linknode of file revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40329
diff
changeset
|
1000 |
40177
41e2633bcd00
wireprotov2: extract file object emission to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40176
diff
changeset
|
1001 followingmeta = [] |
41e2633bcd00
wireprotov2: extract file object emission to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40176
diff
changeset
|
1002 followingdata = [] |
41e2633bcd00
wireprotov2: extract file object emission to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40176
diff
changeset
|
1003 |
41e2633bcd00
wireprotov2: extract file object emission to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40176
diff
changeset
|
1004 if b'revision' in fields: |
41e2633bcd00
wireprotov2: extract file object emission to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40176
diff
changeset
|
1005 if revision.revision is not None: |
41e2633bcd00
wireprotov2: extract file object emission to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40176
diff
changeset
|
1006 followingmeta.append((b'revision', len(revision.revision))) |
41e2633bcd00
wireprotov2: extract file object emission to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40176
diff
changeset
|
1007 followingdata.append(revision.revision) |
41e2633bcd00
wireprotov2: extract file object emission to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40176
diff
changeset
|
1008 else: |
41e2633bcd00
wireprotov2: extract file object emission to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40176
diff
changeset
|
1009 d[b'deltabasenode'] = revision.basenode |
41e2633bcd00
wireprotov2: extract file object emission to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40176
diff
changeset
|
1010 followingmeta.append((b'delta', len(revision.delta))) |
41e2633bcd00
wireprotov2: extract file object emission to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40176
diff
changeset
|
1011 followingdata.append(revision.delta) |
41e2633bcd00
wireprotov2: extract file object emission to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40176
diff
changeset
|
1012 |
41e2633bcd00
wireprotov2: extract file object emission to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40176
diff
changeset
|
1013 if followingmeta: |
41e2633bcd00
wireprotov2: extract file object emission to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40176
diff
changeset
|
1014 d[b'fieldsfollowing'] = followingmeta |
41e2633bcd00
wireprotov2: extract file object emission to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40176
diff
changeset
|
1015 |
41e2633bcd00
wireprotov2: extract file object emission to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40176
diff
changeset
|
1016 yield d |
41e2633bcd00
wireprotov2: extract file object emission to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40176
diff
changeset
|
1017 |
41e2633bcd00
wireprotov2: extract file object emission to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40176
diff
changeset
|
1018 for extra in followingdata: |
41e2633bcd00
wireprotov2: extract file object emission to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40176
diff
changeset
|
1019 yield extra |
41e2633bcd00
wireprotov2: extract file object emission to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40176
diff
changeset
|
1020 |
40178
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1021 def makefilematcher(repo, pathfilter): |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1022 """Construct a matcher from a path filter dict.""" |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1023 |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1024 # Validate values. |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1025 if pathfilter: |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1026 for key in (b'include', b'exclude'): |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1027 for pattern in pathfilter.get(key, []): |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1028 if not pattern.startswith((b'path:', b'rootfilesin:')): |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1029 raise error.WireprotoCommandError( |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1030 '%s pattern must begin with `path:` or `rootfilesin:`; ' |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1031 'got %s', (key, pattern)) |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1032 |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1033 if pathfilter: |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1034 matcher = matchmod.match(repo.root, b'', |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1035 include=pathfilter.get(b'include', []), |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1036 exclude=pathfilter.get(b'exclude', [])) |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1037 else: |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1038 matcher = matchmod.match(repo.root, b'') |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1039 |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1040 # Requested patterns could include files not in the local store. So |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1041 # filter those out. |
40692
f83cea7f54d7
wireprotov2server: let repo.narrowmatch(match) do matcher intersection
Martin von Zweigbergk <martinvonz@google.com>
parents:
40391
diff
changeset
|
1042 return repo.narrowmatch(matcher) |
40178
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1043 |
39815
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1044 @wireprotocommand( |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1045 'filedata', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1046 args={ |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1047 'haveparents': { |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1048 'type': 'bool', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1049 'default': lambda: False, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1050 'example': True, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1051 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1052 'nodes': { |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1053 'type': 'list', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1054 'example': [b'0123456...'], |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1055 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1056 'fields': { |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1057 'type': 'set', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1058 'default': set, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1059 'example': {b'parents', b'revision'}, |
40391
abbd077965c0
wireprotov2: support exposing linknode of file revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40329
diff
changeset
|
1060 'validvalues': {b'parents', b'revision', b'linknode'}, |
39815
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1061 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1062 'path': { |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1063 'type': 'bytes', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1064 'example': b'foo.txt', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1065 } |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1066 }, |
40022
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
1067 permission='pull', |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
1068 # TODO censoring a file revision won't invalidate the cache. |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
1069 # Figure out a way to take censoring into account when deriving |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
1070 # the cache key. |
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
1071 cachekeyfn=makecommandcachekeyfn('filedata', 1, allargs=True)) |
39815
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1072 def filedata(repo, proto, haveparents, nodes, fields, path): |
40178
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1073 # TODO this API allows access to file revisions that are attached to |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1074 # secret changesets. filesdata does not have this problem. Maybe this |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1075 # API should be deleted? |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1076 |
39655
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
1077 try: |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
1078 # 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
|
1079 store = getfilestore(repo, proto, path) |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
1080 except FileAccessError as e: |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
1081 raise error.WireprotoCommandError(e.msg, e.args) |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
1082 |
40941
3ed77780f4a6
wireprotov2: send linknodes to emitfilerevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40692
diff
changeset
|
1083 clnode = repo.changelog.node |
3ed77780f4a6
wireprotov2: send linknodes to emitfilerevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40692
diff
changeset
|
1084 linknodes = {} |
3ed77780f4a6
wireprotov2: send linknodes to emitfilerevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40692
diff
changeset
|
1085 |
39655
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
1086 # Validate requested nodes. |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
1087 for node in nodes: |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
1088 try: |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
1089 store.rev(node) |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
1090 except error.LookupError: |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
1091 raise error.WireprotoCommandError('unknown file node: %s', |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
1092 (hex(node),)) |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
1093 |
40941
3ed77780f4a6
wireprotov2: send linknodes to emitfilerevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40692
diff
changeset
|
1094 # TODO by creating the filectx against a specific file revision |
3ed77780f4a6
wireprotov2: send linknodes to emitfilerevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40692
diff
changeset
|
1095 # instead of changeset, linkrev() is always used. This is wrong for |
3ed77780f4a6
wireprotov2: send linknodes to emitfilerevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40692
diff
changeset
|
1096 # cases where linkrev() may refer to a hidden changeset. But since this |
3ed77780f4a6
wireprotov2: send linknodes to emitfilerevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40692
diff
changeset
|
1097 # API doesn't know anything about changesets, we're not sure how to |
3ed77780f4a6
wireprotov2: send linknodes to emitfilerevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40692
diff
changeset
|
1098 # disambiguate the linknode. Perhaps we should delete this API? |
3ed77780f4a6
wireprotov2: send linknodes to emitfilerevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40692
diff
changeset
|
1099 fctx = repo.filectx(path, fileid=node) |
3ed77780f4a6
wireprotov2: send linknodes to emitfilerevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40692
diff
changeset
|
1100 linknodes[node] = clnode(fctx.introrev()) |
3ed77780f4a6
wireprotov2: send linknodes to emitfilerevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40692
diff
changeset
|
1101 |
39869
7b752bf08435
wireprotov2server: port to emitrevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39842
diff
changeset
|
1102 revisions = store.emitrevisions(nodes, |
7b752bf08435
wireprotov2server: port to emitrevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39842
diff
changeset
|
1103 revisiondata=b'revision' in fields, |
7b752bf08435
wireprotov2server: port to emitrevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39842
diff
changeset
|
1104 assumehaveparentrevisions=haveparents) |
39655
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
1105 |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
1106 yield { |
39869
7b752bf08435
wireprotov2server: port to emitrevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39842
diff
changeset
|
1107 b'totalitems': len(nodes), |
39655
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
1108 } |
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
1109 |
40941
3ed77780f4a6
wireprotov2: send linknodes to emitfilerevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40692
diff
changeset
|
1110 for o in emitfilerevisions(repo, path, revisions, linknodes, fields): |
40177
41e2633bcd00
wireprotov2: extract file object emission to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40176
diff
changeset
|
1111 yield o |
39655
0e03e6a44dee
wireprotov2: define and implement "filedata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39653
diff
changeset
|
1112 |
40178
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1113 def filesdatacapabilities(repo, proto): |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1114 batchsize = repo.ui.configint( |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1115 b'experimental', b'server.filesdata.recommended-batch-size') |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1116 return { |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1117 b'recommendedbatchsize': batchsize, |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1118 } |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1119 |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1120 @wireprotocommand( |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1121 'filesdata', |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1122 args={ |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1123 'haveparents': { |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1124 'type': 'bool', |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1125 'default': lambda: False, |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1126 'example': True, |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1127 }, |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1128 'fields': { |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1129 'type': 'set', |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1130 'default': set, |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1131 'example': {b'parents', b'revision'}, |
40391
abbd077965c0
wireprotov2: support exposing linknode of file revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40329
diff
changeset
|
1132 'validvalues': {b'firstchangeset', b'linknode', b'parents', |
abbd077965c0
wireprotov2: support exposing linknode of file revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40329
diff
changeset
|
1133 b'revision'}, |
40178
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1134 }, |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1135 'pathfilter': { |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1136 'type': 'dict', |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1137 'default': lambda: None, |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1138 'example': {b'include': [b'path:tests']}, |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1139 }, |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1140 'revisions': { |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1141 'type': 'list', |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1142 'example': [{ |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1143 b'type': b'changesetexplicit', |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1144 b'nodes': [b'abcdef...'], |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1145 }], |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1146 }, |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1147 }, |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1148 permission='pull', |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1149 # TODO censoring a file revision won't invalidate the cache. |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1150 # Figure out a way to take censoring into account when deriving |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1151 # the cache key. |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1152 cachekeyfn=makecommandcachekeyfn('filesdata', 1, allargs=True), |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1153 extracapabilitiesfn=filesdatacapabilities) |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1154 def filesdata(repo, proto, haveparents, fields, pathfilter, revisions): |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1155 # TODO This should operate on a repo that exposes obsolete changesets. There |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1156 # is a race between a client making a push that obsoletes a changeset and |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1157 # another client fetching files data for that changeset. If a client has a |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1158 # changeset, it should probably be allowed to access files data for that |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1159 # changeset. |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1160 |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1161 outgoing = resolvenodes(repo, revisions) |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1162 filematcher = makefilematcher(repo, pathfilter) |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1163 |
40941
3ed77780f4a6
wireprotov2: send linknodes to emitfilerevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40692
diff
changeset
|
1164 # path -> {fnode: linknode} |
3ed77780f4a6
wireprotov2: send linknodes to emitfilerevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40692
diff
changeset
|
1165 fnodes = collections.defaultdict(dict) |
40178
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1166 |
40942
08cfa77d7288
wireprotov2: unify file revision collection and linknode derivation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40941
diff
changeset
|
1167 # We collect the set of relevant file revisions by iterating the changeset |
08cfa77d7288
wireprotov2: unify file revision collection and linknode derivation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40941
diff
changeset
|
1168 # revisions and either walking the set of files recorded in the changeset |
08cfa77d7288
wireprotov2: unify file revision collection and linknode derivation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40941
diff
changeset
|
1169 # or by walking the manifest at that revision. There is probably room for a |
08cfa77d7288
wireprotov2: unify file revision collection and linknode derivation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40941
diff
changeset
|
1170 # storage-level API to request this data, as it can be expensive to compute |
08cfa77d7288
wireprotov2: unify file revision collection and linknode derivation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40941
diff
changeset
|
1171 # and would benefit from caching or alternate storage from what revlogs |
08cfa77d7288
wireprotov2: unify file revision collection and linknode derivation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40941
diff
changeset
|
1172 # provide. |
40178
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1173 for node in outgoing: |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1174 ctx = repo[node] |
40942
08cfa77d7288
wireprotov2: unify file revision collection and linknode derivation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40941
diff
changeset
|
1175 mctx = ctx.manifestctx() |
08cfa77d7288
wireprotov2: unify file revision collection and linknode derivation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40941
diff
changeset
|
1176 md = mctx.read() |
40178
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1177 |
40942
08cfa77d7288
wireprotov2: unify file revision collection and linknode derivation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40941
diff
changeset
|
1178 if haveparents: |
08cfa77d7288
wireprotov2: unify file revision collection and linknode derivation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40941
diff
changeset
|
1179 checkpaths = ctx.files() |
08cfa77d7288
wireprotov2: unify file revision collection and linknode derivation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40941
diff
changeset
|
1180 else: |
08cfa77d7288
wireprotov2: unify file revision collection and linknode derivation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40941
diff
changeset
|
1181 checkpaths = md.keys() |
40178
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1182 |
40942
08cfa77d7288
wireprotov2: unify file revision collection and linknode derivation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40941
diff
changeset
|
1183 for path in checkpaths: |
08cfa77d7288
wireprotov2: unify file revision collection and linknode derivation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40941
diff
changeset
|
1184 fnode = md[path] |
40178
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1185 |
40942
08cfa77d7288
wireprotov2: unify file revision collection and linknode derivation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40941
diff
changeset
|
1186 if path in fnodes and fnode in fnodes[path]: |
08cfa77d7288
wireprotov2: unify file revision collection and linknode derivation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40941
diff
changeset
|
1187 continue |
40178
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1188 |
40942
08cfa77d7288
wireprotov2: unify file revision collection and linknode derivation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40941
diff
changeset
|
1189 if not filematcher(path): |
08cfa77d7288
wireprotov2: unify file revision collection and linknode derivation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40941
diff
changeset
|
1190 continue |
08cfa77d7288
wireprotov2: unify file revision collection and linknode derivation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40941
diff
changeset
|
1191 |
08cfa77d7288
wireprotov2: unify file revision collection and linknode derivation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40941
diff
changeset
|
1192 fnodes[path].setdefault(fnode, node) |
40178
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1193 |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1194 yield { |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1195 b'totalpaths': len(fnodes), |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1196 b'totalitems': sum(len(v) for v in fnodes.values()) |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1197 } |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1198 |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1199 for path, filenodes in sorted(fnodes.items()): |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1200 try: |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1201 store = getfilestore(repo, proto, path) |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1202 except FileAccessError as e: |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1203 raise error.WireprotoCommandError(e.msg, e.args) |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1204 |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1205 yield { |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1206 b'path': path, |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1207 b'totalitems': len(filenodes), |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1208 } |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1209 |
40941
3ed77780f4a6
wireprotov2: send linknodes to emitfilerevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40692
diff
changeset
|
1210 revisions = store.emitrevisions(filenodes.keys(), |
40178
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1211 revisiondata=b'revision' in fields, |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1212 assumehaveparentrevisions=haveparents) |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1213 |
40941
3ed77780f4a6
wireprotov2: send linknodes to emitfilerevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40692
diff
changeset
|
1214 for o in emitfilerevisions(repo, path, revisions, filenodes, fields): |
40178
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1215 yield o |
46a40bce3ae0
wireprotov2: define and implement "filesdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40177
diff
changeset
|
1216 |
39815
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1217 @wireprotocommand( |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1218 'heads', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1219 args={ |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1220 'publiconly': { |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1221 'type': 'bool', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1222 'default': lambda: False, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1223 'example': False, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1224 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1225 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1226 permission='pull') |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1227 def headsv2(repo, proto, publiconly): |
37546
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
1228 if publiconly: |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
1229 repo = repo.filtered('immutable') |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
1230 |
39575
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
1231 yield repo.heads() |
37546
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
1232 |
39815
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1233 @wireprotocommand( |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1234 'known', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1235 args={ |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1236 'nodes': { |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1237 'type': 'list', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1238 'default': list, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1239 'example': [b'deadbeef'], |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1240 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1241 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1242 permission='pull') |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1243 def knownv2(repo, proto, nodes): |
37546
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
1244 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
|
1245 yield result |
37546
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
1246 |
39815
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1247 @wireprotocommand( |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1248 'listkeys', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1249 args={ |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1250 'namespace': { |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1251 'type': 'bytes', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1252 'example': b'ns', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1253 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1254 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1255 permission='pull') |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1256 def listkeysv2(repo, proto, namespace): |
37546
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
1257 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
|
1258 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
|
1259 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
|
1260 |
39575
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
1261 yield keys |
37546
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
1262 |
39815
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1263 @wireprotocommand( |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1264 'lookup', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1265 args={ |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1266 'key': { |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1267 'type': 'bytes', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1268 'example': b'foo', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1269 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1270 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1271 permission='pull') |
37546
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
1272 def lookupv2(repo, proto, key): |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
1273 key = encoding.tolocal(key) |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
1274 |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
1275 # TODO handle exception. |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
1276 node = repo.lookup(key) |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
1277 |
39575
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
1278 yield node |
37546
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
1279 |
40172
30f70d11c224
wireprotov2: advertise recommended batch size for requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40138
diff
changeset
|
1280 def manifestdatacapabilities(repo, proto): |
30f70d11c224
wireprotov2: advertise recommended batch size for requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40138
diff
changeset
|
1281 batchsize = repo.ui.configint( |
30f70d11c224
wireprotov2: advertise recommended batch size for requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40138
diff
changeset
|
1282 b'experimental', b'server.manifestdata.recommended-batch-size') |
30f70d11c224
wireprotov2: advertise recommended batch size for requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40138
diff
changeset
|
1283 |
30f70d11c224
wireprotov2: advertise recommended batch size for requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40138
diff
changeset
|
1284 return { |
30f70d11c224
wireprotov2: advertise recommended batch size for requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40138
diff
changeset
|
1285 b'recommendedbatchsize': batchsize, |
30f70d11c224
wireprotov2: advertise recommended batch size for requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40138
diff
changeset
|
1286 } |
30f70d11c224
wireprotov2: advertise recommended batch size for requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40138
diff
changeset
|
1287 |
39815
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1288 @wireprotocommand( |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1289 'manifestdata', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1290 args={ |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1291 'nodes': { |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1292 'type': 'list', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1293 'example': [b'0123456...'], |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1294 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1295 'haveparents': { |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1296 'type': 'bool', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1297 'default': lambda: False, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1298 'example': True, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1299 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1300 'fields': { |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1301 'type': 'set', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1302 'default': set, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1303 'example': {b'parents', b'revision'}, |
39818
c30faea8d02d
wireprotov2: advertise set of valid values for requestable fields
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39817
diff
changeset
|
1304 'validvalues': {b'parents', b'revision'}, |
39815
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1305 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1306 'tree': { |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1307 'type': 'bytes', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1308 'example': b'', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1309 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1310 }, |
40022
c537144fdbef
wireprotov2: support response caching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39996
diff
changeset
|
1311 permission='pull', |
40172
30f70d11c224
wireprotov2: advertise recommended batch size for requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40138
diff
changeset
|
1312 cachekeyfn=makecommandcachekeyfn('manifestdata', 1, allargs=True), |
30f70d11c224
wireprotov2: advertise recommended batch size for requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40138
diff
changeset
|
1313 extracapabilitiesfn=manifestdatacapabilities) |
39815
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1314 def manifestdata(repo, proto, haveparents, nodes, fields, tree): |
39653
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1315 store = repo.manifestlog.getstorage(tree) |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1316 |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1317 # 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
|
1318 for node in nodes: |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1319 try: |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1320 store.rev(node) |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1321 except error.LookupError: |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1322 raise error.WireprotoCommandError( |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1323 'unknown node: %s', (node,)) |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1324 |
39869
7b752bf08435
wireprotov2server: port to emitrevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39842
diff
changeset
|
1325 revisions = store.emitrevisions(nodes, |
7b752bf08435
wireprotov2server: port to emitrevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39842
diff
changeset
|
1326 revisiondata=b'revision' in fields, |
7b752bf08435
wireprotov2server: port to emitrevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39842
diff
changeset
|
1327 assumehaveparentrevisions=haveparents) |
39653
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1328 |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1329 yield { |
39869
7b752bf08435
wireprotov2server: port to emitrevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39842
diff
changeset
|
1330 b'totalitems': len(nodes), |
39653
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1331 } |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1332 |
39869
7b752bf08435
wireprotov2server: port to emitrevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39842
diff
changeset
|
1333 for revision in revisions: |
39653
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1334 d = { |
39869
7b752bf08435
wireprotov2server: port to emitrevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39842
diff
changeset
|
1335 b'node': revision.node, |
39653
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1336 } |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1337 |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1338 if b'parents' in fields: |
39869
7b752bf08435
wireprotov2server: port to emitrevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39842
diff
changeset
|
1339 d[b'parents'] = [revision.p1node, revision.p2node] |
39653
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1340 |
39819
d059cb669632
wireprotov2: allow multiple fields to follow revision maps
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39818
diff
changeset
|
1341 followingmeta = [] |
d059cb669632
wireprotov2: allow multiple fields to follow revision maps
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39818
diff
changeset
|
1342 followingdata = [] |
d059cb669632
wireprotov2: allow multiple fields to follow revision maps
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39818
diff
changeset
|
1343 |
39653
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1344 if b'revision' in fields: |
39869
7b752bf08435
wireprotov2server: port to emitrevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39842
diff
changeset
|
1345 if revision.revision is not None: |
7b752bf08435
wireprotov2server: port to emitrevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39842
diff
changeset
|
1346 followingmeta.append((b'revision', len(revision.revision))) |
7b752bf08435
wireprotov2server: port to emitrevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39842
diff
changeset
|
1347 followingdata.append(revision.revision) |
39653
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1348 else: |
39869
7b752bf08435
wireprotov2server: port to emitrevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39842
diff
changeset
|
1349 d[b'deltabasenode'] = revision.basenode |
7b752bf08435
wireprotov2server: port to emitrevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39842
diff
changeset
|
1350 followingmeta.append((b'delta', len(revision.delta))) |
7b752bf08435
wireprotov2server: port to emitrevisions()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39842
diff
changeset
|
1351 followingdata.append(revision.delta) |
39819
d059cb669632
wireprotov2: allow multiple fields to follow revision maps
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39818
diff
changeset
|
1352 |
d059cb669632
wireprotov2: allow multiple fields to follow revision maps
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39818
diff
changeset
|
1353 if followingmeta: |
d059cb669632
wireprotov2: allow multiple fields to follow revision maps
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39818
diff
changeset
|
1354 d[b'fieldsfollowing'] = followingmeta |
39653
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1355 |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1356 yield d |
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1357 |
39819
d059cb669632
wireprotov2: allow multiple fields to follow revision maps
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39818
diff
changeset
|
1358 for extra in followingdata: |
d059cb669632
wireprotov2: allow multiple fields to follow revision maps
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39818
diff
changeset
|
1359 yield extra |
39653
c7a7c7e844e5
wireprotov2: define and implement "manifestdata" command
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39652
diff
changeset
|
1360 |
39815
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1361 @wireprotocommand( |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1362 'pushkey', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1363 args={ |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1364 'namespace': { |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1365 'type': 'bytes', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1366 'example': b'ns', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1367 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1368 'key': { |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1369 'type': 'bytes', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1370 'example': b'key', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1371 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1372 'old': { |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1373 'type': 'bytes', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1374 'example': b'old', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1375 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1376 'new': { |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1377 'type': 'bytes', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1378 'example': 'new', |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1379 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1380 }, |
0b61d21f05cc
wireprotov2: declare command arguments richly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39657
diff
changeset
|
1381 permission='push') |
37546
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
1382 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
|
1383 # 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
|
1384 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
|
1385 encoding.tolocal(key), |
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
1386 encoding.tolocal(old), |
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39467
diff
changeset
|
1387 encoding.tolocal(new)) |
40329
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1388 |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1389 |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1390 @wireprotocommand( |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1391 'rawstorefiledata', |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1392 args={ |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1393 'files': { |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1394 'type': 'list', |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1395 'example': [b'changelog', b'manifestlog'], |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1396 }, |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1397 'pathfilter': { |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1398 'type': 'list', |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1399 'default': lambda: None, |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1400 'example': {b'include': [b'path:tests']}, |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1401 }, |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1402 }, |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1403 permission='pull') |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1404 def rawstorefiledata(repo, proto, files, pathfilter): |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1405 if not streamclone.allowservergeneration(repo): |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1406 raise error.WireprotoCommandError(b'stream clone is disabled') |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1407 |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1408 # TODO support dynamically advertising what store files "sets" are |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1409 # available. For now, we support changelog, manifestlog, and files. |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1410 files = set(files) |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1411 allowedfiles = {b'changelog', b'manifestlog'} |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1412 |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1413 unsupported = files - allowedfiles |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1414 if unsupported: |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1415 raise error.WireprotoCommandError(b'unknown file type: %s', |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1416 (b', '.join(sorted(unsupported)),)) |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1417 |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1418 with repo.lock(): |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1419 topfiles = list(repo.store.topfiles()) |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1420 |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1421 sendfiles = [] |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1422 totalsize = 0 |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1423 |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1424 # TODO this is a bunch of storage layer interface abstractions because |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1425 # it assumes revlogs. |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1426 for name, encodedname, size in topfiles: |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1427 if b'changelog' in files and name.startswith(b'00changelog'): |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1428 pass |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1429 elif b'manifestlog' in files and name.startswith(b'00manifest'): |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1430 pass |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1431 else: |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1432 continue |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1433 |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1434 sendfiles.append((b'store', name, size)) |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1435 totalsize += size |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1436 |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1437 yield { |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1438 b'filecount': len(sendfiles), |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1439 b'totalsize': totalsize, |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1440 } |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1441 |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1442 for location, name, size in sendfiles: |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1443 yield { |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1444 b'location': location, |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1445 b'path': name, |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1446 b'size': size, |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1447 } |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1448 |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1449 # We have to use a closure for this to ensure the context manager is |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1450 # closed only after sending the final chunk. |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1451 def getfiledata(): |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1452 with repo.svfs(name, 'rb', auditpath=False) as fh: |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1453 for chunk in util.filechunkiter(fh, limit=size): |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1454 yield chunk |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1455 |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1456 yield wireprototypes.indefinitebytestringresponse( |
ed55a0077490
wireprotov2: implement command for retrieving raw store files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40178
diff
changeset
|
1457 getfiledata()) |