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