Mercurial > hg
annotate mercurial/wireprotov2peer.py @ 41307:e8273eaa0726 stable
ui: inline _writenobuf() into write() due to performance issue
I'll remove redundant conditions later in this series.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Thu, 24 Jan 2019 21:35:55 +0900 |
parents | 15a643304728 |
children | e6c1c6478d04 |
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 |
39561
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
10 import threading |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
11 |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
12 from .i18n import _ |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
13 from . import ( |
37721
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
14 encoding, |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
15 error, |
40026
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
16 pycompat, |
40024
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
17 sslutil, |
40026
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
18 url as urlmod, |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
19 util, |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
20 wireprotoframing, |
40026
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
21 wireprototypes, |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
22 ) |
39450
9f51fd22ed50
wireprotov2peer: use our CBOR decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39438
diff
changeset
|
23 from .utils import ( |
9f51fd22ed50
wireprotov2peer: use our CBOR decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39438
diff
changeset
|
24 cborutil, |
9f51fd22ed50
wireprotov2peer: use our CBOR decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39438
diff
changeset
|
25 ) |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
26 |
37725
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
27 def formatrichmessage(atoms): |
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
28 """Format an encoded message from the framing protocol.""" |
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
29 |
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
30 chunks = [] |
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
31 |
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
32 for atom in atoms: |
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
33 msg = _(atom[b'msg']) |
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
34 |
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
35 if b'args' in atom: |
39486
43d92d68ac88
wireprotov2peer: properly format errors
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39485
diff
changeset
|
36 msg = msg % tuple(atom[b'args']) |
37725
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
37 |
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
38 chunks.append(msg) |
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
39 |
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
40 return b''.join(chunks) |
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
41 |
40024
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
42 SUPPORTED_REDIRECT_PROTOCOLS = { |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
43 b'http', |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
44 b'https', |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
45 } |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
46 |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
47 SUPPORTED_CONTENT_HASHES = { |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
48 b'sha1', |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
49 b'sha256', |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
50 } |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
51 |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
52 def redirecttargetsupported(ui, target): |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
53 """Determine whether a redirect target entry is supported. |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
54 |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
55 ``target`` should come from the capabilities data structure emitted by |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
56 the server. |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
57 """ |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
58 if target.get(b'protocol') not in SUPPORTED_REDIRECT_PROTOCOLS: |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
59 ui.note(_('(remote redirect target %s uses unsupported protocol: %s)\n') |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
60 % (target[b'name'], target.get(b'protocol', b''))) |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
61 return False |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
62 |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
63 if target.get(b'snirequired') and not sslutil.hassni: |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
64 ui.note(_('(redirect target %s requires SNI, which is unsupported)\n') % |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
65 target[b'name']) |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
66 return False |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
67 |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
68 if b'tlsversions' in target: |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
69 tlsversions = set(target[b'tlsversions']) |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
70 supported = set() |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
71 |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
72 for v in sslutil.supportedprotocols: |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
73 assert v.startswith(b'tls') |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
74 supported.add(v[3:]) |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
75 |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
76 if not tlsversions & supported: |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
77 ui.note(_('(remote redirect target %s requires unsupported TLS ' |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
78 'versions: %s)\n') % ( |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
79 target[b'name'], b', '.join(sorted(tlsversions)))) |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
80 return False |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
81 |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
82 ui.note(_('(remote redirect target %s is compatible)\n') % target[b'name']) |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
83 |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
84 return True |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
85 |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
86 def supportedredirects(ui, apidescriptor): |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
87 """Resolve the "redirect" command request key given an API descriptor. |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
88 |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
89 Given an API descriptor returned by the server, returns a data structure |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
90 that can be used in hte "redirect" field of command requests to advertise |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
91 support for compatible redirect targets. |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
92 |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
93 Returns None if no redirect targets are remotely advertised or if none are |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
94 supported. |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
95 """ |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
96 if not apidescriptor or b'redirect' not in apidescriptor: |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
97 return None |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
98 |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
99 targets = [t[b'name'] for t in apidescriptor[b'redirect'][b'targets'] |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
100 if redirecttargetsupported(ui, t)] |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
101 |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
102 hashes = [h for h in apidescriptor[b'redirect'][b'hashes'] |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
103 if h in SUPPORTED_CONTENT_HASHES] |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
104 |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
105 return { |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
106 b'targets': targets, |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
107 b'hashes': hashes, |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
108 } |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
109 |
37720
d715a85003c8
wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37719
diff
changeset
|
110 class commandresponse(object): |
39561
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
111 """Represents the response to a command request. |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
112 |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
113 Instances track the state of the command and hold its results. |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
114 |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
115 An external entity is required to update the state of the object when |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
116 events occur. |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
117 """ |
37720
d715a85003c8
wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37719
diff
changeset
|
118 |
40026
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
119 def __init__(self, requestid, command, fromredirect=False): |
37720
d715a85003c8
wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37719
diff
changeset
|
120 self.requestid = requestid |
d715a85003c8
wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37719
diff
changeset
|
121 self.command = command |
40026
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
122 self.fromredirect = fromredirect |
37720
d715a85003c8
wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37719
diff
changeset
|
123 |
39561
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
124 # Whether all remote input related to this command has been |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
125 # received. |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
126 self._inputcomplete = False |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
127 |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
128 # We have a lock that is acquired when important object state is |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
129 # mutated. This is to prevent race conditions between 1 thread |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
130 # sending us new data and another consuming it. |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
131 self._lock = threading.RLock() |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
132 |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
133 # An event is set when state of the object changes. This event |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
134 # is waited on by the generator emitting objects. |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
135 self._serviceable = threading.Event() |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
136 |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
137 self._pendingevents = [] |
40137
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
138 self._pendingerror = None |
39561
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
139 self._decoder = cborutil.bufferingdecoder() |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
140 self._seeninitial = False |
40026
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
141 self._redirect = None |
39561
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
142 |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
143 def _oninputcomplete(self): |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
144 with self._lock: |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
145 self._inputcomplete = True |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
146 self._serviceable.set() |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
147 |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
148 def _onresponsedata(self, data): |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
149 available, readcount, wanted = self._decoder.decode(data) |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
150 |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
151 if not available: |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
152 return |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
153 |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
154 with self._lock: |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
155 for o in self._decoder.getavailable(): |
40026
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
156 if not self._seeninitial and not self.fromredirect: |
39561
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
157 self._handleinitial(o) |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
158 continue |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
159 |
40026
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
160 # We should never see an object after a content redirect, |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
161 # as the spec says the main status object containing the |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
162 # content redirect is the only object in the stream. Fail |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
163 # if we see a misbehaving server. |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
164 if self._redirect: |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
165 raise error.Abort(_('received unexpected response data ' |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
166 'after content redirect; the remote is ' |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
167 'buggy')) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
168 |
39561
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
169 self._pendingevents.append(o) |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
170 |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
171 self._serviceable.set() |
37720
d715a85003c8
wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37719
diff
changeset
|
172 |
40137
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
173 def _onerror(self, e): |
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
174 self._pendingerror = e |
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
175 |
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
176 with self._lock: |
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
177 self._serviceable.set() |
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
178 |
39561
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
179 def _handleinitial(self, o): |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
180 self._seeninitial = True |
40024
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
181 if o[b'status'] == b'ok': |
39561
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
182 return |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
183 |
40024
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
184 elif o[b'status'] == b'redirect': |
40026
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
185 l = o[b'location'] |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
186 self._redirect = wireprototypes.alternatelocationresponse( |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
187 url=l[b'url'], |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
188 mediatype=l[b'mediatype'], |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
189 size=l.get(b'size'), |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
190 fullhashes=l.get(b'fullhashes'), |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
191 fullhashseed=l.get(b'fullhashseed'), |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
192 serverdercerts=l.get(b'serverdercerts'), |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
193 servercadercerts=l.get(b'servercadercerts')) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
194 return |
40024
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
195 |
39561
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
196 atoms = [{'msg': o[b'error'][b'message']}] |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
197 if b'args' in o[b'error']: |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
198 atoms[0]['args'] = o[b'error'][b'args'] |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
199 |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
200 raise error.RepoError(formatrichmessage(atoms)) |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
201 |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
202 def objects(self): |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
203 """Obtained decoded objects from this response. |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
204 |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
205 This is a generator of data structures that were decoded from the |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
206 command response. |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
207 |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
208 Obtaining the next member of the generator may block due to waiting |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
209 on external data to become available. |
37720
d715a85003c8
wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37719
diff
changeset
|
210 |
39561
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
211 If the server encountered an error in the middle of serving the data |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
212 or if another error occurred, an exception may be raised when |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
213 advancing the generator. |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
214 """ |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
215 while True: |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
216 # TODO this can infinite loop if self._inputcomplete is never |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
217 # set. We likely want to tie the lifetime of this object/state |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
218 # to that of the background thread receiving frames and updating |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
219 # our state. |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
220 self._serviceable.wait(1.0) |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
221 |
40137
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
222 if self._pendingerror: |
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
223 raise self._pendingerror |
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
224 |
39561
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
225 with self._lock: |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
226 self._serviceable.clear() |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
227 |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
228 # Make copies because objects could be mutated during |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
229 # iteration. |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
230 stop = self._inputcomplete |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
231 pending = list(self._pendingevents) |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
232 self._pendingevents[:] = [] |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
233 |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
234 for o in pending: |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
235 yield o |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
236 |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
237 if stop: |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
238 break |
37720
d715a85003c8
wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37719
diff
changeset
|
239 |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
240 class clienthandler(object): |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
241 """Object to handle higher-level client activities. |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
242 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
243 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
|
244 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
|
245 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
|
246 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
|
247 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
|
248 with the higher-level peer API. |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
249 """ |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
250 |
40026
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
251 def __init__(self, ui, clientreactor, opener=None, |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
252 requestbuilder=util.urlreq.request): |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
253 self._ui = ui |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
254 self._reactor = clientreactor |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
255 self._requests = {} |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
256 self._futures = {} |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
257 self._responses = {} |
40026
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
258 self._redirects = [] |
40019
f5a05bb48116
wireprotov2: change name and behavior of readframe()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39561
diff
changeset
|
259 self._frameseof = False |
40026
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
260 self._opener = opener or urlmod.opener(ui) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
261 self._requestbuilder = requestbuilder |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
262 |
40024
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
263 def callcommand(self, command, args, f, redirect=None): |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
264 """Register a request to call a command. |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
265 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
266 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
|
267 """ |
40024
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
268 request, action, meta = self._reactor.callcommand(command, args, |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
269 redirect=redirect) |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
270 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
271 if action != 'noop': |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
272 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
|
273 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
274 rid = request.requestid |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
275 self._requests[rid] = request |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
276 self._futures[rid] = f |
39561
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
277 # TODO we need some kind of lifetime on response instances otherwise |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
278 # objects() may deadlock. |
37720
d715a85003c8
wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37719
diff
changeset
|
279 self._responses[rid] = commandresponse(rid, command) |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
280 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
281 return iter(()) |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
282 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
283 def flushcommands(self): |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
284 """Flush all queued commands. |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
285 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
286 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
|
287 """ |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
288 action, meta = self._reactor.flushcommands() |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
289 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
290 if action != 'sendframes': |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
291 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
|
292 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
293 return meta['framegen'] |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
294 |
40019
f5a05bb48116
wireprotov2: change name and behavior of readframe()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39561
diff
changeset
|
295 def readdata(self, framefh): |
f5a05bb48116
wireprotov2: change name and behavior of readframe()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39561
diff
changeset
|
296 """Attempt to read data and do work. |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
297 |
40019
f5a05bb48116
wireprotov2: change name and behavior of readframe()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39561
diff
changeset
|
298 Returns None if no data was read. Presumably this means we're |
f5a05bb48116
wireprotov2: change name and behavior of readframe()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39561
diff
changeset
|
299 done with all read I/O. |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
300 """ |
40019
f5a05bb48116
wireprotov2: change name and behavior of readframe()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39561
diff
changeset
|
301 if not self._frameseof: |
f5a05bb48116
wireprotov2: change name and behavior of readframe()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39561
diff
changeset
|
302 frame = wireprotoframing.readframe(framefh) |
f5a05bb48116
wireprotov2: change name and behavior of readframe()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39561
diff
changeset
|
303 if frame is None: |
f5a05bb48116
wireprotov2: change name and behavior of readframe()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39561
diff
changeset
|
304 # TODO tell reactor? |
f5a05bb48116
wireprotov2: change name and behavior of readframe()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39561
diff
changeset
|
305 self._frameseof = True |
f5a05bb48116
wireprotov2: change name and behavior of readframe()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39561
diff
changeset
|
306 else: |
f5a05bb48116
wireprotov2: change name and behavior of readframe()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39561
diff
changeset
|
307 self._ui.note(_('received %r\n') % frame) |
f5a05bb48116
wireprotov2: change name and behavior of readframe()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39561
diff
changeset
|
308 self._processframe(frame) |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
309 |
40026
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
310 # Also try to read the first redirect. |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
311 if self._redirects: |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
312 if not self._processredirect(*self._redirects[0]): |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
313 self._redirects.pop(0) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
314 |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
315 if self._frameseof and not self._redirects: |
40019
f5a05bb48116
wireprotov2: change name and behavior of readframe()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39561
diff
changeset
|
316 return None |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
317 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
318 return True |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
319 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
320 def _processframe(self, frame): |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
321 """Process a single read frame.""" |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
322 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
323 action, meta = self._reactor.onframerecv(frame) |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
324 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
325 if action == 'error': |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
326 e = error.RepoError(meta['message']) |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
327 |
39561
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
328 if frame.requestid in self._responses: |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
329 self._responses[frame.requestid]._oninputcomplete() |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
330 |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
331 if frame.requestid in self._futures: |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
332 self._futures[frame.requestid].set_exception(e) |
39561
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
333 del self._futures[frame.requestid] |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
334 else: |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
335 raise e |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
336 |
39559
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39486
diff
changeset
|
337 return |
40134
cfeba1aafb9d
wireprotov2: handle noop action
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40026
diff
changeset
|
338 elif action == 'noop': |
cfeba1aafb9d
wireprotov2: handle noop action
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40026
diff
changeset
|
339 return |
40139
17223d8e7d75
wireprotov2: raise ProgrammingError on unknown action
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40137
diff
changeset
|
340 elif action == 'responsedata': |
17223d8e7d75
wireprotov2: raise ProgrammingError on unknown action
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40137
diff
changeset
|
341 # Handled below. |
17223d8e7d75
wireprotov2: raise ProgrammingError on unknown action
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40137
diff
changeset
|
342 pass |
17223d8e7d75
wireprotov2: raise ProgrammingError on unknown action
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40137
diff
changeset
|
343 else: |
17223d8e7d75
wireprotov2: raise ProgrammingError on unknown action
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40137
diff
changeset
|
344 raise error.ProgrammingError('action not handled: %s' % action) |
39559
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39486
diff
changeset
|
345 |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
346 if frame.requestid not in self._requests: |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
347 raise error.ProgrammingError( |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
348 '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
|
349 '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
|
350 'never told about this request: %r' % frame) |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
351 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
352 response = self._responses[frame.requestid] |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
353 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
354 if action == 'responsedata': |
39485
42bc1c70a6b8
wireprotov2peer: report exceptions in frame handling against request future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39450
diff
changeset
|
355 # Any failures processing this frame should bubble up to the |
42bc1c70a6b8
wireprotov2peer: report exceptions in frame handling against request future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39450
diff
changeset
|
356 # future tracking the request. |
42bc1c70a6b8
wireprotov2peer: report exceptions in frame handling against request future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39450
diff
changeset
|
357 try: |
42bc1c70a6b8
wireprotov2peer: report exceptions in frame handling against request future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39450
diff
changeset
|
358 self._processresponsedata(frame, meta, response) |
42bc1c70a6b8
wireprotov2peer: report exceptions in frame handling against request future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39450
diff
changeset
|
359 except BaseException as e: |
40137
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
360 # If an exception occurs before the future is resolved, |
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
361 # fail the future. Otherwise, we stuff the exception on |
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
362 # the response object so it can be raised during objects() |
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
363 # iteration. If nothing is consuming objects(), we could |
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
364 # silently swallow this exception. That's a risk we'll have to |
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
365 # take. |
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
366 if frame.requestid in self._futures: |
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
367 self._futures[frame.requestid].set_exception(e) |
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
368 del self._futures[frame.requestid] |
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
369 response._oninputcomplete() |
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
370 else: |
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
371 response._onerror(e) |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
372 else: |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
373 raise error.ProgrammingError( |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
374 '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
|
375 |
39438
c734a5c82f38
wireprotov2peer: split responsedata handling into separate function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39435
diff
changeset
|
376 def _processresponsedata(self, frame, meta, response): |
39561
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
377 # This can raise. The caller can handle it. |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
378 response._onresponsedata(meta['data']) |
39438
c734a5c82f38
wireprotov2peer: split responsedata handling into separate function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39435
diff
changeset
|
379 |
40724
15a643304728
wireprotov2peer: wait for initial object before resolving future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40723
diff
changeset
|
380 # We need to be careful about resolving futures prematurely. If a |
15a643304728
wireprotov2peer: wait for initial object before resolving future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40723
diff
changeset
|
381 # response is a redirect response, resolving the future before the |
15a643304728
wireprotov2peer: wait for initial object before resolving future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40723
diff
changeset
|
382 # redirect is processed would result in the consumer seeing an |
15a643304728
wireprotov2peer: wait for initial object before resolving future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40723
diff
changeset
|
383 # empty stream of objects, since they'd be consuming our |
15a643304728
wireprotov2peer: wait for initial object before resolving future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40723
diff
changeset
|
384 # response.objects() instead of the redirect's response.objects(). |
15a643304728
wireprotov2peer: wait for initial object before resolving future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40723
diff
changeset
|
385 # |
15a643304728
wireprotov2peer: wait for initial object before resolving future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40723
diff
changeset
|
386 # Our strategy is to not resolve/finish the request until either |
15a643304728
wireprotov2peer: wait for initial object before resolving future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40723
diff
changeset
|
387 # EOS occurs or until the initial response object is fully received. |
40026
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
388 |
40724
15a643304728
wireprotov2peer: wait for initial object before resolving future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40723
diff
changeset
|
389 # Always react to eos. |
39438
c734a5c82f38
wireprotov2peer: split responsedata handling into separate function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39435
diff
changeset
|
390 if meta['eos']: |
39561
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
391 response._oninputcomplete() |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
392 del self._requests[frame.requestid] |
39438
c734a5c82f38
wireprotov2peer: split responsedata handling into separate function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39435
diff
changeset
|
393 |
40724
15a643304728
wireprotov2peer: wait for initial object before resolving future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40723
diff
changeset
|
394 # Not EOS but we haven't decoded the initial response object yet. |
15a643304728
wireprotov2peer: wait for initial object before resolving future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40723
diff
changeset
|
395 # Return and wait for more data. |
15a643304728
wireprotov2peer: wait for initial object before resolving future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40723
diff
changeset
|
396 elif not response._seeninitial: |
15a643304728
wireprotov2peer: wait for initial object before resolving future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40723
diff
changeset
|
397 return |
40026
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
398 |
40724
15a643304728
wireprotov2peer: wait for initial object before resolving future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40723
diff
changeset
|
399 # The specification says no objects should follow the initial/redirect |
15a643304728
wireprotov2peer: wait for initial object before resolving future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40723
diff
changeset
|
400 # object. So it should be safe to handle the redirect object if one is |
15a643304728
wireprotov2peer: wait for initial object before resolving future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40723
diff
changeset
|
401 # decoded, without having to wait for EOS. |
15a643304728
wireprotov2peer: wait for initial object before resolving future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40723
diff
changeset
|
402 if response._redirect: |
15a643304728
wireprotov2peer: wait for initial object before resolving future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40723
diff
changeset
|
403 self._followredirect(frame.requestid, response._redirect) |
40026
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
404 return |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
405 |
39561
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
406 # If the command has a decoder, we wait until all input has been |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
407 # received before resolving the future. Otherwise we resolve the |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
408 # future immediately. |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
409 if frame.requestid not in self._futures: |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
410 return |
39438
c734a5c82f38
wireprotov2peer: split responsedata handling into separate function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39435
diff
changeset
|
411 |
39561
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
412 if response.command not in COMMAND_DECODERS: |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
413 self._futures[frame.requestid].set_result(response.objects()) |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
414 del self._futures[frame.requestid] |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
415 elif response._inputcomplete: |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
416 decoded = COMMAND_DECODERS[response.command](response.objects()) |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
417 self._futures[frame.requestid].set_result(decoded) |
39438
c734a5c82f38
wireprotov2peer: split responsedata handling into separate function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39435
diff
changeset
|
418 del self._futures[frame.requestid] |
c734a5c82f38
wireprotov2peer: split responsedata handling into separate function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39435
diff
changeset
|
419 |
40026
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
420 def _followredirect(self, requestid, redirect): |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
421 """Called to initiate redirect following for a request.""" |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
422 self._ui.note(_('(following redirect to %s)\n') % redirect.url) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
423 |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
424 # TODO handle framed responses. |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
425 if redirect.mediatype != b'application/mercurial-cbor': |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
426 raise error.Abort(_('cannot handle redirects for the %s media type') |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
427 % redirect.mediatype) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
428 |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
429 if redirect.fullhashes: |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
430 self._ui.warn(_('(support for validating hashes on content ' |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
431 'redirects not supported)\n')) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
432 |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
433 if redirect.serverdercerts or redirect.servercadercerts: |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
434 self._ui.warn(_('(support for pinning server certificates on ' |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
435 'content redirects not supported)\n')) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
436 |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
437 headers = { |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
438 r'Accept': redirect.mediatype, |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
439 } |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
440 |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
441 req = self._requestbuilder(pycompat.strurl(redirect.url), None, headers) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
442 |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
443 try: |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
444 res = self._opener.open(req) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
445 except util.urlerr.httperror as e: |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
446 if e.code == 401: |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
447 raise error.Abort(_('authorization failed')) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
448 raise |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
449 except util.httplib.HTTPException as e: |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
450 self._ui.debug('http error requesting %s\n' % req.get_full_url()) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
451 self._ui.traceback() |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
452 raise IOError(None, e) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
453 |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
454 urlmod.wrapresponse(res) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
455 |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
456 # The existing response object is associated with frame data. Rather |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
457 # than try to normalize its state, just create a new object. |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
458 oldresponse = self._responses[requestid] |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
459 self._responses[requestid] = commandresponse(requestid, |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
460 oldresponse.command, |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
461 fromredirect=True) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
462 |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
463 self._redirects.append((requestid, res)) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
464 |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
465 def _processredirect(self, rid, res): |
40723
94b0d0f996e1
wireprotov2peer: always return a bool from _processredirect()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40139
diff
changeset
|
466 """Called to continue processing a response from a redirect. |
94b0d0f996e1
wireprotov2peer: always return a bool from _processredirect()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40139
diff
changeset
|
467 |
94b0d0f996e1
wireprotov2peer: always return a bool from _processredirect()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40139
diff
changeset
|
468 Returns a bool indicating if the redirect is still serviceable. |
94b0d0f996e1
wireprotov2peer: always return a bool from _processredirect()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40139
diff
changeset
|
469 """ |
40026
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
470 response = self._responses[rid] |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
471 |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
472 try: |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
473 data = res.read(32768) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
474 response._onresponsedata(data) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
475 |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
476 # We're at end of stream. |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
477 if not data: |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
478 response._oninputcomplete() |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
479 |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
480 if rid not in self._futures: |
40723
94b0d0f996e1
wireprotov2peer: always return a bool from _processredirect()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40139
diff
changeset
|
481 return bool(data) |
40026
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
482 |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
483 if response.command not in COMMAND_DECODERS: |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
484 self._futures[rid].set_result(response.objects()) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
485 del self._futures[rid] |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
486 elif response._inputcomplete: |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
487 decoded = COMMAND_DECODERS[response.command](response.objects()) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
488 self._futures[rid].set_result(decoded) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
489 del self._futures[rid] |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
490 |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
491 return bool(data) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
492 |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
493 except BaseException as e: |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
494 self._futures[rid].set_exception(e) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
495 del self._futures[rid] |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
496 response._oninputcomplete() |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
497 return False |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
498 |
37725
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
499 def decodebranchmap(objs): |
37721
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
500 # Response should be a single CBOR map of branch name to array of nodes. |
37725
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
501 bm = next(objs) |
37721
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
502 |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
503 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
|
504 |
37725
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
505 def decodeheads(objs): |
37721
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
506 # Array of node bytestrings. |
37725
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
507 return next(objs) |
37721
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
508 |
37725
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
509 def decodeknown(objs): |
37721
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
510 # Bytestring where each byte is a 0 or 1. |
37725
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
511 raw = next(objs) |
37721
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
512 |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
513 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
|
514 |
37725
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
515 def decodelistkeys(objs): |
37721
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
516 # Map with bytestring keys and values. |
37725
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
517 return next(objs) |
37721
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
518 |
37725
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
519 def decodelookup(objs): |
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
520 return next(objs) |
37721
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
521 |
37725
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
522 def decodepushkey(objs): |
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
523 return next(objs) |
37721
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
524 |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
525 COMMAND_DECODERS = { |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
526 'branchmap': decodebranchmap, |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
527 'heads': decodeheads, |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
528 'known': decodeknown, |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
529 'listkeys': decodelistkeys, |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
530 'lookup': decodelookup, |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
531 'pushkey': decodepushkey, |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
532 } |