annotate mercurial/wireprotov2peer.py @ 45938:f5d62f4d5327

rhg: check that .hg/requires is ASCII Differential Revision: https://phab.mercurial-scm.org/D9400
author Simon Sapin <simon-commits@exyr.org>
date Wed, 25 Nov 2020 12:33:37 +0100
parents 9f70512ae2cf
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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 )
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
23 from .utils import cborutil
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
24
37719
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
25
37725
3ea8323d6f95 wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37722
diff changeset
26 def formatrichmessage(atoms):
3ea8323d6f95 wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37722
diff changeset
27 """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
28
3ea8323d6f95 wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37722
diff changeset
29 chunks = []
3ea8323d6f95 wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37722
diff changeset
30
3ea8323d6f95 wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37722
diff changeset
31 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
32 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
33
3ea8323d6f95 wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37722
diff changeset
34 if b'args' in atom:
39486
43d92d68ac88 wireprotov2peer: properly format errors
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39485
diff changeset
35 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
36
3ea8323d6f95 wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37722
diff changeset
37 chunks.append(msg)
3ea8323d6f95 wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37722
diff changeset
38
3ea8323d6f95 wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37722
diff changeset
39 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
40
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
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
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
52
40024
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40019
diff changeset
53 def redirecttargetsupported(ui, target):
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40019
diff changeset
54 """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
55
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40019
diff changeset
56 ``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
57 the server.
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40019
diff changeset
58 """
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40019
diff changeset
59 if target.get(b'protocol') not in SUPPORTED_REDIRECT_PROTOCOLS:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
60 ui.note(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
61 _(b'(remote redirect target %s uses unsupported protocol: %s)\n')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
62 % (target[b'name'], target.get(b'protocol', b''))
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
63 )
40024
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40019
diff changeset
64 return False
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40019
diff changeset
65
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40019
diff changeset
66 if target.get(b'snirequired') and not sslutil.hassni:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
67 ui.note(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
68 _(b'(redirect target %s requires SNI, which is unsupported)\n')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
69 % target[b'name']
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
70 )
40024
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40019
diff changeset
71 return False
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40019
diff changeset
72
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40019
diff changeset
73 if b'tlsversions' in target:
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40019
diff changeset
74 tlsversions = set(target[b'tlsversions'])
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40019
diff changeset
75 supported = set()
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40019
diff changeset
76
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40019
diff changeset
77 for v in sslutil.supportedprotocols:
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40019
diff changeset
78 assert v.startswith(b'tls')
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40019
diff changeset
79 supported.add(v[3:])
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40019
diff changeset
80
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40019
diff changeset
81 if not tlsversions & supported:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
82 ui.note(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
83 _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
84 b'(remote redirect target %s requires unsupported TLS '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
85 b'versions: %s)\n'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
86 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
87 % (target[b'name'], b', '.join(sorted(tlsversions)))
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
88 )
40024
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40019
diff changeset
89 return False
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40019
diff changeset
90
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
91 ui.note(_(b'(remote redirect target %s is compatible)\n') % target[b'name'])
40024
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 return True
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40019
diff changeset
94
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
95
40024
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40019
diff changeset
96 def supportedredirects(ui, apidescriptor):
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40019
diff changeset
97 """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
98
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40019
diff changeset
99 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
100 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
101 support for compatible redirect targets.
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40019
diff changeset
102
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40019
diff changeset
103 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
104 supported.
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40019
diff changeset
105 """
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40019
diff changeset
106 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
107 return None
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40019
diff changeset
108
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
109 targets = [
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
110 t[b'name']
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
111 for t in apidescriptor[b'redirect'][b'targets']
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
112 if redirecttargetsupported(ui, t)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
113 ]
40024
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40019
diff changeset
114
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
115 hashes = [
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
116 h
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
117 for h in apidescriptor[b'redirect'][b'hashes']
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
118 if h in SUPPORTED_CONTENT_HASHES
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
119 ]
40024
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40019
diff changeset
120
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40019
diff changeset
121 return {
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40019
diff changeset
122 b'targets': targets,
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40019
diff changeset
123 b'hashes': hashes,
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40019
diff changeset
124 }
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40019
diff changeset
125
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
126
37720
d715a85003c8 wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37719
diff changeset
127 class commandresponse(object):
39561
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
128 """Represents the response to a command request.
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
129
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
130 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
131
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
132 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
133 events occur.
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
134 """
37720
d715a85003c8 wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37719
diff changeset
135
40026
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
136 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
137 self.requestid = requestid
d715a85003c8 wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37719
diff changeset
138 self.command = command
40026
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
139 self.fromredirect = fromredirect
37720
d715a85003c8 wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37719
diff changeset
140
39561
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
141 # 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
142 # received.
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
143 self._inputcomplete = False
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
144
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
145 # 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
146 # 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
147 # sending us new data and another consuming it.
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
148 self._lock = threading.RLock()
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
149
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
150 # 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
151 # is waited on by the generator emitting objects.
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
152 self._serviceable = threading.Event()
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 self._pendingevents = []
40137
ed4ebbb98ca0 wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40134
diff changeset
155 self._pendingerror = None
39561
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
156 self._decoder = cborutil.bufferingdecoder()
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
157 self._seeninitial = False
40026
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
158 self._redirect = None
39561
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
159
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
160 def _oninputcomplete(self):
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
161 with self._lock:
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
162 self._inputcomplete = True
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
163 self._serviceable.set()
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
164
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
165 def _onresponsedata(self, data):
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
166 available, readcount, wanted = self._decoder.decode(data)
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
167
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
168 if not available:
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
169 return
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 with self._lock:
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
172 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
173 if not self._seeninitial and not self.fromredirect:
39561
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
174 self._handleinitial(o)
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
175 continue
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
176
40026
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
177 # 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
178 # 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
179 # 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
180 # if we see a misbehaving server.
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
181 if self._redirect:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
182 raise error.Abort(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
183 _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
184 b'received unexpected response data '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
185 b'after content redirect; the remote is '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
186 b'buggy'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
187 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
188 )
40026
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
189
39561
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
190 self._pendingevents.append(o)
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
191
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
192 self._serviceable.set()
37720
d715a85003c8 wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37719
diff changeset
193
40137
ed4ebbb98ca0 wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40134
diff changeset
194 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
195 self._pendingerror = e
ed4ebbb98ca0 wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40134
diff changeset
196
ed4ebbb98ca0 wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40134
diff changeset
197 with self._lock:
ed4ebbb98ca0 wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40134
diff changeset
198 self._serviceable.set()
ed4ebbb98ca0 wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40134
diff changeset
199
39561
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
200 def _handleinitial(self, o):
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
201 self._seeninitial = True
40024
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40019
diff changeset
202 if o[b'status'] == b'ok':
39561
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
203 return
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
204
40024
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40019
diff changeset
205 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
206 l = o[b'location']
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
207 self._redirect = wireprototypes.alternatelocationresponse(
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
208 url=l[b'url'],
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
209 mediatype=l[b'mediatype'],
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
210 size=l.get(b'size'),
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
211 fullhashes=l.get(b'fullhashes'),
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
212 fullhashseed=l.get(b'fullhashseed'),
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
213 serverdercerts=l.get(b'serverdercerts'),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
214 servercadercerts=l.get(b'servercadercerts'),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
215 )
40026
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
216 return
40024
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40019
diff changeset
217
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
218 atoms = [{b'msg': o[b'error'][b'message']}]
39561
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
219 if b'args' in o[b'error']:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
220 atoms[0][b'args'] = o[b'error'][b'args']
39561
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
221
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
222 raise error.RepoError(formatrichmessage(atoms))
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
223
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
224 def objects(self):
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
225 """Obtained decoded objects from this response.
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
226
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
227 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
228 command response.
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
229
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
230 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
231 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
232
39561
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
233 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
234 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
235 advancing the generator.
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 while True:
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
238 # 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
239 # 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
240 # 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
241 # our state.
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
242 self._serviceable.wait(1.0)
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
243
40137
ed4ebbb98ca0 wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40134
diff changeset
244 if self._pendingerror:
ed4ebbb98ca0 wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40134
diff changeset
245 raise self._pendingerror
ed4ebbb98ca0 wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40134
diff changeset
246
39561
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
247 with self._lock:
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
248 self._serviceable.clear()
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
249
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
250 # Make copies because objects could be mutated during
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
251 # iteration.
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
252 stop = self._inputcomplete
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
253 pending = list(self._pendingevents)
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
254 self._pendingevents[:] = []
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
255
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
256 for o in pending:
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
257 yield o
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
258
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
259 if stop:
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
260 break
37720
d715a85003c8 wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37719
diff changeset
261
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
262
37719
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
263 class clienthandler(object):
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
264 """Object to handle higher-level client activities.
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 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
267 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
268 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
269 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
270 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
271 with the higher-level peer API.
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
272 """
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
273
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
274 def __init__(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
275 self, ui, clientreactor, opener=None, requestbuilder=util.urlreq.request
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
276 ):
37719
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
277 self._ui = ui
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
278 self._reactor = clientreactor
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
279 self._requests = {}
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
280 self._futures = {}
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
281 self._responses = {}
40026
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
282 self._redirects = []
40019
f5a05bb48116 wireprotov2: change name and behavior of readframe()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39561
diff changeset
283 self._frameseof = False
40026
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
284 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
285 self._requestbuilder = requestbuilder
37719
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
286
40024
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40019
diff changeset
287 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
288 """Register a request to call a command.
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 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
291 """
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
292 request, action, meta = self._reactor.callcommand(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
293 command, args, redirect=redirect
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
294 )
37719
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
295
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
296 if action != b'noop':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
297 raise error.ProgrammingError(b'%s not yet supported' % action)
37719
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
298
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
299 rid = request.requestid
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
300 self._requests[rid] = request
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
301 self._futures[rid] = f
39561
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
302 # 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
303 # objects() may deadlock.
37720
d715a85003c8 wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37719
diff changeset
304 self._responses[rid] = commandresponse(rid, command)
37719
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
305
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
306 return iter(())
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
307
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
308 def flushcommands(self):
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
309 """Flush all queued commands.
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
310
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
311 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
312 """
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
313 action, meta = self._reactor.flushcommands()
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
314
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
315 if action != b'sendframes':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
316 raise error.ProgrammingError(b'%s not yet supported' % action)
37719
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
317
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
318 return meta[b'framegen']
37719
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
319
40019
f5a05bb48116 wireprotov2: change name and behavior of readframe()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39561
diff changeset
320 def readdata(self, framefh):
f5a05bb48116 wireprotov2: change name and behavior of readframe()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39561
diff changeset
321 """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
322
40019
f5a05bb48116 wireprotov2: change name and behavior of readframe()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39561
diff changeset
323 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
324 done with all read I/O.
37719
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
325 """
40019
f5a05bb48116 wireprotov2: change name and behavior of readframe()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39561
diff changeset
326 if not self._frameseof:
f5a05bb48116 wireprotov2: change name and behavior of readframe()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39561
diff changeset
327 frame = wireprotoframing.readframe(framefh)
f5a05bb48116 wireprotov2: change name and behavior of readframe()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39561
diff changeset
328 if frame is None:
f5a05bb48116 wireprotov2: change name and behavior of readframe()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39561
diff changeset
329 # TODO tell reactor?
f5a05bb48116 wireprotov2: change name and behavior of readframe()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39561
diff changeset
330 self._frameseof = True
f5a05bb48116 wireprotov2: change name and behavior of readframe()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39561
diff changeset
331 else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
332 self._ui.debug(b'received %r\n' % frame)
40019
f5a05bb48116 wireprotov2: change name and behavior of readframe()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39561
diff changeset
333 self._processframe(frame)
37719
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
334
40026
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
335 # 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
336 if self._redirects:
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
337 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
338 self._redirects.pop(0)
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
339
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
340 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
341 return None
37719
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
342
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
343 return True
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
344
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
345 def _processframe(self, frame):
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
346 """Process a single read frame."""
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
347
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
348 action, meta = self._reactor.onframerecv(frame)
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
349
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
350 if action == b'error':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
351 e = error.RepoError(meta[b'message'])
37719
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
352
39561
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
353 if frame.requestid in self._responses:
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
354 self._responses[frame.requestid]._oninputcomplete()
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
355
37719
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
356 if frame.requestid in self._futures:
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
357 self._futures[frame.requestid].set_exception(e)
39561
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
358 del self._futures[frame.requestid]
37719
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
359 else:
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
360 raise e
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
361
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
362 return
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
363 elif action == b'noop':
40134
cfeba1aafb9d wireprotov2: handle noop action
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40026
diff changeset
364 return
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
365 elif action == b'responsedata':
40139
17223d8e7d75 wireprotov2: raise ProgrammingError on unknown action
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40137
diff changeset
366 # Handled below.
17223d8e7d75 wireprotov2: raise ProgrammingError on unknown action
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40137
diff changeset
367 pass
17223d8e7d75 wireprotov2: raise ProgrammingError on unknown action
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40137
diff changeset
368 else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
369 raise error.ProgrammingError(b'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
370
37719
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
371 if frame.requestid not in self._requests:
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
372 raise error.ProgrammingError(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
373 b'received frame for unknown request; this is either a bug in '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
374 b'the clientreactor not screening for this or this instance was '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
375 b'never told about this request: %r' % frame
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
376 )
37719
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
377
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
378 response = self._responses[frame.requestid]
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
379
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
380 if action == b'responsedata':
39485
42bc1c70a6b8 wireprotov2peer: report exceptions in frame handling against request future
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39450
diff changeset
381 # 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
382 # future tracking the request.
42bc1c70a6b8 wireprotov2peer: report exceptions in frame handling against request future
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39450
diff changeset
383 try:
42bc1c70a6b8 wireprotov2peer: report exceptions in frame handling against request future
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39450
diff changeset
384 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
385 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
386 # 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
387 # 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
388 # 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
389 # 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
390 # 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
391 # take.
ed4ebbb98ca0 wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40134
diff changeset
392 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
393 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
394 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
395 response._oninputcomplete()
ed4ebbb98ca0 wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40134
diff changeset
396 else:
ed4ebbb98ca0 wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40134
diff changeset
397 response._onerror(e)
37719
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
398 else:
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
399 raise error.ProgrammingError(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
400 b'unhandled action from clientreactor: %s' % action
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
401 )
37721
f7673845b167 wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37720
diff changeset
402
39438
c734a5c82f38 wireprotov2peer: split responsedata handling into separate function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39435
diff changeset
403 def _processresponsedata(self, frame, meta, response):
39561
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
404 # This can raise. The caller can handle it.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
405 response._onresponsedata(meta[b'data'])
39438
c734a5c82f38 wireprotov2peer: split responsedata handling into separate function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39435
diff changeset
406
40724
15a643304728 wireprotov2peer: wait for initial object before resolving future
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40723
diff changeset
407 # 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
408 # 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
409 # 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
410 # 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
411 # 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
412 #
15a643304728 wireprotov2peer: wait for initial object before resolving future
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40723
diff changeset
413 # 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
414 # 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
415
40724
15a643304728 wireprotov2peer: wait for initial object before resolving future
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40723
diff changeset
416 # Always react to eos.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
417 if meta[b'eos']:
39561
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
418 response._oninputcomplete()
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
419 del self._requests[frame.requestid]
39438
c734a5c82f38 wireprotov2peer: split responsedata handling into separate function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39435
diff changeset
420
40724
15a643304728 wireprotov2peer: wait for initial object before resolving future
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40723
diff changeset
421 # 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
422 # 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
423 elif not response._seeninitial:
15a643304728 wireprotov2peer: wait for initial object before resolving future
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40723
diff changeset
424 return
40026
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
425
40724
15a643304728 wireprotov2peer: wait for initial object before resolving future
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40723
diff changeset
426 # 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
427 # 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
428 # 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
429 if response._redirect:
15a643304728 wireprotov2peer: wait for initial object before resolving future
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40723
diff changeset
430 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
431 return
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
432
39561
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
433 # 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
434 # received before resolving the future. Otherwise we resolve the
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
435 # future immediately.
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
436 if frame.requestid not in self._futures:
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
437 return
39438
c734a5c82f38 wireprotov2peer: split responsedata handling into separate function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39435
diff changeset
438
39561
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
439 if response.command not in COMMAND_DECODERS:
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
440 self._futures[frame.requestid].set_result(response.objects())
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
441 del self._futures[frame.requestid]
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
442 elif response._inputcomplete:
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
443 decoded = COMMAND_DECODERS[response.command](response.objects())
d06834e0f48e wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
444 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
445 del self._futures[frame.requestid]
c734a5c82f38 wireprotov2peer: split responsedata handling into separate function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39435
diff changeset
446
40026
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
447 def _followredirect(self, requestid, redirect):
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
448 """Called to initiate redirect following for a request."""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
449 self._ui.note(_(b'(following redirect to %s)\n') % redirect.url)
40026
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
450
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
451 # TODO handle framed responses.
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
452 if redirect.mediatype != b'application/mercurial-cbor':
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
453 raise error.Abort(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
454 _(b'cannot handle redirects for the %s media type')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
455 % redirect.mediatype
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
456 )
40026
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
457
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
458 if redirect.fullhashes:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
459 self._ui.warn(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
460 _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
461 b'(support for validating hashes on content '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
462 b'redirects not supported)\n'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
463 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
464 )
40026
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
465
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
466 if redirect.serverdercerts or redirect.servercadercerts:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
467 self._ui.warn(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
468 _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
469 b'(support for pinning server certificates on '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
470 b'content redirects not supported)\n'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
471 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
472 )
40026
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
473
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
474 headers = {
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43077
diff changeset
475 'Accept': redirect.mediatype,
40026
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
476 }
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
477
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
478 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
479
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
480 try:
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
481 res = self._opener.open(req)
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
482 except util.urlerr.httperror as e:
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
483 if e.code == 401:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
484 raise error.Abort(_(b'authorization failed'))
40026
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
485 raise
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
486 except util.httplib.HTTPException as e:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
487 self._ui.debug(b'http error requesting %s\n' % req.get_full_url())
40026
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
488 self._ui.traceback()
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
489 raise IOError(None, e)
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 urlmod.wrapresponse(res)
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 # 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
494 # 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
495 oldresponse = self._responses[requestid]
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
496 self._responses[requestid] = commandresponse(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
497 requestid, oldresponse.command, fromredirect=True
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
498 )
40026
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
499
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
500 self._redirects.append((requestid, res))
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
501
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
502 def _processredirect(self, rid, res):
40723
94b0d0f996e1 wireprotov2peer: always return a bool from _processredirect()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40139
diff changeset
503 """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
504
94b0d0f996e1 wireprotov2peer: always return a bool from _processredirect()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40139
diff changeset
505 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
506 """
40026
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
507 response = self._responses[rid]
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
508
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
509 try:
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
510 data = res.read(32768)
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
511 response._onresponsedata(data)
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
512
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
513 # We're at end of stream.
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
514 if not data:
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
515 response._oninputcomplete()
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
516
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
517 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
518 return bool(data)
40026
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
519
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
520 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
521 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
522 del self._futures[rid]
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
523 elif response._inputcomplete:
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
524 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
525 self._futures[rid].set_result(decoded)
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
526 del self._futures[rid]
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
527
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
528 return bool(data)
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
529
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
530 except BaseException as e:
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
531 self._futures[rid].set_exception(e)
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
532 del self._futures[rid]
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
533 response._oninputcomplete()
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
534 return False
7e807b8a9e56 wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
535
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
536
37725
3ea8323d6f95 wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37722
diff changeset
537 def decodebranchmap(objs):
37721
f7673845b167 wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37720
diff changeset
538 # 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
539 bm = next(objs)
37721
f7673845b167 wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37720
diff changeset
540
f7673845b167 wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37720
diff changeset
541 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
542
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
543
37725
3ea8323d6f95 wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37722
diff changeset
544 def decodeheads(objs):
37721
f7673845b167 wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37720
diff changeset
545 # 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
546 return next(objs)
37721
f7673845b167 wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37720
diff changeset
547
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
548
37725
3ea8323d6f95 wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37722
diff changeset
549 def decodeknown(objs):
37721
f7673845b167 wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37720
diff changeset
550 # 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
551 raw = next(objs)
37721
f7673845b167 wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37720
diff changeset
552
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
553 return [True if raw[i : i + 1] == b'1' else False for i in range(len(raw))]
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
554
37721
f7673845b167 wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37720
diff changeset
555
37725
3ea8323d6f95 wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37722
diff changeset
556 def decodelistkeys(objs):
37721
f7673845b167 wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37720
diff changeset
557 # 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
558 return next(objs)
37721
f7673845b167 wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37720
diff changeset
559
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
560
37725
3ea8323d6f95 wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37722
diff changeset
561 def decodelookup(objs):
3ea8323d6f95 wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37722
diff changeset
562 return next(objs)
37721
f7673845b167 wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37720
diff changeset
563
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
564
37725
3ea8323d6f95 wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37722
diff changeset
565 def decodepushkey(objs):
3ea8323d6f95 wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37722
diff changeset
566 return next(objs)
37721
f7673845b167 wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37720
diff changeset
567
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41380
diff changeset
568
37721
f7673845b167 wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37720
diff changeset
569 COMMAND_DECODERS = {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
570 b'branchmap': decodebranchmap,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
571 b'heads': decodeheads,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
572 b'known': decodeknown,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
573 b'listkeys': decodelistkeys,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
574 b'lookup': decodelookup,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
575 b'pushkey': decodepushkey,
37721
f7673845b167 wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37720
diff changeset
576 }