Mercurial > hg
annotate mercurial/wireprotov2peer.py @ 37721:f7673845b167
wireprotov2: decode responses to their expected types
Callers of established wire protocol commands expect the
response from that command to be decoded into a data structure.
It's not very useful if callers get back a stream of bytes and
don't know how they should be interpreted - especially since that
stream of bytes varies by wire protocol and even the transport
within that protocol version.
This commit establishes decoding functions for various command
responses so callers of those commands get the response type
they expect.
In theory, this should make the version 2 HTTP peer usable for
various operations. But I haven't tested to confirm.
Differential Revision: https://phab.mercurial-scm.org/D3381
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Sat, 14 Apr 2018 11:49:06 -0700 |
parents | d715a85003c8 |
children | 89a16704114c |
rev | line source |
---|---|
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
1 # wireprotov2peer.py - client side code for wire protocol version 2 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
2 # |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
3 # Copyright 2018 Gregory Szorc <gregory.szorc@gmail.com> |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
4 # |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
5 # This software may be used and distributed according to the terms of the |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
6 # GNU General Public License version 2 or any later version. |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
7 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
8 from __future__ import absolute_import |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
9 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
10 from .i18n import _ |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
11 from .thirdparty import ( |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
12 cbor, |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
13 ) |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
14 from . import ( |
37721
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
15 encoding, |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
16 error, |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
17 util, |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
18 wireprotoframing, |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
19 ) |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
20 |
37720
d715a85003c8
wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37719
diff
changeset
|
21 class commandresponse(object): |
d715a85003c8
wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37719
diff
changeset
|
22 """Represents the response to a command request.""" |
d715a85003c8
wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37719
diff
changeset
|
23 |
d715a85003c8
wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37719
diff
changeset
|
24 def __init__(self, requestid, command): |
d715a85003c8
wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37719
diff
changeset
|
25 self.requestid = requestid |
d715a85003c8
wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37719
diff
changeset
|
26 self.command = command |
d715a85003c8
wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37719
diff
changeset
|
27 |
d715a85003c8
wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37719
diff
changeset
|
28 self.cbor = False |
d715a85003c8
wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37719
diff
changeset
|
29 self.b = util.bytesio() |
d715a85003c8
wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37719
diff
changeset
|
30 |
d715a85003c8
wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37719
diff
changeset
|
31 def cborobjects(self): |
d715a85003c8
wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37719
diff
changeset
|
32 """Obtain decoded CBOR objects from this response.""" |
d715a85003c8
wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37719
diff
changeset
|
33 size = self.b.tell() |
d715a85003c8
wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37719
diff
changeset
|
34 self.b.seek(0) |
d715a85003c8
wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37719
diff
changeset
|
35 |
d715a85003c8
wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37719
diff
changeset
|
36 decoder = cbor.CBORDecoder(self.b) |
d715a85003c8
wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37719
diff
changeset
|
37 |
d715a85003c8
wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37719
diff
changeset
|
38 while self.b.tell() < size: |
d715a85003c8
wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37719
diff
changeset
|
39 yield decoder.decode() |
d715a85003c8
wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37719
diff
changeset
|
40 |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
41 class clienthandler(object): |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
42 """Object to handle higher-level client activities. |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
43 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
44 The ``clientreactor`` is used to hold low-level state about the frame-based |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
45 protocol, such as which requests and streams are active. This type is used |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
46 for higher-level operations, such as reading frames from a socket, exposing |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
47 and managing a higher-level primitive for representing command responses, |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
48 etc. This class is what peers should probably use to bridge wire activity |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
49 with the higher-level peer API. |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
50 """ |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
51 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
52 def __init__(self, ui, clientreactor): |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
53 self._ui = ui |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
54 self._reactor = clientreactor |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
55 self._requests = {} |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
56 self._futures = {} |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
57 self._responses = {} |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
58 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
59 def callcommand(self, command, args, f): |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
60 """Register a request to call a command. |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
61 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
62 Returns an iterable of frames that should be sent over the wire. |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
63 """ |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
64 request, action, meta = self._reactor.callcommand(command, args) |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
65 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
66 if action != 'noop': |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
67 raise error.ProgrammingError('%s not yet supported' % action) |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
68 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
69 rid = request.requestid |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
70 self._requests[rid] = request |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
71 self._futures[rid] = f |
37720
d715a85003c8
wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37719
diff
changeset
|
72 self._responses[rid] = commandresponse(rid, command) |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
73 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
74 return iter(()) |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
75 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
76 def flushcommands(self): |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
77 """Flush all queued commands. |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
78 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
79 Returns an iterable of frames that should be sent over the wire. |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
80 """ |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
81 action, meta = self._reactor.flushcommands() |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
82 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
83 if action != 'sendframes': |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
84 raise error.ProgrammingError('%s not yet supported' % action) |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
85 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
86 return meta['framegen'] |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
87 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
88 def readframe(self, fh): |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
89 """Attempt to read and process a frame. |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
90 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
91 Returns None if no frame was read. Presumably this means EOF. |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
92 """ |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
93 frame = wireprotoframing.readframe(fh) |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
94 if frame is None: |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
95 # TODO tell reactor? |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
96 return |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
97 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
98 self._ui.note(_('received %r\n') % frame) |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
99 self._processframe(frame) |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
100 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
101 return True |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
102 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
103 def _processframe(self, frame): |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
104 """Process a single read frame.""" |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
105 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
106 action, meta = self._reactor.onframerecv(frame) |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
107 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
108 if action == 'error': |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
109 e = error.RepoError(meta['message']) |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
110 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
111 if frame.requestid in self._futures: |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
112 self._futures[frame.requestid].set_exception(e) |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
113 else: |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
114 raise e |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
115 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
116 if frame.requestid not in self._requests: |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
117 raise error.ProgrammingError( |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
118 'received frame for unknown request; this is either a bug in ' |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
119 'the clientreactor not screening for this or this instance was ' |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
120 'never told about this request: %r' % frame) |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
121 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
122 response = self._responses[frame.requestid] |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
123 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
124 if action == 'responsedata': |
37720
d715a85003c8
wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37719
diff
changeset
|
125 response.b.write(meta['data']) |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
126 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
127 if meta['cbor']: |
37720
d715a85003c8
wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37719
diff
changeset
|
128 response.cbor = True |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
129 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
130 if meta['eos']: |
37721
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
131 # If the command has a decoder, resolve the future to the |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
132 # decoded value. Otherwise resolve to the rich response object. |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
133 decoder = COMMAND_DECODERS.get(response.command) |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
134 |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
135 result = decoder(response) if decoder else response |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
136 |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
137 self._futures[frame.requestid].set_result(result) |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
138 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
139 del self._requests[frame.requestid] |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
140 del self._futures[frame.requestid] |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
141 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
142 else: |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
143 raise error.ProgrammingError( |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
144 'unhandled action from clientreactor: %s' % action) |
37721
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
145 |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
146 def decodebranchmap(resp): |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
147 # Response should be a single CBOR map of branch name to array of nodes. |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
148 bm = next(resp.cborobjects()) |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
149 |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
150 return {encoding.tolocal(k): v for k, v in bm.items()} |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
151 |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
152 def decodeheads(resp): |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
153 # Array of node bytestrings. |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
154 return next(resp.cborobjects()) |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
155 |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
156 def decodeknown(resp): |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
157 # Bytestring where each byte is a 0 or 1. |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
158 raw = next(resp.cborobjects()) |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
159 |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
160 return [True if c == '1' else False for c in raw] |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
161 |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
162 def decodelistkeys(resp): |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
163 # Map with bytestring keys and values. |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
164 return next(resp.cborobjects()) |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
165 |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
166 def decodelookup(resp): |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
167 return next(resp.cborobjects()) |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
168 |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
169 def decodepushkey(resp): |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
170 return next(resp.cborobjects()) |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
171 |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
172 COMMAND_DECODERS = { |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
173 'branchmap': decodebranchmap, |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
174 'heads': decodeheads, |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
175 'known': decodeknown, |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
176 'listkeys': decodelistkeys, |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
177 'lookup': decodelookup, |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
178 'pushkey': decodepushkey, |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
179 } |