##// END OF EJS Templates
wireproto: define frame to represent progress updates...
Gregory Szorc -
r37307:b0041036 default
parent child Browse files
Show More
@@ -1,1612 +1,1650 b''
1 The Mercurial wire protocol is a request-response based protocol
1 The Mercurial wire protocol is a request-response based protocol
2 with multiple wire representations.
2 with multiple wire representations.
3
3
4 Each request is modeled as a command name, a dictionary of arguments, and
4 Each request is modeled as a command name, a dictionary of arguments, and
5 optional raw input. Command arguments and their types are intrinsic
5 optional raw input. Command arguments and their types are intrinsic
6 properties of commands. So is the response type of the command. This means
6 properties of commands. So is the response type of the command. This means
7 clients can't always send arbitrary arguments to servers and servers can't
7 clients can't always send arbitrary arguments to servers and servers can't
8 return multiple response types.
8 return multiple response types.
9
9
10 The protocol is synchronous and does not support multiplexing (concurrent
10 The protocol is synchronous and does not support multiplexing (concurrent
11 commands).
11 commands).
12
12
13 Handshake
13 Handshake
14 =========
14 =========
15
15
16 It is required or common for clients to perform a *handshake* when connecting
16 It is required or common for clients to perform a *handshake* when connecting
17 to a server. The handshake serves the following purposes:
17 to a server. The handshake serves the following purposes:
18
18
19 * Negotiating protocol/transport level options
19 * Negotiating protocol/transport level options
20 * Allows the client to learn about server capabilities to influence
20 * Allows the client to learn about server capabilities to influence
21 future requests
21 future requests
22 * Ensures the underlying transport channel is in a *clean* state
22 * Ensures the underlying transport channel is in a *clean* state
23
23
24 An important goal of the handshake is to allow clients to use more modern
24 An important goal of the handshake is to allow clients to use more modern
25 wire protocol features. By default, clients must assume they are talking
25 wire protocol features. By default, clients must assume they are talking
26 to an old version of Mercurial server (possibly even the very first
26 to an old version of Mercurial server (possibly even the very first
27 implementation). So, clients should not attempt to call or utilize modern
27 implementation). So, clients should not attempt to call or utilize modern
28 wire protocol features until they have confirmation that the server
28 wire protocol features until they have confirmation that the server
29 supports them. The handshake implementation is designed to allow both
29 supports them. The handshake implementation is designed to allow both
30 ends to utilize the latest set of features and capabilities with as
30 ends to utilize the latest set of features and capabilities with as
31 few round trips as possible.
31 few round trips as possible.
32
32
33 The handshake mechanism varies by transport and protocol and is documented
33 The handshake mechanism varies by transport and protocol and is documented
34 in the sections below.
34 in the sections below.
35
35
36 HTTP Protocol
36 HTTP Protocol
37 =============
37 =============
38
38
39 Handshake
39 Handshake
40 ---------
40 ---------
41
41
42 The client sends a ``capabilities`` command request (``?cmd=capabilities``)
42 The client sends a ``capabilities`` command request (``?cmd=capabilities``)
43 as soon as HTTP requests may be issued.
43 as soon as HTTP requests may be issued.
44
44
45 The server responds with a capabilities string, which the client parses to
45 The server responds with a capabilities string, which the client parses to
46 learn about the server's abilities.
46 learn about the server's abilities.
47
47
48 HTTP Version 1 Transport
48 HTTP Version 1 Transport
49 ------------------------
49 ------------------------
50
50
51 Commands are issued as HTTP/1.0 or HTTP/1.1 requests. Commands are
51 Commands are issued as HTTP/1.0 or HTTP/1.1 requests. Commands are
52 sent to the base URL of the repository with the command name sent in
52 sent to the base URL of the repository with the command name sent in
53 the ``cmd`` query string parameter. e.g.
53 the ``cmd`` query string parameter. e.g.
54 ``https://example.com/repo?cmd=capabilities``. The HTTP method is ``GET``
54 ``https://example.com/repo?cmd=capabilities``. The HTTP method is ``GET``
55 or ``POST`` depending on the command and whether there is a request
55 or ``POST`` depending on the command and whether there is a request
56 body.
56 body.
57
57
58 Command arguments can be sent multiple ways.
58 Command arguments can be sent multiple ways.
59
59
60 The simplest is part of the URL query string using ``x-www-form-urlencoded``
60 The simplest is part of the URL query string using ``x-www-form-urlencoded``
61 encoding (see Python's ``urllib.urlencode()``. However, many servers impose
61 encoding (see Python's ``urllib.urlencode()``. However, many servers impose
62 length limitations on the URL. So this mechanism is typically only used if
62 length limitations on the URL. So this mechanism is typically only used if
63 the server doesn't support other mechanisms.
63 the server doesn't support other mechanisms.
64
64
65 If the server supports the ``httpheader`` capability, command arguments can
65 If the server supports the ``httpheader`` capability, command arguments can
66 be sent in HTTP request headers named ``X-HgArg-<N>`` where ``<N>`` is an
66 be sent in HTTP request headers named ``X-HgArg-<N>`` where ``<N>`` is an
67 integer starting at 1. A ``x-www-form-urlencoded`` representation of the
67 integer starting at 1. A ``x-www-form-urlencoded`` representation of the
68 arguments is obtained. This full string is then split into chunks and sent
68 arguments is obtained. This full string is then split into chunks and sent
69 in numbered ``X-HgArg-<N>`` headers. The maximum length of each HTTP header
69 in numbered ``X-HgArg-<N>`` headers. The maximum length of each HTTP header
70 is defined by the server in the ``httpheader`` capability value, which defaults
70 is defined by the server in the ``httpheader`` capability value, which defaults
71 to ``1024``. The server reassembles the encoded arguments string by
71 to ``1024``. The server reassembles the encoded arguments string by
72 concatenating the ``X-HgArg-<N>`` headers then URL decodes them into a
72 concatenating the ``X-HgArg-<N>`` headers then URL decodes them into a
73 dictionary.
73 dictionary.
74
74
75 The list of ``X-HgArg-<N>`` headers should be added to the ``Vary`` request
75 The list of ``X-HgArg-<N>`` headers should be added to the ``Vary`` request
76 header to instruct caches to take these headers into consideration when caching
76 header to instruct caches to take these headers into consideration when caching
77 requests.
77 requests.
78
78
79 If the server supports the ``httppostargs`` capability, the client
79 If the server supports the ``httppostargs`` capability, the client
80 may send command arguments in the HTTP request body as part of an
80 may send command arguments in the HTTP request body as part of an
81 HTTP POST request. The command arguments will be URL encoded just like
81 HTTP POST request. The command arguments will be URL encoded just like
82 they would for sending them via HTTP headers. However, no splitting is
82 they would for sending them via HTTP headers. However, no splitting is
83 performed: the raw arguments are included in the HTTP request body.
83 performed: the raw arguments are included in the HTTP request body.
84
84
85 The client sends a ``X-HgArgs-Post`` header with the string length of the
85 The client sends a ``X-HgArgs-Post`` header with the string length of the
86 encoded arguments data. Additional data may be included in the HTTP
86 encoded arguments data. Additional data may be included in the HTTP
87 request body immediately following the argument data. The offset of the
87 request body immediately following the argument data. The offset of the
88 non-argument data is defined by the ``X-HgArgs-Post`` header. The
88 non-argument data is defined by the ``X-HgArgs-Post`` header. The
89 ``X-HgArgs-Post`` header is not required if there is no argument data.
89 ``X-HgArgs-Post`` header is not required if there is no argument data.
90
90
91 Additional command data can be sent as part of the HTTP request body. The
91 Additional command data can be sent as part of the HTTP request body. The
92 default ``Content-Type`` when sending data is ``application/mercurial-0.1``.
92 default ``Content-Type`` when sending data is ``application/mercurial-0.1``.
93 A ``Content-Length`` header is currently always sent.
93 A ``Content-Length`` header is currently always sent.
94
94
95 Example HTTP requests::
95 Example HTTP requests::
96
96
97 GET /repo?cmd=capabilities
97 GET /repo?cmd=capabilities
98 X-HgArg-1: foo=bar&baz=hello%20world
98 X-HgArg-1: foo=bar&baz=hello%20world
99
99
100 The request media type should be chosen based on server support. If the
100 The request media type should be chosen based on server support. If the
101 ``httpmediatype`` server capability is present, the client should send
101 ``httpmediatype`` server capability is present, the client should send
102 the newest mutually supported media type. If this capability is absent,
102 the newest mutually supported media type. If this capability is absent,
103 the client must assume the server only supports the
103 the client must assume the server only supports the
104 ``application/mercurial-0.1`` media type.
104 ``application/mercurial-0.1`` media type.
105
105
106 The ``Content-Type`` HTTP response header identifies the response as coming
106 The ``Content-Type`` HTTP response header identifies the response as coming
107 from Mercurial and can also be used to signal an error has occurred.
107 from Mercurial and can also be used to signal an error has occurred.
108
108
109 The ``application/mercurial-*`` media types indicate a generic Mercurial
109 The ``application/mercurial-*`` media types indicate a generic Mercurial
110 data type.
110 data type.
111
111
112 The ``application/mercurial-0.1`` media type is raw Mercurial data. It is the
112 The ``application/mercurial-0.1`` media type is raw Mercurial data. It is the
113 predecessor of the format below.
113 predecessor of the format below.
114
114
115 The ``application/mercurial-0.2`` media type is compression framed Mercurial
115 The ``application/mercurial-0.2`` media type is compression framed Mercurial
116 data. The first byte of the payload indicates the length of the compression
116 data. The first byte of the payload indicates the length of the compression
117 format identifier that follows. Next are N bytes indicating the compression
117 format identifier that follows. Next are N bytes indicating the compression
118 format. e.g. ``zlib``. The remaining bytes are compressed according to that
118 format. e.g. ``zlib``. The remaining bytes are compressed according to that
119 compression format. The decompressed data behaves the same as with
119 compression format. The decompressed data behaves the same as with
120 ``application/mercurial-0.1``.
120 ``application/mercurial-0.1``.
121
121
122 The ``application/hg-error`` media type indicates a generic error occurred.
122 The ``application/hg-error`` media type indicates a generic error occurred.
123 The content of the HTTP response body typically holds text describing the
123 The content of the HTTP response body typically holds text describing the
124 error.
124 error.
125
125
126 The ``application/hg-changegroup`` media type indicates a changegroup response
126 The ``application/hg-changegroup`` media type indicates a changegroup response
127 type.
127 type.
128
128
129 Clients also accept the ``text/plain`` media type. All other media
129 Clients also accept the ``text/plain`` media type. All other media
130 types should cause the client to error.
130 types should cause the client to error.
131
131
132 Behavior of media types is further described in the ``Content Negotiation``
132 Behavior of media types is further described in the ``Content Negotiation``
133 section below.
133 section below.
134
134
135 Clients should issue a ``User-Agent`` request header that identifies the client.
135 Clients should issue a ``User-Agent`` request header that identifies the client.
136 The server should not use the ``User-Agent`` for feature detection.
136 The server should not use the ``User-Agent`` for feature detection.
137
137
138 A command returning a ``string`` response issues a
138 A command returning a ``string`` response issues a
139 ``application/mercurial-0.*`` media type and the HTTP response body contains
139 ``application/mercurial-0.*`` media type and the HTTP response body contains
140 the raw string value (after compression decoding, if used). A
140 the raw string value (after compression decoding, if used). A
141 ``Content-Length`` header is typically issued, but not required.
141 ``Content-Length`` header is typically issued, but not required.
142
142
143 A command returning a ``stream`` response issues a
143 A command returning a ``stream`` response issues a
144 ``application/mercurial-0.*`` media type and the HTTP response is typically
144 ``application/mercurial-0.*`` media type and the HTTP response is typically
145 using *chunked transfer* (``Transfer-Encoding: chunked``).
145 using *chunked transfer* (``Transfer-Encoding: chunked``).
146
146
147 HTTP Version 2 Transport
147 HTTP Version 2 Transport
148 ------------------------
148 ------------------------
149
149
150 **Experimental - feature under active development**
150 **Experimental - feature under active development**
151
151
152 Version 2 of the HTTP protocol is exposed under the ``/api/*`` URL space.
152 Version 2 of the HTTP protocol is exposed under the ``/api/*`` URL space.
153 It's final API name is not yet formalized.
153 It's final API name is not yet formalized.
154
154
155 Commands are triggered by sending HTTP POST requests against URLs of the
155 Commands are triggered by sending HTTP POST requests against URLs of the
156 form ``<permission>/<command>``, where ``<permission>`` is ``ro`` or
156 form ``<permission>/<command>``, where ``<permission>`` is ``ro`` or
157 ``rw``, meaning read-only and read-write, respectively and ``<command>``
157 ``rw``, meaning read-only and read-write, respectively and ``<command>``
158 is a named wire protocol command.
158 is a named wire protocol command.
159
159
160 Non-POST request methods MUST be rejected by the server with an HTTP
160 Non-POST request methods MUST be rejected by the server with an HTTP
161 405 response.
161 405 response.
162
162
163 Commands that modify repository state in meaningful ways MUST NOT be
163 Commands that modify repository state in meaningful ways MUST NOT be
164 exposed under the ``ro`` URL prefix. All available commands MUST be
164 exposed under the ``ro`` URL prefix. All available commands MUST be
165 available under the ``rw`` URL prefix.
165 available under the ``rw`` URL prefix.
166
166
167 Server adminstrators MAY implement blanket HTTP authentication keyed
167 Server adminstrators MAY implement blanket HTTP authentication keyed
168 off the URL prefix. For example, a server may require authentication
168 off the URL prefix. For example, a server may require authentication
169 for all ``rw/*`` URLs and let unauthenticated requests to ``ro/*``
169 for all ``rw/*`` URLs and let unauthenticated requests to ``ro/*``
170 URL proceed. A server MAY issue an HTTP 401, 403, or 407 response
170 URL proceed. A server MAY issue an HTTP 401, 403, or 407 response
171 in accordance with RFC 7235. Clients SHOULD recognize the HTTP Basic
171 in accordance with RFC 7235. Clients SHOULD recognize the HTTP Basic
172 (RFC 7617) and Digest (RFC 7616) authentication schemes. Clients SHOULD
172 (RFC 7617) and Digest (RFC 7616) authentication schemes. Clients SHOULD
173 make an attempt to recognize unknown schemes using the
173 make an attempt to recognize unknown schemes using the
174 ``WWW-Authenticate`` response header on a 401 response, as defined by
174 ``WWW-Authenticate`` response header on a 401 response, as defined by
175 RFC 7235.
175 RFC 7235.
176
176
177 Read-only commands are accessible under ``rw/*`` URLs so clients can
177 Read-only commands are accessible under ``rw/*`` URLs so clients can
178 signal the intent of the operation very early in the connection
178 signal the intent of the operation very early in the connection
179 lifecycle. For example, a ``push`` operation - which consists of
179 lifecycle. For example, a ``push`` operation - which consists of
180 various read-only commands mixed with at least one read-write command -
180 various read-only commands mixed with at least one read-write command -
181 can perform all commands against ``rw/*`` URLs so that any server-side
181 can perform all commands against ``rw/*`` URLs so that any server-side
182 authentication requirements are discovered upon attempting the first
182 authentication requirements are discovered upon attempting the first
183 command - not potentially several commands into the exchange. This
183 command - not potentially several commands into the exchange. This
184 allows clients to fail faster or prompt for credentials as soon as the
184 allows clients to fail faster or prompt for credentials as soon as the
185 exchange takes place. This provides a better end-user experience.
185 exchange takes place. This provides a better end-user experience.
186
186
187 Requests to unknown commands or URLS result in an HTTP 404.
187 Requests to unknown commands or URLS result in an HTTP 404.
188 TODO formally define response type, how error is communicated, etc.
188 TODO formally define response type, how error is communicated, etc.
189
189
190 HTTP request and response bodies use the *Unified Frame-Based Protocol*
190 HTTP request and response bodies use the *Unified Frame-Based Protocol*
191 (defined below) for media exchange. The entirety of the HTTP message
191 (defined below) for media exchange. The entirety of the HTTP message
192 body is 0 or more frames as defined by this protocol.
192 body is 0 or more frames as defined by this protocol.
193
193
194 Clients and servers MUST advertise the ``TBD`` media type via the
194 Clients and servers MUST advertise the ``TBD`` media type via the
195 ``Content-Type`` request and response headers. In addition, clients MUST
195 ``Content-Type`` request and response headers. In addition, clients MUST
196 advertise this media type value in their ``Accept`` request header in all
196 advertise this media type value in their ``Accept`` request header in all
197 requests.
197 requests.
198 TODO finalize the media type. For now, it is defined in wireprotoserver.py.
198 TODO finalize the media type. For now, it is defined in wireprotoserver.py.
199
199
200 Servers receiving requests without an ``Accept`` header SHOULD respond with
200 Servers receiving requests without an ``Accept`` header SHOULD respond with
201 an HTTP 406.
201 an HTTP 406.
202
202
203 Servers receiving requests with an invalid ``Content-Type`` header SHOULD
203 Servers receiving requests with an invalid ``Content-Type`` header SHOULD
204 respond with an HTTP 415.
204 respond with an HTTP 415.
205
205
206 The command to run is specified in the POST payload as defined by the
206 The command to run is specified in the POST payload as defined by the
207 *Unified Frame-Based Protocol*. This is redundant with data already
207 *Unified Frame-Based Protocol*. This is redundant with data already
208 encoded in the URL. This is by design, so server operators can have
208 encoded in the URL. This is by design, so server operators can have
209 better understanding about server activity from looking merely at
209 better understanding about server activity from looking merely at
210 HTTP access logs.
210 HTTP access logs.
211
211
212 In most circumstances, the command specified in the URL MUST match
212 In most circumstances, the command specified in the URL MUST match
213 the command specified in the frame-based payload or the server will
213 the command specified in the frame-based payload or the server will
214 respond with an error. The exception to this is the special
214 respond with an error. The exception to this is the special
215 ``multirequest`` URL. (See below.) In addition, HTTP requests
215 ``multirequest`` URL. (See below.) In addition, HTTP requests
216 are limited to one command invocation. The exception is the special
216 are limited to one command invocation. The exception is the special
217 ``multirequest`` URL.
217 ``multirequest`` URL.
218
218
219 The ``multirequest`` command endpoints (``ro/multirequest`` and
219 The ``multirequest`` command endpoints (``ro/multirequest`` and
220 ``rw/multirequest``) are special in that they allow the execution of
220 ``rw/multirequest``) are special in that they allow the execution of
221 *any* command and allow the execution of multiple commands. If the
221 *any* command and allow the execution of multiple commands. If the
222 HTTP request issues multiple commands across multiple frames, all
222 HTTP request issues multiple commands across multiple frames, all
223 issued commands will be processed by the server. Per the defined
223 issued commands will be processed by the server. Per the defined
224 behavior of the *Unified Frame-Based Protocol*, commands may be
224 behavior of the *Unified Frame-Based Protocol*, commands may be
225 issued interleaved and responses may come back in a different order
225 issued interleaved and responses may come back in a different order
226 than they were issued. Clients MUST be able to deal with this.
226 than they were issued. Clients MUST be able to deal with this.
227
227
228 SSH Protocol
228 SSH Protocol
229 ============
229 ============
230
230
231 Handshake
231 Handshake
232 ---------
232 ---------
233
233
234 For all clients, the handshake consists of the client sending 1 or more
234 For all clients, the handshake consists of the client sending 1 or more
235 commands to the server using version 1 of the transport. Servers respond
235 commands to the server using version 1 of the transport. Servers respond
236 to commands they know how to respond to and send an empty response (``0\n``)
236 to commands they know how to respond to and send an empty response (``0\n``)
237 for unknown commands (per standard behavior of version 1 of the transport).
237 for unknown commands (per standard behavior of version 1 of the transport).
238 Clients then typically look for a response to the newest sent command to
238 Clients then typically look for a response to the newest sent command to
239 determine which transport version to use and what the available features for
239 determine which transport version to use and what the available features for
240 the connection and server are.
240 the connection and server are.
241
241
242 Preceding any response from client-issued commands, the server may print
242 Preceding any response from client-issued commands, the server may print
243 non-protocol output. It is common for SSH servers to print banners, message
243 non-protocol output. It is common for SSH servers to print banners, message
244 of the day announcements, etc when clients connect. It is assumed that any
244 of the day announcements, etc when clients connect. It is assumed that any
245 such *banner* output will precede any Mercurial server output. So clients
245 such *banner* output will precede any Mercurial server output. So clients
246 must be prepared to handle server output on initial connect that isn't
246 must be prepared to handle server output on initial connect that isn't
247 in response to any client-issued command and doesn't conform to Mercurial's
247 in response to any client-issued command and doesn't conform to Mercurial's
248 wire protocol. This *banner* output should only be on stdout. However,
248 wire protocol. This *banner* output should only be on stdout. However,
249 some servers may send output on stderr.
249 some servers may send output on stderr.
250
250
251 Pre 0.9.1 clients issue a ``between`` command with the ``pairs`` argument
251 Pre 0.9.1 clients issue a ``between`` command with the ``pairs`` argument
252 having the value
252 having the value
253 ``0000000000000000000000000000000000000000-0000000000000000000000000000000000000000``.
253 ``0000000000000000000000000000000000000000-0000000000000000000000000000000000000000``.
254
254
255 The ``between`` command has been supported since the original Mercurial
255 The ``between`` command has been supported since the original Mercurial
256 SSH server. Requesting the empty range will return a ``\n`` string response,
256 SSH server. Requesting the empty range will return a ``\n`` string response,
257 which will be encoded as ``1\n\n`` (value length of ``1`` followed by a newline
257 which will be encoded as ``1\n\n`` (value length of ``1`` followed by a newline
258 followed by the value, which happens to be a newline).
258 followed by the value, which happens to be a newline).
259
259
260 For pre 0.9.1 clients and all servers, the exchange looks like::
260 For pre 0.9.1 clients and all servers, the exchange looks like::
261
261
262 c: between\n
262 c: between\n
263 c: pairs 81\n
263 c: pairs 81\n
264 c: 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
264 c: 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
265 s: 1\n
265 s: 1\n
266 s: \n
266 s: \n
267
267
268 0.9.1+ clients send a ``hello`` command (with no arguments) before the
268 0.9.1+ clients send a ``hello`` command (with no arguments) before the
269 ``between`` command. The response to this command allows clients to
269 ``between`` command. The response to this command allows clients to
270 discover server capabilities and settings.
270 discover server capabilities and settings.
271
271
272 An example exchange between 0.9.1+ clients and a ``hello`` aware server looks
272 An example exchange between 0.9.1+ clients and a ``hello`` aware server looks
273 like::
273 like::
274
274
275 c: hello\n
275 c: hello\n
276 c: between\n
276 c: between\n
277 c: pairs 81\n
277 c: pairs 81\n
278 c: 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
278 c: 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
279 s: 324\n
279 s: 324\n
280 s: capabilities: lookup changegroupsubset branchmap pushkey known getbundle ...\n
280 s: capabilities: lookup changegroupsubset branchmap pushkey known getbundle ...\n
281 s: 1\n
281 s: 1\n
282 s: \n
282 s: \n
283
283
284 And a similar scenario but with servers sending a banner on connect::
284 And a similar scenario but with servers sending a banner on connect::
285
285
286 c: hello\n
286 c: hello\n
287 c: between\n
287 c: between\n
288 c: pairs 81\n
288 c: pairs 81\n
289 c: 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
289 c: 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
290 s: welcome to the server\n
290 s: welcome to the server\n
291 s: if you find any issues, email someone@somewhere.com\n
291 s: if you find any issues, email someone@somewhere.com\n
292 s: 324\n
292 s: 324\n
293 s: capabilities: lookup changegroupsubset branchmap pushkey known getbundle ...\n
293 s: capabilities: lookup changegroupsubset branchmap pushkey known getbundle ...\n
294 s: 1\n
294 s: 1\n
295 s: \n
295 s: \n
296
296
297 Note that output from the ``hello`` command is terminated by a ``\n``. This is
297 Note that output from the ``hello`` command is terminated by a ``\n``. This is
298 part of the response payload and not part of the wire protocol adding a newline
298 part of the response payload and not part of the wire protocol adding a newline
299 after responses. In other words, the length of the response contains the
299 after responses. In other words, the length of the response contains the
300 trailing ``\n``.
300 trailing ``\n``.
301
301
302 Clients supporting version 2 of the SSH transport send a line beginning
302 Clients supporting version 2 of the SSH transport send a line beginning
303 with ``upgrade`` before the ``hello`` and ``between`` commands. The line
303 with ``upgrade`` before the ``hello`` and ``between`` commands. The line
304 (which isn't a well-formed command line because it doesn't consist of a
304 (which isn't a well-formed command line because it doesn't consist of a
305 single command name) serves to both communicate the client's intent to
305 single command name) serves to both communicate the client's intent to
306 switch to transport version 2 (transports are version 1 by default) as
306 switch to transport version 2 (transports are version 1 by default) as
307 well as to advertise the client's transport-level capabilities so the
307 well as to advertise the client's transport-level capabilities so the
308 server may satisfy that request immediately.
308 server may satisfy that request immediately.
309
309
310 The upgrade line has the form:
310 The upgrade line has the form:
311
311
312 upgrade <token> <transport capabilities>
312 upgrade <token> <transport capabilities>
313
313
314 That is the literal string ``upgrade`` followed by a space, followed by
314 That is the literal string ``upgrade`` followed by a space, followed by
315 a randomly generated string, followed by a space, followed by a string
315 a randomly generated string, followed by a space, followed by a string
316 denoting the client's transport capabilities.
316 denoting the client's transport capabilities.
317
317
318 The token can be anything. However, a random UUID is recommended. (Use
318 The token can be anything. However, a random UUID is recommended. (Use
319 of version 4 UUIDs is recommended because version 1 UUIDs can leak the
319 of version 4 UUIDs is recommended because version 1 UUIDs can leak the
320 client's MAC address.)
320 client's MAC address.)
321
321
322 The transport capabilities string is a URL/percent encoded string
322 The transport capabilities string is a URL/percent encoded string
323 containing key-value pairs defining the client's transport-level
323 containing key-value pairs defining the client's transport-level
324 capabilities. The following capabilities are defined:
324 capabilities. The following capabilities are defined:
325
325
326 proto
326 proto
327 A comma-delimited list of transport protocol versions the client
327 A comma-delimited list of transport protocol versions the client
328 supports. e.g. ``ssh-v2``.
328 supports. e.g. ``ssh-v2``.
329
329
330 If the server does not recognize the ``upgrade`` line, it should issue
330 If the server does not recognize the ``upgrade`` line, it should issue
331 an empty response and continue processing the ``hello`` and ``between``
331 an empty response and continue processing the ``hello`` and ``between``
332 commands. Here is an example handshake between a version 2 aware client
332 commands. Here is an example handshake between a version 2 aware client
333 and a non version 2 aware server:
333 and a non version 2 aware server:
334
334
335 c: upgrade 2e82ab3f-9ce3-4b4e-8f8c-6fd1c0e9e23a proto=ssh-v2
335 c: upgrade 2e82ab3f-9ce3-4b4e-8f8c-6fd1c0e9e23a proto=ssh-v2
336 c: hello\n
336 c: hello\n
337 c: between\n
337 c: between\n
338 c: pairs 81\n
338 c: pairs 81\n
339 c: 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
339 c: 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
340 s: 0\n
340 s: 0\n
341 s: 324\n
341 s: 324\n
342 s: capabilities: lookup changegroupsubset branchmap pushkey known getbundle ...\n
342 s: capabilities: lookup changegroupsubset branchmap pushkey known getbundle ...\n
343 s: 1\n
343 s: 1\n
344 s: \n
344 s: \n
345
345
346 (The initial ``0\n`` line from the server indicates an empty response to
346 (The initial ``0\n`` line from the server indicates an empty response to
347 the unknown ``upgrade ..`` command/line.)
347 the unknown ``upgrade ..`` command/line.)
348
348
349 If the server recognizes the ``upgrade`` line and is willing to satisfy that
349 If the server recognizes the ``upgrade`` line and is willing to satisfy that
350 upgrade request, it replies to with a payload of the following form:
350 upgrade request, it replies to with a payload of the following form:
351
351
352 upgraded <token> <transport name>\n
352 upgraded <token> <transport name>\n
353
353
354 This line is the literal string ``upgraded``, a space, the token that was
354 This line is the literal string ``upgraded``, a space, the token that was
355 specified by the client in its ``upgrade ...`` request line, a space, and the
355 specified by the client in its ``upgrade ...`` request line, a space, and the
356 name of the transport protocol that was chosen by the server. The transport
356 name of the transport protocol that was chosen by the server. The transport
357 name MUST match one of the names the client specified in the ``proto`` field
357 name MUST match one of the names the client specified in the ``proto`` field
358 of its ``upgrade ...`` request line.
358 of its ``upgrade ...`` request line.
359
359
360 If a server issues an ``upgraded`` response, it MUST also read and ignore
360 If a server issues an ``upgraded`` response, it MUST also read and ignore
361 the lines associated with the ``hello`` and ``between`` command requests
361 the lines associated with the ``hello`` and ``between`` command requests
362 that were issued by the server. It is assumed that the negotiated transport
362 that were issued by the server. It is assumed that the negotiated transport
363 will respond with equivalent requested information following the transport
363 will respond with equivalent requested information following the transport
364 handshake.
364 handshake.
365
365
366 All data following the ``\n`` terminating the ``upgraded`` line is the
366 All data following the ``\n`` terminating the ``upgraded`` line is the
367 domain of the negotiated transport. It is common for the data immediately
367 domain of the negotiated transport. It is common for the data immediately
368 following to contain additional metadata about the state of the transport and
368 following to contain additional metadata about the state of the transport and
369 the server. However, this isn't strictly speaking part of the transport
369 the server. However, this isn't strictly speaking part of the transport
370 handshake and isn't covered by this section.
370 handshake and isn't covered by this section.
371
371
372 Here is an example handshake between a version 2 aware client and a version
372 Here is an example handshake between a version 2 aware client and a version
373 2 aware server:
373 2 aware server:
374
374
375 c: upgrade 2e82ab3f-9ce3-4b4e-8f8c-6fd1c0e9e23a proto=ssh-v2
375 c: upgrade 2e82ab3f-9ce3-4b4e-8f8c-6fd1c0e9e23a proto=ssh-v2
376 c: hello\n
376 c: hello\n
377 c: between\n
377 c: between\n
378 c: pairs 81\n
378 c: pairs 81\n
379 c: 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
379 c: 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
380 s: upgraded 2e82ab3f-9ce3-4b4e-8f8c-6fd1c0e9e23a ssh-v2\n
380 s: upgraded 2e82ab3f-9ce3-4b4e-8f8c-6fd1c0e9e23a ssh-v2\n
381 s: <additional transport specific data>
381 s: <additional transport specific data>
382
382
383 The client-issued token that is echoed in the response provides a more
383 The client-issued token that is echoed in the response provides a more
384 resilient mechanism for differentiating *banner* output from Mercurial
384 resilient mechanism for differentiating *banner* output from Mercurial
385 output. In version 1, properly formatted banner output could get confused
385 output. In version 1, properly formatted banner output could get confused
386 for Mercurial server output. By submitting a randomly generated token
386 for Mercurial server output. By submitting a randomly generated token
387 that is then present in the response, the client can look for that token
387 that is then present in the response, the client can look for that token
388 in response lines and have reasonable certainty that the line did not
388 in response lines and have reasonable certainty that the line did not
389 originate from a *banner* message.
389 originate from a *banner* message.
390
390
391 SSH Version 1 Transport
391 SSH Version 1 Transport
392 -----------------------
392 -----------------------
393
393
394 The SSH transport (version 1) is a custom text-based protocol suitable for
394 The SSH transport (version 1) is a custom text-based protocol suitable for
395 use over any bi-directional stream transport. It is most commonly used with
395 use over any bi-directional stream transport. It is most commonly used with
396 SSH.
396 SSH.
397
397
398 A SSH transport server can be started with ``hg serve --stdio``. The stdin,
398 A SSH transport server can be started with ``hg serve --stdio``. The stdin,
399 stderr, and stdout file descriptors of the started process are used to exchange
399 stderr, and stdout file descriptors of the started process are used to exchange
400 data. When Mercurial connects to a remote server over SSH, it actually starts
400 data. When Mercurial connects to a remote server over SSH, it actually starts
401 a ``hg serve --stdio`` process on the remote server.
401 a ``hg serve --stdio`` process on the remote server.
402
402
403 Commands are issued by sending the command name followed by a trailing newline
403 Commands are issued by sending the command name followed by a trailing newline
404 ``\n`` to the server. e.g. ``capabilities\n``.
404 ``\n`` to the server. e.g. ``capabilities\n``.
405
405
406 Command arguments are sent in the following format::
406 Command arguments are sent in the following format::
407
407
408 <argument> <length>\n<value>
408 <argument> <length>\n<value>
409
409
410 That is, the argument string name followed by a space followed by the
410 That is, the argument string name followed by a space followed by the
411 integer length of the value (expressed as a string) followed by a newline
411 integer length of the value (expressed as a string) followed by a newline
412 (``\n``) followed by the raw argument value.
412 (``\n``) followed by the raw argument value.
413
413
414 Dictionary arguments are encoded differently::
414 Dictionary arguments are encoded differently::
415
415
416 <argument> <# elements>\n
416 <argument> <# elements>\n
417 <key1> <length1>\n<value1>
417 <key1> <length1>\n<value1>
418 <key2> <length2>\n<value2>
418 <key2> <length2>\n<value2>
419 ...
419 ...
420
420
421 Non-argument data is sent immediately after the final argument value. It is
421 Non-argument data is sent immediately after the final argument value. It is
422 encoded in chunks::
422 encoded in chunks::
423
423
424 <length>\n<data>
424 <length>\n<data>
425
425
426 Each command declares a list of supported arguments and their types. If a
426 Each command declares a list of supported arguments and their types. If a
427 client sends an unknown argument to the server, the server should abort
427 client sends an unknown argument to the server, the server should abort
428 immediately. The special argument ``*`` in a command's definition indicates
428 immediately. The special argument ``*`` in a command's definition indicates
429 that all argument names are allowed.
429 that all argument names are allowed.
430
430
431 The definition of supported arguments and types is initially made when a
431 The definition of supported arguments and types is initially made when a
432 new command is implemented. The client and server must initially independently
432 new command is implemented. The client and server must initially independently
433 agree on the arguments and their types. This initial set of arguments can be
433 agree on the arguments and their types. This initial set of arguments can be
434 supplemented through the presence of *capabilities* advertised by the server.
434 supplemented through the presence of *capabilities* advertised by the server.
435
435
436 Each command has a defined expected response type.
436 Each command has a defined expected response type.
437
437
438 A ``string`` response type is a length framed value. The response consists of
438 A ``string`` response type is a length framed value. The response consists of
439 the string encoded integer length of a value followed by a newline (``\n``)
439 the string encoded integer length of a value followed by a newline (``\n``)
440 followed by the value. Empty values are allowed (and are represented as
440 followed by the value. Empty values are allowed (and are represented as
441 ``0\n``).
441 ``0\n``).
442
442
443 A ``stream`` response type consists of raw bytes of data. There is no framing.
443 A ``stream`` response type consists of raw bytes of data. There is no framing.
444
444
445 A generic error response type is also supported. It consists of a an error
445 A generic error response type is also supported. It consists of a an error
446 message written to ``stderr`` followed by ``\n-\n``. In addition, ``\n`` is
446 message written to ``stderr`` followed by ``\n-\n``. In addition, ``\n`` is
447 written to ``stdout``.
447 written to ``stdout``.
448
448
449 If the server receives an unknown command, it will send an empty ``string``
449 If the server receives an unknown command, it will send an empty ``string``
450 response.
450 response.
451
451
452 The server terminates if it receives an empty command (a ``\n`` character).
452 The server terminates if it receives an empty command (a ``\n`` character).
453
453
454 SSH Version 2 Transport
454 SSH Version 2 Transport
455 -----------------------
455 -----------------------
456
456
457 **Experimental and under development**
457 **Experimental and under development**
458
458
459 Version 2 of the SSH transport behaves identically to version 1 of the SSH
459 Version 2 of the SSH transport behaves identically to version 1 of the SSH
460 transport with the exception of handshake semantics. See above for how
460 transport with the exception of handshake semantics. See above for how
461 version 2 of the SSH transport is negotiated.
461 version 2 of the SSH transport is negotiated.
462
462
463 Immediately following the ``upgraded`` line signaling a switch to version
463 Immediately following the ``upgraded`` line signaling a switch to version
464 2 of the SSH protocol, the server automatically sends additional details
464 2 of the SSH protocol, the server automatically sends additional details
465 about the capabilities of the remote server. This has the form:
465 about the capabilities of the remote server. This has the form:
466
466
467 <integer length of value>\n
467 <integer length of value>\n
468 capabilities: ...\n
468 capabilities: ...\n
469
469
470 e.g.
470 e.g.
471
471
472 s: upgraded 2e82ab3f-9ce3-4b4e-8f8c-6fd1c0e9e23a ssh-v2\n
472 s: upgraded 2e82ab3f-9ce3-4b4e-8f8c-6fd1c0e9e23a ssh-v2\n
473 s: 240\n
473 s: 240\n
474 s: capabilities: known getbundle batch ...\n
474 s: capabilities: known getbundle batch ...\n
475
475
476 Following capabilities advertisement, the peers communicate using version
476 Following capabilities advertisement, the peers communicate using version
477 1 of the SSH transport.
477 1 of the SSH transport.
478
478
479 Unified Frame-Based Protocol
479 Unified Frame-Based Protocol
480 ============================
480 ============================
481
481
482 **Experimental and under development**
482 **Experimental and under development**
483
483
484 The *Unified Frame-Based Protocol* is a communications protocol between
484 The *Unified Frame-Based Protocol* is a communications protocol between
485 Mercurial peers. The protocol aims to be mostly transport agnostic
485 Mercurial peers. The protocol aims to be mostly transport agnostic
486 (works similarly on HTTP, SSH, etc).
486 (works similarly on HTTP, SSH, etc).
487
487
488 To operate the protocol, a bi-directional, half-duplex pipe supporting
488 To operate the protocol, a bi-directional, half-duplex pipe supporting
489 ordered sends and receives is required. That is, each peer has one pipe
489 ordered sends and receives is required. That is, each peer has one pipe
490 for sending data and another for receiving.
490 for sending data and another for receiving.
491
491
492 All data is read and written in atomic units called *frames*. These
492 All data is read and written in atomic units called *frames*. These
493 are conceptually similar to TCP packets. Higher-level functionality
493 are conceptually similar to TCP packets. Higher-level functionality
494 is built on the exchange and processing of frames.
494 is built on the exchange and processing of frames.
495
495
496 All frames are associated with a *stream*. A *stream* provides a
496 All frames are associated with a *stream*. A *stream* provides a
497 unidirectional grouping of frames. Streams facilitate two goals:
497 unidirectional grouping of frames. Streams facilitate two goals:
498 content encoding and parallelism. There is a dedicated section on
498 content encoding and parallelism. There is a dedicated section on
499 streams below.
499 streams below.
500
500
501 The protocol is request-response based: the client issues requests to
501 The protocol is request-response based: the client issues requests to
502 the server, which issues replies to those requests. Server-initiated
502 the server, which issues replies to those requests. Server-initiated
503 messaging is not currently supported, but this specification carves
503 messaging is not currently supported, but this specification carves
504 out room to implement it.
504 out room to implement it.
505
505
506 All frames are associated with a numbered request. Frames can thus
506 All frames are associated with a numbered request. Frames can thus
507 be logically grouped by their request ID.
507 be logically grouped by their request ID.
508
508
509 Frames begin with an 8 octet header followed by a variable length
509 Frames begin with an 8 octet header followed by a variable length
510 payload::
510 payload::
511
511
512 +------------------------------------------------+
512 +------------------------------------------------+
513 | Length (24) |
513 | Length (24) |
514 +--------------------------------+---------------+
514 +--------------------------------+---------------+
515 | Request ID (16) | Stream ID (8) |
515 | Request ID (16) | Stream ID (8) |
516 +------------------+-------------+---------------+
516 +------------------+-------------+---------------+
517 | Stream Flags (8) |
517 | Stream Flags (8) |
518 +-----------+------+
518 +-----------+------+
519 | Type (4) |
519 | Type (4) |
520 +-----------+
520 +-----------+
521 | Flags (4) |
521 | Flags (4) |
522 +===========+===================================================|
522 +===========+===================================================|
523 | Frame Payload (0...) ...
523 | Frame Payload (0...) ...
524 +---------------------------------------------------------------+
524 +---------------------------------------------------------------+
525
525
526 The length of the frame payload is expressed as an unsigned 24 bit
526 The length of the frame payload is expressed as an unsigned 24 bit
527 little endian integer. Values larger than 65535 MUST NOT be used unless
527 little endian integer. Values larger than 65535 MUST NOT be used unless
528 given permission by the server as part of the negotiated capabilities
528 given permission by the server as part of the negotiated capabilities
529 during the handshake. The frame header is not part of the advertised
529 during the handshake. The frame header is not part of the advertised
530 frame length. The payload length is the over-the-wire length. If there
530 frame length. The payload length is the over-the-wire length. If there
531 is content encoding applied to the payload as part of the frame's stream,
531 is content encoding applied to the payload as part of the frame's stream,
532 the length is the output of that content encoding, not the input.
532 the length is the output of that content encoding, not the input.
533
533
534 The 16-bit ``Request ID`` field denotes the integer request identifier,
534 The 16-bit ``Request ID`` field denotes the integer request identifier,
535 stored as an unsigned little endian integer. Odd numbered requests are
535 stored as an unsigned little endian integer. Odd numbered requests are
536 client-initiated. Even numbered requests are server-initiated. This
536 client-initiated. Even numbered requests are server-initiated. This
537 refers to where the *request* was initiated - not where the *frame* was
537 refers to where the *request* was initiated - not where the *frame* was
538 initiated, so servers will send frames with odd ``Request ID`` in
538 initiated, so servers will send frames with odd ``Request ID`` in
539 response to client-initiated requests. Implementations are advised to
539 response to client-initiated requests. Implementations are advised to
540 start ordering request identifiers at ``1`` and ``0``, increment by
540 start ordering request identifiers at ``1`` and ``0``, increment by
541 ``2``, and wrap around if all available numbers have been exhausted.
541 ``2``, and wrap around if all available numbers have been exhausted.
542
542
543 The 8-bit ``Stream ID`` field denotes the stream that the frame is
543 The 8-bit ``Stream ID`` field denotes the stream that the frame is
544 associated with. Frames belonging to a stream may have content
544 associated with. Frames belonging to a stream may have content
545 encoding applied and the receiver may need to decode the raw frame
545 encoding applied and the receiver may need to decode the raw frame
546 payload to obtain the original data. Odd numbered IDs are
546 payload to obtain the original data. Odd numbered IDs are
547 client-initiated. Even numbered IDs are server-initiated.
547 client-initiated. Even numbered IDs are server-initiated.
548
548
549 The 8-bit ``Stream Flags`` field defines stream processing semantics.
549 The 8-bit ``Stream Flags`` field defines stream processing semantics.
550 See the section on streams below.
550 See the section on streams below.
551
551
552 The 4-bit ``Type`` field denotes the type of frame being sent.
552 The 4-bit ``Type`` field denotes the type of frame being sent.
553
553
554 The 4-bit ``Flags`` field defines special, per-type attributes for
554 The 4-bit ``Flags`` field defines special, per-type attributes for
555 the frame.
555 the frame.
556
556
557 The sections below define the frame types and their behavior.
557 The sections below define the frame types and their behavior.
558
558
559 Command Request (``0x01``)
559 Command Request (``0x01``)
560 --------------------------
560 --------------------------
561
561
562 This frame contains a request to run a command.
562 This frame contains a request to run a command.
563
563
564 The name of the command to run constitutes the entirety of the frame
564 The name of the command to run constitutes the entirety of the frame
565 payload.
565 payload.
566
566
567 This frame type MUST ONLY be sent from clients to servers: it is illegal
567 This frame type MUST ONLY be sent from clients to servers: it is illegal
568 for a server to send this frame to a client.
568 for a server to send this frame to a client.
569
569
570 The following flag values are defined for this type:
570 The following flag values are defined for this type:
571
571
572 0x01
572 0x01
573 End of command data. When set, the client will not send any command
573 End of command data. When set, the client will not send any command
574 arguments or additional command data. When set, the command has been
574 arguments or additional command data. When set, the command has been
575 fully issued and the server has the full context to process the command.
575 fully issued and the server has the full context to process the command.
576 The next frame issued by the client is not part of this command.
576 The next frame issued by the client is not part of this command.
577 0x02
577 0x02
578 Command argument frames expected. When set, the client will send
578 Command argument frames expected. When set, the client will send
579 *Command Argument* frames containing command argument data.
579 *Command Argument* frames containing command argument data.
580 0x04
580 0x04
581 Command data frames expected. When set, the client will send
581 Command data frames expected. When set, the client will send
582 *Command Data* frames containing a raw stream of data for this
582 *Command Data* frames containing a raw stream of data for this
583 command.
583 command.
584
584
585 The ``0x01`` flag is mutually exclusive with both the ``0x02`` and ``0x04``
585 The ``0x01`` flag is mutually exclusive with both the ``0x02`` and ``0x04``
586 flags.
586 flags.
587
587
588 Command Argument (``0x02``)
588 Command Argument (``0x02``)
589 ---------------------------
589 ---------------------------
590
590
591 This frame contains a named argument for a command.
591 This frame contains a named argument for a command.
592
592
593 The frame type MUST ONLY be sent from clients to servers: it is illegal
593 The frame type MUST ONLY be sent from clients to servers: it is illegal
594 for a server to send this frame to a client.
594 for a server to send this frame to a client.
595
595
596 The payload consists of:
596 The payload consists of:
597
597
598 * A 16-bit little endian integer denoting the length of the
598 * A 16-bit little endian integer denoting the length of the
599 argument name.
599 argument name.
600 * A 16-bit little endian integer denoting the length of the
600 * A 16-bit little endian integer denoting the length of the
601 argument value.
601 argument value.
602 * N bytes of ASCII data containing the argument name.
602 * N bytes of ASCII data containing the argument name.
603 * N bytes of binary data containing the argument value.
603 * N bytes of binary data containing the argument value.
604
604
605 The payload MUST hold the entirety of the 32-bit header and the
605 The payload MUST hold the entirety of the 32-bit header and the
606 argument name. The argument value MAY span multiple frames. If this
606 argument name. The argument value MAY span multiple frames. If this
607 occurs, the appropriate frame flag should be set to indicate this.
607 occurs, the appropriate frame flag should be set to indicate this.
608
608
609 The following flag values are defined for this type:
609 The following flag values are defined for this type:
610
610
611 0x01
611 0x01
612 Argument data continuation. When set, the data for this argument did
612 Argument data continuation. When set, the data for this argument did
613 not fit in a single frame and the next frame will contain additional
613 not fit in a single frame and the next frame will contain additional
614 argument data.
614 argument data.
615
615
616 0x02
616 0x02
617 End of arguments data. When set, the client will not send any more
617 End of arguments data. When set, the client will not send any more
618 command arguments for the command this frame is associated with.
618 command arguments for the command this frame is associated with.
619 The next frame issued by the client will be command data or
619 The next frame issued by the client will be command data or
620 belong to a separate request.
620 belong to a separate request.
621
621
622 Command Data (``0x03``)
622 Command Data (``0x03``)
623 -----------------------
623 -----------------------
624
624
625 This frame contains raw data for a command.
625 This frame contains raw data for a command.
626
626
627 Most commands can be executed by specifying arguments. However,
627 Most commands can be executed by specifying arguments. However,
628 arguments have an upper bound to their length. For commands that
628 arguments have an upper bound to their length. For commands that
629 accept data that is beyond this length or whose length isn't known
629 accept data that is beyond this length or whose length isn't known
630 when the command is initially sent, they will need to stream
630 when the command is initially sent, they will need to stream
631 arbitrary data to the server. This frame type facilitates the sending
631 arbitrary data to the server. This frame type facilitates the sending
632 of this data.
632 of this data.
633
633
634 The payload of this frame type consists of a stream of raw data to be
634 The payload of this frame type consists of a stream of raw data to be
635 consumed by the command handler on the server. The format of the data
635 consumed by the command handler on the server. The format of the data
636 is command specific.
636 is command specific.
637
637
638 The following flag values are defined for this type:
638 The following flag values are defined for this type:
639
639
640 0x01
640 0x01
641 Command data continuation. When set, the data for this command
641 Command data continuation. When set, the data for this command
642 continues into a subsequent frame.
642 continues into a subsequent frame.
643
643
644 0x02
644 0x02
645 End of data. When set, command data has been fully sent to the
645 End of data. When set, command data has been fully sent to the
646 server. The command has been fully issued and no new data for this
646 server. The command has been fully issued and no new data for this
647 command will be sent. The next frame will belong to a new command.
647 command will be sent. The next frame will belong to a new command.
648
648
649 Bytes Response Data (``0x04``)
649 Bytes Response Data (``0x04``)
650 ------------------------------
650 ------------------------------
651
651
652 This frame contains raw bytes response data to an issued command.
652 This frame contains raw bytes response data to an issued command.
653
653
654 The following flag values are defined for this type:
654 The following flag values are defined for this type:
655
655
656 0x01
656 0x01
657 Data continuation. When set, an additional frame containing raw
657 Data continuation. When set, an additional frame containing raw
658 response data will follow.
658 response data will follow.
659 0x02
659 0x02
660 End of data. When sent, the response data has been fully sent and
660 End of data. When sent, the response data has been fully sent and
661 no additional frames for this response will be sent.
661 no additional frames for this response will be sent.
662
662
663 The ``0x01`` flag is mutually exclusive with the ``0x02`` flag.
663 The ``0x01`` flag is mutually exclusive with the ``0x02`` flag.
664
664
665 Error Response (``0x05``)
665 Error Response (``0x05``)
666 -------------------------
666 -------------------------
667
667
668 An error occurred when processing a request. This could indicate
668 An error occurred when processing a request. This could indicate
669 a protocol-level failure or an application level failure depending
669 a protocol-level failure or an application level failure depending
670 on the flags for this message type.
670 on the flags for this message type.
671
671
672 The payload for this type is an error message that should be
672 The payload for this type is an error message that should be
673 displayed to the user.
673 displayed to the user.
674
674
675 The following flag values are defined for this type:
675 The following flag values are defined for this type:
676
676
677 0x01
677 0x01
678 The error occurred at the transport/protocol level. If set, the
678 The error occurred at the transport/protocol level. If set, the
679 connection should be closed.
679 connection should be closed.
680 0x02
680 0x02
681 The error occurred at the application level. e.g. invalid command.
681 The error occurred at the application level. e.g. invalid command.
682
682
683 Human Output Side-Channel (``0x06``)
683 Human Output Side-Channel (``0x06``)
684 ------------------------------------
684 ------------------------------------
685
685
686 This frame contains a message that is intended to be displayed to
686 This frame contains a message that is intended to be displayed to
687 people. Whereas most frames communicate machine readable data, this
687 people. Whereas most frames communicate machine readable data, this
688 frame communicates textual data that is intended to be shown to
688 frame communicates textual data that is intended to be shown to
689 humans.
689 humans.
690
690
691 The frame consists of a series of *formatting requests*. Each formatting
691 The frame consists of a series of *formatting requests*. Each formatting
692 request consists of a formatting string, arguments for that formatting
692 request consists of a formatting string, arguments for that formatting
693 string, and labels to apply to that formatting string.
693 string, and labels to apply to that formatting string.
694
694
695 A formatting string is a printf()-like string that allows variable
695 A formatting string is a printf()-like string that allows variable
696 substitution within the string. Labels allow the rendered text to be
696 substitution within the string. Labels allow the rendered text to be
697 *decorated*. Assuming use of the canonical Mercurial code base, a
697 *decorated*. Assuming use of the canonical Mercurial code base, a
698 formatting string can be the input to the ``i18n._`` function. This
698 formatting string can be the input to the ``i18n._`` function. This
699 allows messages emitted from the server to be localized. So even if
699 allows messages emitted from the server to be localized. So even if
700 the server has different i18n settings, people could see messages in
700 the server has different i18n settings, people could see messages in
701 their *native* settings. Similarly, the use of labels allows
701 their *native* settings. Similarly, the use of labels allows
702 decorations like coloring and underlining to be applied using the
702 decorations like coloring and underlining to be applied using the
703 client's configured rendering settings.
703 client's configured rendering settings.
704
704
705 Formatting strings are similar to ``printf()`` strings or how
705 Formatting strings are similar to ``printf()`` strings or how
706 Python's ``%`` operator works. The only supported formatting sequences
706 Python's ``%`` operator works. The only supported formatting sequences
707 are ``%s`` and ``%%``. ``%s`` will be replaced by whatever the string
707 are ``%s`` and ``%%``. ``%s`` will be replaced by whatever the string
708 at that position resolves to. ``%%`` will be replaced by ``%``. All
708 at that position resolves to. ``%%`` will be replaced by ``%``. All
709 other 2-byte sequences beginning with ``%`` represent a literal
709 other 2-byte sequences beginning with ``%`` represent a literal
710 ``%`` followed by that character. However, future versions of the
710 ``%`` followed by that character. However, future versions of the
711 wire protocol reserve the right to allow clients to opt in to receiving
711 wire protocol reserve the right to allow clients to opt in to receiving
712 formatting strings with additional formatters, hence why ``%%`` is
712 formatting strings with additional formatters, hence why ``%%`` is
713 required to represent the literal ``%``.
713 required to represent the literal ``%``.
714
714
715 The raw frame consists of a series of data structures representing
715 The raw frame consists of a series of data structures representing
716 textual atoms to print. Each atom begins with a struct defining the
716 textual atoms to print. Each atom begins with a struct defining the
717 size of the data that follows:
717 size of the data that follows:
718
718
719 * A 16-bit little endian unsigned integer denoting the length of the
719 * A 16-bit little endian unsigned integer denoting the length of the
720 formatting string.
720 formatting string.
721 * An 8-bit unsigned integer denoting the number of label strings
721 * An 8-bit unsigned integer denoting the number of label strings
722 that follow.
722 that follow.
723 * An 8-bit unsigned integer denoting the number of formatting string
723 * An 8-bit unsigned integer denoting the number of formatting string
724 arguments strings that follow.
724 arguments strings that follow.
725 * An array of 8-bit unsigned integers denoting the lengths of
725 * An array of 8-bit unsigned integers denoting the lengths of
726 *labels* data.
726 *labels* data.
727 * An array of 16-bit unsigned integers denoting the lengths of
727 * An array of 16-bit unsigned integers denoting the lengths of
728 formatting strings.
728 formatting strings.
729 * The formatting string, encoded as UTF-8.
729 * The formatting string, encoded as UTF-8.
730 * 0 or more ASCII strings defining labels to apply to this atom.
730 * 0 or more ASCII strings defining labels to apply to this atom.
731 * 0 or more UTF-8 strings that will be used as arguments to the
731 * 0 or more UTF-8 strings that will be used as arguments to the
732 formatting string.
732 formatting string.
733
733
734 TODO use ASCII for formatting string.
734 TODO use ASCII for formatting string.
735
735
736 All data to be printed MUST be encoded into a single frame: this frame
736 All data to be printed MUST be encoded into a single frame: this frame
737 does not support spanning data across multiple frames.
737 does not support spanning data across multiple frames.
738
738
739 All textual data encoded in these frames is assumed to be line delimited.
739 All textual data encoded in these frames is assumed to be line delimited.
740 The last atom in the frame SHOULD end with a newline (``\n``). If it
740 The last atom in the frame SHOULD end with a newline (``\n``). If it
741 doesn't, clients MAY add a newline to facilitate immediate printing.
741 doesn't, clients MAY add a newline to facilitate immediate printing.
742
742
743 Progress Update (``0x07``)
744 --------------------------
745
746 This frame holds the progress of an operation on the peer. Consumption
747 of these frames allows clients to display progress bars, estimated
748 completion times, etc.
749
750 Each frame defines the progress of a single operation on the peer. The
751 payload consists of a CBOR map with the following bytestring keys:
752
753 topic
754 Topic name (string)
755 pos
756 Current numeric position within the topic (integer)
757 total
758 Total/end numeric position of this topic (unsigned integer)
759 label (optional)
760 Unit label (string)
761 item (optional)
762 Item name (string)
763
764 Progress state is created when a frame is received referencing a
765 *topic* that isn't currently tracked. Progress tracking for that
766 *topic* is finished when a frame is received reporting the current
767 position of that topic as ``-1``.
768
769 Multiple *topics* may be active at any given time.
770
771 Rendering of progress information is not mandated or governed by this
772 specification: implementations MAY render progress information however
773 they see fit, including not at all.
774
775 The string data describing the topic SHOULD be static strings to
776 facilitate receivers localizing that string data. The emitter
777 MUST normalize all string data to valid UTF-8 and receivers SHOULD
778 validate that received data conforms to UTF-8. The topic name
779 SHOULD be ASCII.
780
743 Stream Encoding Settings (``0x08``)
781 Stream Encoding Settings (``0x08``)
744 -----------------------------------
782 -----------------------------------
745
783
746 This frame type holds information defining the content encoding
784 This frame type holds information defining the content encoding
747 settings for a *stream*.
785 settings for a *stream*.
748
786
749 This frame type is likely consumed by the protocol layer and is not
787 This frame type is likely consumed by the protocol layer and is not
750 passed on to applications.
788 passed on to applications.
751
789
752 This frame type MUST ONLY occur on frames having the *Beginning of Stream*
790 This frame type MUST ONLY occur on frames having the *Beginning of Stream*
753 ``Stream Flag`` set.
791 ``Stream Flag`` set.
754
792
755 The payload of this frame defines what content encoding has (possibly)
793 The payload of this frame defines what content encoding has (possibly)
756 been applied to the payloads of subsequent frames in this stream.
794 been applied to the payloads of subsequent frames in this stream.
757
795
758 The payload begins with an 8-bit integer defining the length of the
796 The payload begins with an 8-bit integer defining the length of the
759 encoding *profile*, followed by the string name of that profile, which
797 encoding *profile*, followed by the string name of that profile, which
760 must be an ASCII string. All bytes that follow can be used by that
798 must be an ASCII string. All bytes that follow can be used by that
761 profile for supplemental settings definitions. See the section below
799 profile for supplemental settings definitions. See the section below
762 on defined encoding profiles.
800 on defined encoding profiles.
763
801
764 Stream States and Flags
802 Stream States and Flags
765 -----------------------
803 -----------------------
766
804
767 Streams can be in two states: *open* and *closed*. An *open* stream
805 Streams can be in two states: *open* and *closed*. An *open* stream
768 is active and frames attached to that stream could arrive at any time.
806 is active and frames attached to that stream could arrive at any time.
769 A *closed* stream is not active. If a frame attached to a *closed*
807 A *closed* stream is not active. If a frame attached to a *closed*
770 stream arrives, that frame MUST have an appropriate stream flag
808 stream arrives, that frame MUST have an appropriate stream flag
771 set indicating beginning of stream. All streams are in the *closed*
809 set indicating beginning of stream. All streams are in the *closed*
772 state by default.
810 state by default.
773
811
774 The ``Stream Flags`` field denotes a set of bit flags for defining
812 The ``Stream Flags`` field denotes a set of bit flags for defining
775 the relationship of this frame within a stream. The following flags
813 the relationship of this frame within a stream. The following flags
776 are defined:
814 are defined:
777
815
778 0x01
816 0x01
779 Beginning of stream. The first frame in the stream MUST set this
817 Beginning of stream. The first frame in the stream MUST set this
780 flag. When received, the ``Stream ID`` this frame is attached to
818 flag. When received, the ``Stream ID`` this frame is attached to
781 becomes ``open``.
819 becomes ``open``.
782
820
783 0x02
821 0x02
784 End of stream. The last frame in a stream MUST set this flag. When
822 End of stream. The last frame in a stream MUST set this flag. When
785 received, the ``Stream ID`` this frame is attached to becomes
823 received, the ``Stream ID`` this frame is attached to becomes
786 ``closed``. Any content encoding context associated with this stream
824 ``closed``. Any content encoding context associated with this stream
787 can be destroyed after processing the payload of this frame.
825 can be destroyed after processing the payload of this frame.
788
826
789 0x04
827 0x04
790 Apply content encoding. When set, any content encoding settings
828 Apply content encoding. When set, any content encoding settings
791 defined by the stream should be applied when attempting to read
829 defined by the stream should be applied when attempting to read
792 the frame. When not set, the frame payload isn't encoded.
830 the frame. When not set, the frame payload isn't encoded.
793
831
794 Streams
832 Streams
795 -------
833 -------
796
834
797 Streams - along with ``Request IDs`` - facilitate grouping of frames.
835 Streams - along with ``Request IDs`` - facilitate grouping of frames.
798 But the purpose of each is quite different and the groupings they
836 But the purpose of each is quite different and the groupings they
799 constitute are independent.
837 constitute are independent.
800
838
801 A ``Request ID`` is essentially a tag. It tells you which logical
839 A ``Request ID`` is essentially a tag. It tells you which logical
802 request a frame is associated with.
840 request a frame is associated with.
803
841
804 A *stream* is a sequence of frames grouped for the express purpose
842 A *stream* is a sequence of frames grouped for the express purpose
805 of applying a stateful encoding or for denoting sub-groups of frames.
843 of applying a stateful encoding or for denoting sub-groups of frames.
806
844
807 Unlike ``Request ID``s which span the request and response, a stream
845 Unlike ``Request ID``s which span the request and response, a stream
808 is unidirectional and stream IDs are independent from client to
846 is unidirectional and stream IDs are independent from client to
809 server.
847 server.
810
848
811 There is no strict hierarchical relationship between ``Request IDs``
849 There is no strict hierarchical relationship between ``Request IDs``
812 and *streams*. A stream can contain frames having multiple
850 and *streams*. A stream can contain frames having multiple
813 ``Request IDs``. Frames belonging to the same ``Request ID`` can
851 ``Request IDs``. Frames belonging to the same ``Request ID`` can
814 span multiple streams.
852 span multiple streams.
815
853
816 One goal of streams is to facilitate content encoding. A stream can
854 One goal of streams is to facilitate content encoding. A stream can
817 define an encoding to be applied to frame payloads. For example, the
855 define an encoding to be applied to frame payloads. For example, the
818 payload transmitted over the wire may contain output from a
856 payload transmitted over the wire may contain output from a
819 zstandard compression operation and the receiving end may decompress
857 zstandard compression operation and the receiving end may decompress
820 that payload to obtain the original data.
858 that payload to obtain the original data.
821
859
822 The other goal of streams is to facilitate concurrent execution. For
860 The other goal of streams is to facilitate concurrent execution. For
823 example, a server could spawn 4 threads to service a request that can
861 example, a server could spawn 4 threads to service a request that can
824 be easily parallelized. Each of those 4 threads could write into its
862 be easily parallelized. Each of those 4 threads could write into its
825 own stream. Those streams could then in turn be delivered to 4 threads
863 own stream. Those streams could then in turn be delivered to 4 threads
826 on the receiving end, with each thread consuming its stream in near
864 on the receiving end, with each thread consuming its stream in near
827 isolation. The *main* thread on both ends merely does I/O and
865 isolation. The *main* thread on both ends merely does I/O and
828 encodes/decodes frame headers: the bulk of the work is done by worker
866 encodes/decodes frame headers: the bulk of the work is done by worker
829 threads.
867 threads.
830
868
831 In addition, since content encoding is defined per stream, each
869 In addition, since content encoding is defined per stream, each
832 *worker thread* could perform potentially CPU bound work concurrently
870 *worker thread* could perform potentially CPU bound work concurrently
833 with other threads. This approach of applying encoding at the
871 with other threads. This approach of applying encoding at the
834 sub-protocol / stream level eliminates a potential resource constraint
872 sub-protocol / stream level eliminates a potential resource constraint
835 on the protocol stream as a whole (it is common for the throughput of
873 on the protocol stream as a whole (it is common for the throughput of
836 a compression engine to be smaller than the throughput of a network).
874 a compression engine to be smaller than the throughput of a network).
837
875
838 Having multiple streams - each with their own encoding settings - also
876 Having multiple streams - each with their own encoding settings - also
839 facilitates the use of advanced data compression techniques. For
877 facilitates the use of advanced data compression techniques. For
840 example, a transmitter could see that it is generating data faster
878 example, a transmitter could see that it is generating data faster
841 and slower than the receiving end is consuming it and adjust its
879 and slower than the receiving end is consuming it and adjust its
842 compression settings to trade CPU for compression ratio accordingly.
880 compression settings to trade CPU for compression ratio accordingly.
843
881
844 While streams can define a content encoding, not all frames within
882 While streams can define a content encoding, not all frames within
845 that stream must use that content encoding. This can be useful when
883 that stream must use that content encoding. This can be useful when
846 data is being served from caches and being derived dynamically. A
884 data is being served from caches and being derived dynamically. A
847 cache could pre-compressed data so the server doesn't have to
885 cache could pre-compressed data so the server doesn't have to
848 recompress it. The ability to pick and choose which frames are
886 recompress it. The ability to pick and choose which frames are
849 compressed allows servers to easily send data to the wire without
887 compressed allows servers to easily send data to the wire without
850 involving potentially expensive encoding overhead.
888 involving potentially expensive encoding overhead.
851
889
852 Content Encoding Profiles
890 Content Encoding Profiles
853 -------------------------
891 -------------------------
854
892
855 Streams can have named content encoding *profiles* associated with
893 Streams can have named content encoding *profiles* associated with
856 them. A profile defines a shared understanding of content encoding
894 them. A profile defines a shared understanding of content encoding
857 settings and behavior.
895 settings and behavior.
858
896
859 The following profiles are defined:
897 The following profiles are defined:
860
898
861 TBD
899 TBD
862
900
863 Issuing Commands
901 Issuing Commands
864 ----------------
902 ----------------
865
903
866 A client can request that a remote run a command by sending it
904 A client can request that a remote run a command by sending it
867 frames defining that command. This logical stream is composed of
905 frames defining that command. This logical stream is composed of
868 1 ``Command Request`` frame, 0 or more ``Command Argument`` frames,
906 1 ``Command Request`` frame, 0 or more ``Command Argument`` frames,
869 and 0 or more ``Command Data`` frames.
907 and 0 or more ``Command Data`` frames.
870
908
871 All frames composing a single command request MUST be associated with
909 All frames composing a single command request MUST be associated with
872 the same ``Request ID``.
910 the same ``Request ID``.
873
911
874 Clients MAY send additional command requests without waiting on the
912 Clients MAY send additional command requests without waiting on the
875 response to a previous command request. If they do so, they MUST ensure
913 response to a previous command request. If they do so, they MUST ensure
876 that the ``Request ID`` field of outbound frames does not conflict
914 that the ``Request ID`` field of outbound frames does not conflict
877 with that of an active ``Request ID`` whose response has not yet been
915 with that of an active ``Request ID`` whose response has not yet been
878 fully received.
916 fully received.
879
917
880 Servers MAY respond to commands in a different order than they were
918 Servers MAY respond to commands in a different order than they were
881 sent over the wire. Clients MUST be prepared to deal with this. Servers
919 sent over the wire. Clients MUST be prepared to deal with this. Servers
882 also MAY start executing commands in a different order than they were
920 also MAY start executing commands in a different order than they were
883 received, or MAY execute multiple commands concurrently.
921 received, or MAY execute multiple commands concurrently.
884
922
885 If there is a dependency between commands or a race condition between
923 If there is a dependency between commands or a race condition between
886 commands executing (e.g. a read-only command that depends on the results
924 commands executing (e.g. a read-only command that depends on the results
887 of a command that mutates the repository), then clients MUST NOT send
925 of a command that mutates the repository), then clients MUST NOT send
888 frames issuing a command until a response to all dependent commands has
926 frames issuing a command until a response to all dependent commands has
889 been received.
927 been received.
890 TODO think about whether we should express dependencies between commands
928 TODO think about whether we should express dependencies between commands
891 to avoid roundtrip latency.
929 to avoid roundtrip latency.
892
930
893 Argument frames are the recommended mechanism for transferring fixed
931 Argument frames are the recommended mechanism for transferring fixed
894 sets of parameters to a command. Data frames are appropriate for
932 sets of parameters to a command. Data frames are appropriate for
895 transferring variable data. A similar comparison would be to HTTP:
933 transferring variable data. A similar comparison would be to HTTP:
896 argument frames are headers and the message body is data frames.
934 argument frames are headers and the message body is data frames.
897
935
898 It is recommended for servers to delay the dispatch of a command
936 It is recommended for servers to delay the dispatch of a command
899 until all argument frames for that command have been received. Servers
937 until all argument frames for that command have been received. Servers
900 MAY impose limits on the maximum argument size.
938 MAY impose limits on the maximum argument size.
901 TODO define failure mechanism.
939 TODO define failure mechanism.
902
940
903 Servers MAY dispatch to commands immediately once argument data
941 Servers MAY dispatch to commands immediately once argument data
904 is available or delay until command data is received in full.
942 is available or delay until command data is received in full.
905
943
906 Capabilities
944 Capabilities
907 ============
945 ============
908
946
909 Servers advertise supported wire protocol features. This allows clients to
947 Servers advertise supported wire protocol features. This allows clients to
910 probe for server features before blindly calling a command or passing a
948 probe for server features before blindly calling a command or passing a
911 specific argument.
949 specific argument.
912
950
913 The server's features are exposed via a *capabilities* string. This is a
951 The server's features are exposed via a *capabilities* string. This is a
914 space-delimited string of tokens/features. Some features are single words
952 space-delimited string of tokens/features. Some features are single words
915 like ``lookup`` or ``batch``. Others are complicated key-value pairs
953 like ``lookup`` or ``batch``. Others are complicated key-value pairs
916 advertising sub-features. e.g. ``httpheader=2048``. When complex, non-word
954 advertising sub-features. e.g. ``httpheader=2048``. When complex, non-word
917 values are used, each feature name can define its own encoding of sub-values.
955 values are used, each feature name can define its own encoding of sub-values.
918 Comma-delimited and ``x-www-form-urlencoded`` values are common.
956 Comma-delimited and ``x-www-form-urlencoded`` values are common.
919
957
920 The following document capabilities defined by the canonical Mercurial server
958 The following document capabilities defined by the canonical Mercurial server
921 implementation.
959 implementation.
922
960
923 batch
961 batch
924 -----
962 -----
925
963
926 Whether the server supports the ``batch`` command.
964 Whether the server supports the ``batch`` command.
927
965
928 This capability/command was introduced in Mercurial 1.9 (released July 2011).
966 This capability/command was introduced in Mercurial 1.9 (released July 2011).
929
967
930 branchmap
968 branchmap
931 ---------
969 ---------
932
970
933 Whether the server supports the ``branchmap`` command.
971 Whether the server supports the ``branchmap`` command.
934
972
935 This capability/command was introduced in Mercurial 1.3 (released July 2009).
973 This capability/command was introduced in Mercurial 1.3 (released July 2009).
936
974
937 bundle2-exp
975 bundle2-exp
938 -----------
976 -----------
939
977
940 Precursor to ``bundle2`` capability that was used before bundle2 was a
978 Precursor to ``bundle2`` capability that was used before bundle2 was a
941 stable feature.
979 stable feature.
942
980
943 This capability was introduced in Mercurial 3.0 behind an experimental
981 This capability was introduced in Mercurial 3.0 behind an experimental
944 flag. This capability should not be observed in the wild.
982 flag. This capability should not be observed in the wild.
945
983
946 bundle2
984 bundle2
947 -------
985 -------
948
986
949 Indicates whether the server supports the ``bundle2`` data exchange format.
987 Indicates whether the server supports the ``bundle2`` data exchange format.
950
988
951 The value of the capability is a URL quoted, newline (``\n``) delimited
989 The value of the capability is a URL quoted, newline (``\n``) delimited
952 list of keys or key-value pairs.
990 list of keys or key-value pairs.
953
991
954 A key is simply a URL encoded string.
992 A key is simply a URL encoded string.
955
993
956 A key-value pair is a URL encoded key separated from a URL encoded value by
994 A key-value pair is a URL encoded key separated from a URL encoded value by
957 an ``=``. If the value is a list, elements are delimited by a ``,`` after
995 an ``=``. If the value is a list, elements are delimited by a ``,`` after
958 URL encoding.
996 URL encoding.
959
997
960 For example, say we have the values::
998 For example, say we have the values::
961
999
962 {'HG20': [], 'changegroup': ['01', '02'], 'digests': ['sha1', 'sha512']}
1000 {'HG20': [], 'changegroup': ['01', '02'], 'digests': ['sha1', 'sha512']}
963
1001
964 We would first construct a string::
1002 We would first construct a string::
965
1003
966 HG20\nchangegroup=01,02\ndigests=sha1,sha512
1004 HG20\nchangegroup=01,02\ndigests=sha1,sha512
967
1005
968 We would then URL quote this string::
1006 We would then URL quote this string::
969
1007
970 HG20%0Achangegroup%3D01%2C02%0Adigests%3Dsha1%2Csha512
1008 HG20%0Achangegroup%3D01%2C02%0Adigests%3Dsha1%2Csha512
971
1009
972 This capability was introduced in Mercurial 3.4 (released May 2015).
1010 This capability was introduced in Mercurial 3.4 (released May 2015).
973
1011
974 changegroupsubset
1012 changegroupsubset
975 -----------------
1013 -----------------
976
1014
977 Whether the server supports the ``changegroupsubset`` command.
1015 Whether the server supports the ``changegroupsubset`` command.
978
1016
979 This capability was introduced in Mercurial 0.9.2 (released December
1017 This capability was introduced in Mercurial 0.9.2 (released December
980 2006).
1018 2006).
981
1019
982 This capability was introduced at the same time as the ``lookup``
1020 This capability was introduced at the same time as the ``lookup``
983 capability/command.
1021 capability/command.
984
1022
985 compression
1023 compression
986 -----------
1024 -----------
987
1025
988 Declares support for negotiating compression formats.
1026 Declares support for negotiating compression formats.
989
1027
990 Presence of this capability indicates the server supports dynamic selection
1028 Presence of this capability indicates the server supports dynamic selection
991 of compression formats based on the client request.
1029 of compression formats based on the client request.
992
1030
993 Servers advertising this capability are required to support the
1031 Servers advertising this capability are required to support the
994 ``application/mercurial-0.2`` media type in response to commands returning
1032 ``application/mercurial-0.2`` media type in response to commands returning
995 streams. Servers may support this media type on any command.
1033 streams. Servers may support this media type on any command.
996
1034
997 The value of the capability is a comma-delimited list of strings declaring
1035 The value of the capability is a comma-delimited list of strings declaring
998 supported compression formats. The order of the compression formats is in
1036 supported compression formats. The order of the compression formats is in
999 server-preferred order, most preferred first.
1037 server-preferred order, most preferred first.
1000
1038
1001 The identifiers used by the official Mercurial distribution are:
1039 The identifiers used by the official Mercurial distribution are:
1002
1040
1003 bzip2
1041 bzip2
1004 bzip2
1042 bzip2
1005 none
1043 none
1006 uncompressed / raw data
1044 uncompressed / raw data
1007 zlib
1045 zlib
1008 zlib (no gzip header)
1046 zlib (no gzip header)
1009 zstd
1047 zstd
1010 zstd
1048 zstd
1011
1049
1012 This capability was introduced in Mercurial 4.1 (released February 2017).
1050 This capability was introduced in Mercurial 4.1 (released February 2017).
1013
1051
1014 getbundle
1052 getbundle
1015 ---------
1053 ---------
1016
1054
1017 Whether the server supports the ``getbundle`` command.
1055 Whether the server supports the ``getbundle`` command.
1018
1056
1019 This capability was introduced in Mercurial 1.9 (released July 2011).
1057 This capability was introduced in Mercurial 1.9 (released July 2011).
1020
1058
1021 httpheader
1059 httpheader
1022 ----------
1060 ----------
1023
1061
1024 Whether the server supports receiving command arguments via HTTP request
1062 Whether the server supports receiving command arguments via HTTP request
1025 headers.
1063 headers.
1026
1064
1027 The value of the capability is an integer describing the max header
1065 The value of the capability is an integer describing the max header
1028 length that clients should send. Clients should ignore any content after a
1066 length that clients should send. Clients should ignore any content after a
1029 comma in the value, as this is reserved for future use.
1067 comma in the value, as this is reserved for future use.
1030
1068
1031 This capability was introduced in Mercurial 1.9 (released July 2011).
1069 This capability was introduced in Mercurial 1.9 (released July 2011).
1032
1070
1033 httpmediatype
1071 httpmediatype
1034 -------------
1072 -------------
1035
1073
1036 Indicates which HTTP media types (``Content-Type`` header) the server is
1074 Indicates which HTTP media types (``Content-Type`` header) the server is
1037 capable of receiving and sending.
1075 capable of receiving and sending.
1038
1076
1039 The value of the capability is a comma-delimited list of strings identifying
1077 The value of the capability is a comma-delimited list of strings identifying
1040 support for media type and transmission direction. The following strings may
1078 support for media type and transmission direction. The following strings may
1041 be present:
1079 be present:
1042
1080
1043 0.1rx
1081 0.1rx
1044 Indicates server support for receiving ``application/mercurial-0.1`` media
1082 Indicates server support for receiving ``application/mercurial-0.1`` media
1045 types.
1083 types.
1046
1084
1047 0.1tx
1085 0.1tx
1048 Indicates server support for sending ``application/mercurial-0.1`` media
1086 Indicates server support for sending ``application/mercurial-0.1`` media
1049 types.
1087 types.
1050
1088
1051 0.2rx
1089 0.2rx
1052 Indicates server support for receiving ``application/mercurial-0.2`` media
1090 Indicates server support for receiving ``application/mercurial-0.2`` media
1053 types.
1091 types.
1054
1092
1055 0.2tx
1093 0.2tx
1056 Indicates server support for sending ``application/mercurial-0.2`` media
1094 Indicates server support for sending ``application/mercurial-0.2`` media
1057 types.
1095 types.
1058
1096
1059 minrx=X
1097 minrx=X
1060 Minimum media type version the server is capable of receiving. Value is a
1098 Minimum media type version the server is capable of receiving. Value is a
1061 string like ``0.2``.
1099 string like ``0.2``.
1062
1100
1063 This capability can be used by servers to limit connections from legacy
1101 This capability can be used by servers to limit connections from legacy
1064 clients not using the latest supported media type. However, only clients
1102 clients not using the latest supported media type. However, only clients
1065 with knowledge of this capability will know to consult this value. This
1103 with knowledge of this capability will know to consult this value. This
1066 capability is present so the client may issue a more user-friendly error
1104 capability is present so the client may issue a more user-friendly error
1067 when the server has locked out a legacy client.
1105 when the server has locked out a legacy client.
1068
1106
1069 mintx=X
1107 mintx=X
1070 Minimum media type version the server is capable of sending. Value is a
1108 Minimum media type version the server is capable of sending. Value is a
1071 string like ``0.1``.
1109 string like ``0.1``.
1072
1110
1073 Servers advertising support for the ``application/mercurial-0.2`` media type
1111 Servers advertising support for the ``application/mercurial-0.2`` media type
1074 should also advertise the ``compression`` capability.
1112 should also advertise the ``compression`` capability.
1075
1113
1076 This capability was introduced in Mercurial 4.1 (released February 2017).
1114 This capability was introduced in Mercurial 4.1 (released February 2017).
1077
1115
1078 httppostargs
1116 httppostargs
1079 ------------
1117 ------------
1080
1118
1081 **Experimental**
1119 **Experimental**
1082
1120
1083 Indicates that the server supports and prefers clients send command arguments
1121 Indicates that the server supports and prefers clients send command arguments
1084 via a HTTP POST request as part of the request body.
1122 via a HTTP POST request as part of the request body.
1085
1123
1086 This capability was introduced in Mercurial 3.8 (released May 2016).
1124 This capability was introduced in Mercurial 3.8 (released May 2016).
1087
1125
1088 known
1126 known
1089 -----
1127 -----
1090
1128
1091 Whether the server supports the ``known`` command.
1129 Whether the server supports the ``known`` command.
1092
1130
1093 This capability/command was introduced in Mercurial 1.9 (released July 2011).
1131 This capability/command was introduced in Mercurial 1.9 (released July 2011).
1094
1132
1095 lookup
1133 lookup
1096 ------
1134 ------
1097
1135
1098 Whether the server supports the ``lookup`` command.
1136 Whether the server supports the ``lookup`` command.
1099
1137
1100 This capability was introduced in Mercurial 0.9.2 (released December
1138 This capability was introduced in Mercurial 0.9.2 (released December
1101 2006).
1139 2006).
1102
1140
1103 This capability was introduced at the same time as the ``changegroupsubset``
1141 This capability was introduced at the same time as the ``changegroupsubset``
1104 capability/command.
1142 capability/command.
1105
1143
1106 pushkey
1144 pushkey
1107 -------
1145 -------
1108
1146
1109 Whether the server supports the ``pushkey`` and ``listkeys`` commands.
1147 Whether the server supports the ``pushkey`` and ``listkeys`` commands.
1110
1148
1111 This capability was introduced in Mercurial 1.6 (released July 2010).
1149 This capability was introduced in Mercurial 1.6 (released July 2010).
1112
1150
1113 standardbundle
1151 standardbundle
1114 --------------
1152 --------------
1115
1153
1116 **Unsupported**
1154 **Unsupported**
1117
1155
1118 This capability was introduced during the Mercurial 0.9.2 development cycle in
1156 This capability was introduced during the Mercurial 0.9.2 development cycle in
1119 2006. It was never present in a release, as it was replaced by the ``unbundle``
1157 2006. It was never present in a release, as it was replaced by the ``unbundle``
1120 capability. This capability should not be encountered in the wild.
1158 capability. This capability should not be encountered in the wild.
1121
1159
1122 stream-preferred
1160 stream-preferred
1123 ----------------
1161 ----------------
1124
1162
1125 If present the server prefers that clients clone using the streaming clone
1163 If present the server prefers that clients clone using the streaming clone
1126 protocol (``hg clone --stream``) rather than the standard
1164 protocol (``hg clone --stream``) rather than the standard
1127 changegroup/bundle based protocol.
1165 changegroup/bundle based protocol.
1128
1166
1129 This capability was introduced in Mercurial 2.2 (released May 2012).
1167 This capability was introduced in Mercurial 2.2 (released May 2012).
1130
1168
1131 streamreqs
1169 streamreqs
1132 ----------
1170 ----------
1133
1171
1134 Indicates whether the server supports *streaming clones* and the *requirements*
1172 Indicates whether the server supports *streaming clones* and the *requirements*
1135 that clients must support to receive it.
1173 that clients must support to receive it.
1136
1174
1137 If present, the server supports the ``stream_out`` command, which transmits
1175 If present, the server supports the ``stream_out`` command, which transmits
1138 raw revlogs from the repository instead of changegroups. This provides a faster
1176 raw revlogs from the repository instead of changegroups. This provides a faster
1139 cloning mechanism at the expense of more bandwidth used.
1177 cloning mechanism at the expense of more bandwidth used.
1140
1178
1141 The value of this capability is a comma-delimited list of repo format
1179 The value of this capability is a comma-delimited list of repo format
1142 *requirements*. These are requirements that impact the reading of data in
1180 *requirements*. These are requirements that impact the reading of data in
1143 the ``.hg/store`` directory. An example value is
1181 the ``.hg/store`` directory. An example value is
1144 ``streamreqs=generaldelta,revlogv1`` indicating the server repo requires
1182 ``streamreqs=generaldelta,revlogv1`` indicating the server repo requires
1145 the ``revlogv1`` and ``generaldelta`` requirements.
1183 the ``revlogv1`` and ``generaldelta`` requirements.
1146
1184
1147 If the only format requirement is ``revlogv1``, the server may expose the
1185 If the only format requirement is ``revlogv1``, the server may expose the
1148 ``stream`` capability instead of the ``streamreqs`` capability.
1186 ``stream`` capability instead of the ``streamreqs`` capability.
1149
1187
1150 This capability was introduced in Mercurial 1.7 (released November 2010).
1188 This capability was introduced in Mercurial 1.7 (released November 2010).
1151
1189
1152 stream
1190 stream
1153 ------
1191 ------
1154
1192
1155 Whether the server supports *streaming clones* from ``revlogv1`` repos.
1193 Whether the server supports *streaming clones* from ``revlogv1`` repos.
1156
1194
1157 If present, the server supports the ``stream_out`` command, which transmits
1195 If present, the server supports the ``stream_out`` command, which transmits
1158 raw revlogs from the repository instead of changegroups. This provides a faster
1196 raw revlogs from the repository instead of changegroups. This provides a faster
1159 cloning mechanism at the expense of more bandwidth used.
1197 cloning mechanism at the expense of more bandwidth used.
1160
1198
1161 This capability was introduced in Mercurial 0.9.1 (released July 2006).
1199 This capability was introduced in Mercurial 0.9.1 (released July 2006).
1162
1200
1163 When initially introduced, the value of the capability was the numeric
1201 When initially introduced, the value of the capability was the numeric
1164 revlog revision. e.g. ``stream=1``. This indicates the changegroup is using
1202 revlog revision. e.g. ``stream=1``. This indicates the changegroup is using
1165 ``revlogv1``. This simple integer value wasn't powerful enough, so the
1203 ``revlogv1``. This simple integer value wasn't powerful enough, so the
1166 ``streamreqs`` capability was invented to handle cases where the repo
1204 ``streamreqs`` capability was invented to handle cases where the repo
1167 requirements have more than just ``revlogv1``. Newer servers omit the
1205 requirements have more than just ``revlogv1``. Newer servers omit the
1168 ``=1`` since it was the only value supported and the value of ``1`` can
1206 ``=1`` since it was the only value supported and the value of ``1`` can
1169 be implied by clients.
1207 be implied by clients.
1170
1208
1171 unbundlehash
1209 unbundlehash
1172 ------------
1210 ------------
1173
1211
1174 Whether the ``unbundle`` commands supports receiving a hash of all the
1212 Whether the ``unbundle`` commands supports receiving a hash of all the
1175 heads instead of a list.
1213 heads instead of a list.
1176
1214
1177 For more, see the documentation for the ``unbundle`` command.
1215 For more, see the documentation for the ``unbundle`` command.
1178
1216
1179 This capability was introduced in Mercurial 1.9 (released July 2011).
1217 This capability was introduced in Mercurial 1.9 (released July 2011).
1180
1218
1181 unbundle
1219 unbundle
1182 --------
1220 --------
1183
1221
1184 Whether the server supports pushing via the ``unbundle`` command.
1222 Whether the server supports pushing via the ``unbundle`` command.
1185
1223
1186 This capability/command has been present since Mercurial 0.9.1 (released
1224 This capability/command has been present since Mercurial 0.9.1 (released
1187 July 2006).
1225 July 2006).
1188
1226
1189 Mercurial 0.9.2 (released December 2006) added values to the capability
1227 Mercurial 0.9.2 (released December 2006) added values to the capability
1190 indicating which bundle types the server supports receiving. This value is a
1228 indicating which bundle types the server supports receiving. This value is a
1191 comma-delimited list. e.g. ``HG10GZ,HG10BZ,HG10UN``. The order of values
1229 comma-delimited list. e.g. ``HG10GZ,HG10BZ,HG10UN``. The order of values
1192 reflects the priority/preference of that type, where the first value is the
1230 reflects the priority/preference of that type, where the first value is the
1193 most preferred type.
1231 most preferred type.
1194
1232
1195 Content Negotiation
1233 Content Negotiation
1196 ===================
1234 ===================
1197
1235
1198 The wire protocol has some mechanisms to help peers determine what content
1236 The wire protocol has some mechanisms to help peers determine what content
1199 types and encoding the other side will accept. Historically, these mechanisms
1237 types and encoding the other side will accept. Historically, these mechanisms
1200 have been built into commands themselves because most commands only send a
1238 have been built into commands themselves because most commands only send a
1201 well-defined response type and only certain commands needed to support
1239 well-defined response type and only certain commands needed to support
1202 functionality like compression.
1240 functionality like compression.
1203
1241
1204 Currently, only the HTTP version 1 transport supports content negotiation
1242 Currently, only the HTTP version 1 transport supports content negotiation
1205 at the protocol layer.
1243 at the protocol layer.
1206
1244
1207 HTTP requests advertise supported response formats via the ``X-HgProto-<N>``
1245 HTTP requests advertise supported response formats via the ``X-HgProto-<N>``
1208 request header, where ``<N>`` is an integer starting at 1 allowing the logical
1246 request header, where ``<N>`` is an integer starting at 1 allowing the logical
1209 value to span multiple headers. This value consists of a list of
1247 value to span multiple headers. This value consists of a list of
1210 space-delimited parameters. Each parameter denotes a feature or capability.
1248 space-delimited parameters. Each parameter denotes a feature or capability.
1211
1249
1212 The following parameters are defined:
1250 The following parameters are defined:
1213
1251
1214 0.1
1252 0.1
1215 Indicates the client supports receiving ``application/mercurial-0.1``
1253 Indicates the client supports receiving ``application/mercurial-0.1``
1216 responses.
1254 responses.
1217
1255
1218 0.2
1256 0.2
1219 Indicates the client supports receiving ``application/mercurial-0.2``
1257 Indicates the client supports receiving ``application/mercurial-0.2``
1220 responses.
1258 responses.
1221
1259
1222 comp
1260 comp
1223 Indicates compression formats the client can decode. Value is a list of
1261 Indicates compression formats the client can decode. Value is a list of
1224 comma delimited strings identifying compression formats ordered from
1262 comma delimited strings identifying compression formats ordered from
1225 most preferential to least preferential. e.g. ``comp=zstd,zlib,none``.
1263 most preferential to least preferential. e.g. ``comp=zstd,zlib,none``.
1226
1264
1227 This parameter does not have an effect if only the ``0.1`` parameter
1265 This parameter does not have an effect if only the ``0.1`` parameter
1228 is defined, as support for ``application/mercurial-0.2`` or greater is
1266 is defined, as support for ``application/mercurial-0.2`` or greater is
1229 required to use arbitrary compression formats.
1267 required to use arbitrary compression formats.
1230
1268
1231 If this parameter is not advertised, the server interprets this as
1269 If this parameter is not advertised, the server interprets this as
1232 equivalent to ``zlib,none``.
1270 equivalent to ``zlib,none``.
1233
1271
1234 Clients may choose to only send this header if the ``httpmediatype``
1272 Clients may choose to only send this header if the ``httpmediatype``
1235 server capability is present, as currently all server-side features
1273 server capability is present, as currently all server-side features
1236 consulting this header require the client to opt in to new protocol features
1274 consulting this header require the client to opt in to new protocol features
1237 advertised via the ``httpmediatype`` capability.
1275 advertised via the ``httpmediatype`` capability.
1238
1276
1239 A server that doesn't receive an ``X-HgProto-<N>`` header should infer a
1277 A server that doesn't receive an ``X-HgProto-<N>`` header should infer a
1240 value of ``0.1``. This is compatible with legacy clients.
1278 value of ``0.1``. This is compatible with legacy clients.
1241
1279
1242 A server receiving a request indicating support for multiple media type
1280 A server receiving a request indicating support for multiple media type
1243 versions may respond with any of the supported media types. Not all servers
1281 versions may respond with any of the supported media types. Not all servers
1244 may support all media types on all commands.
1282 may support all media types on all commands.
1245
1283
1246 Commands
1284 Commands
1247 ========
1285 ========
1248
1286
1249 This section contains a list of all wire protocol commands implemented by
1287 This section contains a list of all wire protocol commands implemented by
1250 the canonical Mercurial server.
1288 the canonical Mercurial server.
1251
1289
1252 batch
1290 batch
1253 -----
1291 -----
1254
1292
1255 Issue multiple commands while sending a single command request. The purpose
1293 Issue multiple commands while sending a single command request. The purpose
1256 of this command is to allow a client to issue multiple commands while avoiding
1294 of this command is to allow a client to issue multiple commands while avoiding
1257 multiple round trips to the server therefore enabling commands to complete
1295 multiple round trips to the server therefore enabling commands to complete
1258 quicker.
1296 quicker.
1259
1297
1260 The command accepts a ``cmds`` argument that contains a list of commands to
1298 The command accepts a ``cmds`` argument that contains a list of commands to
1261 execute.
1299 execute.
1262
1300
1263 The value of ``cmds`` is a ``;`` delimited list of strings. Each string has the
1301 The value of ``cmds`` is a ``;`` delimited list of strings. Each string has the
1264 form ``<command> <arguments>``. That is, the command name followed by a space
1302 form ``<command> <arguments>``. That is, the command name followed by a space
1265 followed by an argument string.
1303 followed by an argument string.
1266
1304
1267 The argument string is a ``,`` delimited list of ``<key>=<value>`` values
1305 The argument string is a ``,`` delimited list of ``<key>=<value>`` values
1268 corresponding to command arguments. Both the argument name and value are
1306 corresponding to command arguments. Both the argument name and value are
1269 escaped using a special substitution map::
1307 escaped using a special substitution map::
1270
1308
1271 : -> :c
1309 : -> :c
1272 , -> :o
1310 , -> :o
1273 ; -> :s
1311 ; -> :s
1274 = -> :e
1312 = -> :e
1275
1313
1276 The response type for this command is ``string``. The value contains a
1314 The response type for this command is ``string``. The value contains a
1277 ``;`` delimited list of responses for each requested command. Each value
1315 ``;`` delimited list of responses for each requested command. Each value
1278 in this list is escaped using the same substitution map used for arguments.
1316 in this list is escaped using the same substitution map used for arguments.
1279
1317
1280 If an error occurs, the generic error response may be sent.
1318 If an error occurs, the generic error response may be sent.
1281
1319
1282 between
1320 between
1283 -------
1321 -------
1284
1322
1285 (Legacy command used for discovery in old clients)
1323 (Legacy command used for discovery in old clients)
1286
1324
1287 Obtain nodes between pairs of nodes.
1325 Obtain nodes between pairs of nodes.
1288
1326
1289 The ``pairs`` arguments contains a space-delimited list of ``-`` delimited
1327 The ``pairs`` arguments contains a space-delimited list of ``-`` delimited
1290 hex node pairs. e.g.::
1328 hex node pairs. e.g.::
1291
1329
1292 a072279d3f7fd3a4aa7ffa1a5af8efc573e1c896-6dc58916e7c070f678682bfe404d2e2d68291a18
1330 a072279d3f7fd3a4aa7ffa1a5af8efc573e1c896-6dc58916e7c070f678682bfe404d2e2d68291a18
1293
1331
1294 Return type is a ``string``. Value consists of lines corresponding to each
1332 Return type is a ``string``. Value consists of lines corresponding to each
1295 requested range. Each line contains a space-delimited list of hex nodes.
1333 requested range. Each line contains a space-delimited list of hex nodes.
1296 A newline ``\n`` terminates each line, including the last one.
1334 A newline ``\n`` terminates each line, including the last one.
1297
1335
1298 branchmap
1336 branchmap
1299 ---------
1337 ---------
1300
1338
1301 Obtain heads in named branches.
1339 Obtain heads in named branches.
1302
1340
1303 Accepts no arguments. Return type is a ``string``.
1341 Accepts no arguments. Return type is a ``string``.
1304
1342
1305 Return value contains lines with URL encoded branch names followed by a space
1343 Return value contains lines with URL encoded branch names followed by a space
1306 followed by a space-delimited list of hex nodes of heads on that branch.
1344 followed by a space-delimited list of hex nodes of heads on that branch.
1307 e.g.::
1345 e.g.::
1308
1346
1309 default a072279d3f7fd3a4aa7ffa1a5af8efc573e1c896 6dc58916e7c070f678682bfe404d2e2d68291a18
1347 default a072279d3f7fd3a4aa7ffa1a5af8efc573e1c896 6dc58916e7c070f678682bfe404d2e2d68291a18
1310 stable baae3bf31522f41dd5e6d7377d0edd8d1cf3fccc
1348 stable baae3bf31522f41dd5e6d7377d0edd8d1cf3fccc
1311
1349
1312 There is no trailing newline.
1350 There is no trailing newline.
1313
1351
1314 branches
1352 branches
1315 --------
1353 --------
1316
1354
1317 (Legacy command used for discovery in old clients. Clients with ``getbundle``
1355 (Legacy command used for discovery in old clients. Clients with ``getbundle``
1318 use the ``known`` and ``heads`` commands instead.)
1356 use the ``known`` and ``heads`` commands instead.)
1319
1357
1320 Obtain ancestor changesets of specific nodes back to a branch point.
1358 Obtain ancestor changesets of specific nodes back to a branch point.
1321
1359
1322 Despite the name, this command has nothing to do with Mercurial named branches.
1360 Despite the name, this command has nothing to do with Mercurial named branches.
1323 Instead, it is related to DAG branches.
1361 Instead, it is related to DAG branches.
1324
1362
1325 The command accepts a ``nodes`` argument, which is a string of space-delimited
1363 The command accepts a ``nodes`` argument, which is a string of space-delimited
1326 hex nodes.
1364 hex nodes.
1327
1365
1328 For each node requested, the server will find the first ancestor node that is
1366 For each node requested, the server will find the first ancestor node that is
1329 a DAG root or is a merge.
1367 a DAG root or is a merge.
1330
1368
1331 Return type is a ``string``. Return value contains lines with result data for
1369 Return type is a ``string``. Return value contains lines with result data for
1332 each requested node. Each line contains space-delimited nodes followed by a
1370 each requested node. Each line contains space-delimited nodes followed by a
1333 newline (``\n``). The 4 nodes reported on each line correspond to the requested
1371 newline (``\n``). The 4 nodes reported on each line correspond to the requested
1334 node, the ancestor node found, and its 2 parent nodes (which may be the null
1372 node, the ancestor node found, and its 2 parent nodes (which may be the null
1335 node).
1373 node).
1336
1374
1337 capabilities
1375 capabilities
1338 ------------
1376 ------------
1339
1377
1340 Obtain the capabilities string for the repo.
1378 Obtain the capabilities string for the repo.
1341
1379
1342 Unlike the ``hello`` command, the capabilities string is not prefixed.
1380 Unlike the ``hello`` command, the capabilities string is not prefixed.
1343 There is no trailing newline.
1381 There is no trailing newline.
1344
1382
1345 This command does not accept any arguments. Return type is a ``string``.
1383 This command does not accept any arguments. Return type is a ``string``.
1346
1384
1347 This command was introduced in Mercurial 0.9.1 (released July 2006).
1385 This command was introduced in Mercurial 0.9.1 (released July 2006).
1348
1386
1349 changegroup
1387 changegroup
1350 -----------
1388 -----------
1351
1389
1352 (Legacy command: use ``getbundle`` instead)
1390 (Legacy command: use ``getbundle`` instead)
1353
1391
1354 Obtain a changegroup version 1 with data for changesets that are
1392 Obtain a changegroup version 1 with data for changesets that are
1355 descendants of client-specified changesets.
1393 descendants of client-specified changesets.
1356
1394
1357 The ``roots`` arguments contains a list of space-delimited hex nodes.
1395 The ``roots`` arguments contains a list of space-delimited hex nodes.
1358
1396
1359 The server responds with a changegroup version 1 containing all
1397 The server responds with a changegroup version 1 containing all
1360 changesets between the requested root/base nodes and the repo's head nodes
1398 changesets between the requested root/base nodes and the repo's head nodes
1361 at the time of the request.
1399 at the time of the request.
1362
1400
1363 The return type is a ``stream``.
1401 The return type is a ``stream``.
1364
1402
1365 changegroupsubset
1403 changegroupsubset
1366 -----------------
1404 -----------------
1367
1405
1368 (Legacy command: use ``getbundle`` instead)
1406 (Legacy command: use ``getbundle`` instead)
1369
1407
1370 Obtain a changegroup version 1 with data for changesetsets between
1408 Obtain a changegroup version 1 with data for changesetsets between
1371 client specified base and head nodes.
1409 client specified base and head nodes.
1372
1410
1373 The ``bases`` argument contains a list of space-delimited hex nodes.
1411 The ``bases`` argument contains a list of space-delimited hex nodes.
1374 The ``heads`` argument contains a list of space-delimited hex nodes.
1412 The ``heads`` argument contains a list of space-delimited hex nodes.
1375
1413
1376 The server responds with a changegroup version 1 containing all
1414 The server responds with a changegroup version 1 containing all
1377 changesets between the requested base and head nodes at the time of the
1415 changesets between the requested base and head nodes at the time of the
1378 request.
1416 request.
1379
1417
1380 The return type is a ``stream``.
1418 The return type is a ``stream``.
1381
1419
1382 clonebundles
1420 clonebundles
1383 ------------
1421 ------------
1384
1422
1385 Obtains a manifest of bundle URLs available to seed clones.
1423 Obtains a manifest of bundle URLs available to seed clones.
1386
1424
1387 Each returned line contains a URL followed by metadata. See the
1425 Each returned line contains a URL followed by metadata. See the
1388 documentation in the ``clonebundles`` extension for more.
1426 documentation in the ``clonebundles`` extension for more.
1389
1427
1390 The return type is a ``string``.
1428 The return type is a ``string``.
1391
1429
1392 getbundle
1430 getbundle
1393 ---------
1431 ---------
1394
1432
1395 Obtain a bundle containing repository data.
1433 Obtain a bundle containing repository data.
1396
1434
1397 This command accepts the following arguments:
1435 This command accepts the following arguments:
1398
1436
1399 heads
1437 heads
1400 List of space-delimited hex nodes of heads to retrieve.
1438 List of space-delimited hex nodes of heads to retrieve.
1401 common
1439 common
1402 List of space-delimited hex nodes that the client has in common with the
1440 List of space-delimited hex nodes that the client has in common with the
1403 server.
1441 server.
1404 obsmarkers
1442 obsmarkers
1405 Boolean indicating whether to include obsolescence markers as part
1443 Boolean indicating whether to include obsolescence markers as part
1406 of the response. Only works with bundle2.
1444 of the response. Only works with bundle2.
1407 bundlecaps
1445 bundlecaps
1408 Comma-delimited set of strings defining client bundle capabilities.
1446 Comma-delimited set of strings defining client bundle capabilities.
1409 listkeys
1447 listkeys
1410 Comma-delimited list of strings of ``pushkey`` namespaces. For each
1448 Comma-delimited list of strings of ``pushkey`` namespaces. For each
1411 namespace listed, a bundle2 part will be included with the content of
1449 namespace listed, a bundle2 part will be included with the content of
1412 that namespace.
1450 that namespace.
1413 cg
1451 cg
1414 Boolean indicating whether changegroup data is requested.
1452 Boolean indicating whether changegroup data is requested.
1415 cbattempted
1453 cbattempted
1416 Boolean indicating whether the client attempted to use the *clone bundles*
1454 Boolean indicating whether the client attempted to use the *clone bundles*
1417 feature before performing this request.
1455 feature before performing this request.
1418 bookmarks
1456 bookmarks
1419 Boolean indicating whether bookmark data is requested.
1457 Boolean indicating whether bookmark data is requested.
1420 phases
1458 phases
1421 Boolean indicating whether phases data is requested.
1459 Boolean indicating whether phases data is requested.
1422
1460
1423 The return type on success is a ``stream`` where the value is bundle.
1461 The return type on success is a ``stream`` where the value is bundle.
1424 On the HTTP version 1 transport, the response is zlib compressed.
1462 On the HTTP version 1 transport, the response is zlib compressed.
1425
1463
1426 If an error occurs, a generic error response can be sent.
1464 If an error occurs, a generic error response can be sent.
1427
1465
1428 Unless the client sends a false value for the ``cg`` argument, the returned
1466 Unless the client sends a false value for the ``cg`` argument, the returned
1429 bundle contains a changegroup with the nodes between the specified ``common``
1467 bundle contains a changegroup with the nodes between the specified ``common``
1430 and ``heads`` nodes. Depending on the command arguments, the type and content
1468 and ``heads`` nodes. Depending on the command arguments, the type and content
1431 of the returned bundle can vary significantly.
1469 of the returned bundle can vary significantly.
1432
1470
1433 The default behavior is for the server to send a raw changegroup version
1471 The default behavior is for the server to send a raw changegroup version
1434 ``01`` response.
1472 ``01`` response.
1435
1473
1436 If the ``bundlecaps`` provided by the client contain a value beginning
1474 If the ``bundlecaps`` provided by the client contain a value beginning
1437 with ``HG2``, a bundle2 will be returned. The bundle2 data may contain
1475 with ``HG2``, a bundle2 will be returned. The bundle2 data may contain
1438 additional repository data, such as ``pushkey`` namespace values.
1476 additional repository data, such as ``pushkey`` namespace values.
1439
1477
1440 heads
1478 heads
1441 -----
1479 -----
1442
1480
1443 Returns a list of space-delimited hex nodes of repository heads followed
1481 Returns a list of space-delimited hex nodes of repository heads followed
1444 by a newline. e.g.
1482 by a newline. e.g.
1445 ``a9eeb3adc7ddb5006c088e9eda61791c777cbf7c 31f91a3da534dc849f0d6bfc00a395a97cf218a1\n``
1483 ``a9eeb3adc7ddb5006c088e9eda61791c777cbf7c 31f91a3da534dc849f0d6bfc00a395a97cf218a1\n``
1446
1484
1447 This command does not accept any arguments. The return type is a ``string``.
1485 This command does not accept any arguments. The return type is a ``string``.
1448
1486
1449 hello
1487 hello
1450 -----
1488 -----
1451
1489
1452 Returns lines describing interesting things about the server in an RFC-822
1490 Returns lines describing interesting things about the server in an RFC-822
1453 like format.
1491 like format.
1454
1492
1455 Currently, the only line defines the server capabilities. It has the form::
1493 Currently, the only line defines the server capabilities. It has the form::
1456
1494
1457 capabilities: <value>
1495 capabilities: <value>
1458
1496
1459 See above for more about the capabilities string.
1497 See above for more about the capabilities string.
1460
1498
1461 SSH clients typically issue this command as soon as a connection is
1499 SSH clients typically issue this command as soon as a connection is
1462 established.
1500 established.
1463
1501
1464 This command does not accept any arguments. The return type is a ``string``.
1502 This command does not accept any arguments. The return type is a ``string``.
1465
1503
1466 This command was introduced in Mercurial 0.9.1 (released July 2006).
1504 This command was introduced in Mercurial 0.9.1 (released July 2006).
1467
1505
1468 listkeys
1506 listkeys
1469 --------
1507 --------
1470
1508
1471 List values in a specified ``pushkey`` namespace.
1509 List values in a specified ``pushkey`` namespace.
1472
1510
1473 The ``namespace`` argument defines the pushkey namespace to operate on.
1511 The ``namespace`` argument defines the pushkey namespace to operate on.
1474
1512
1475 The return type is a ``string``. The value is an encoded dictionary of keys.
1513 The return type is a ``string``. The value is an encoded dictionary of keys.
1476
1514
1477 Key-value pairs are delimited by newlines (``\n``). Within each line, keys and
1515 Key-value pairs are delimited by newlines (``\n``). Within each line, keys and
1478 values are separated by a tab (``\t``). Keys and values are both strings.
1516 values are separated by a tab (``\t``). Keys and values are both strings.
1479
1517
1480 lookup
1518 lookup
1481 ------
1519 ------
1482
1520
1483 Try to resolve a value to a known repository revision.
1521 Try to resolve a value to a known repository revision.
1484
1522
1485 The ``key`` argument is converted from bytes to an
1523 The ``key`` argument is converted from bytes to an
1486 ``encoding.localstr`` instance then passed into
1524 ``encoding.localstr`` instance then passed into
1487 ``localrepository.__getitem__`` in an attempt to resolve it.
1525 ``localrepository.__getitem__`` in an attempt to resolve it.
1488
1526
1489 The return type is a ``string``.
1527 The return type is a ``string``.
1490
1528
1491 Upon successful resolution, returns ``1 <hex node>\n``. On failure,
1529 Upon successful resolution, returns ``1 <hex node>\n``. On failure,
1492 returns ``0 <error string>\n``. e.g.::
1530 returns ``0 <error string>\n``. e.g.::
1493
1531
1494 1 273ce12ad8f155317b2c078ec75a4eba507f1fba\n
1532 1 273ce12ad8f155317b2c078ec75a4eba507f1fba\n
1495
1533
1496 0 unknown revision 'foo'\n
1534 0 unknown revision 'foo'\n
1497
1535
1498 known
1536 known
1499 -----
1537 -----
1500
1538
1501 Determine whether multiple nodes are known.
1539 Determine whether multiple nodes are known.
1502
1540
1503 The ``nodes`` argument is a list of space-delimited hex nodes to check
1541 The ``nodes`` argument is a list of space-delimited hex nodes to check
1504 for existence.
1542 for existence.
1505
1543
1506 The return type is ``string``.
1544 The return type is ``string``.
1507
1545
1508 Returns a string consisting of ``0``s and ``1``s indicating whether nodes
1546 Returns a string consisting of ``0``s and ``1``s indicating whether nodes
1509 are known. If the Nth node specified in the ``nodes`` argument is known,
1547 are known. If the Nth node specified in the ``nodes`` argument is known,
1510 a ``1`` will be returned at byte offset N. If the node isn't known, ``0``
1548 a ``1`` will be returned at byte offset N. If the node isn't known, ``0``
1511 will be present at byte offset N.
1549 will be present at byte offset N.
1512
1550
1513 There is no trailing newline.
1551 There is no trailing newline.
1514
1552
1515 pushkey
1553 pushkey
1516 -------
1554 -------
1517
1555
1518 Set a value using the ``pushkey`` protocol.
1556 Set a value using the ``pushkey`` protocol.
1519
1557
1520 Accepts arguments ``namespace``, ``key``, ``old``, and ``new``, which
1558 Accepts arguments ``namespace``, ``key``, ``old``, and ``new``, which
1521 correspond to the pushkey namespace to operate on, the key within that
1559 correspond to the pushkey namespace to operate on, the key within that
1522 namespace to change, the old value (which may be empty), and the new value.
1560 namespace to change, the old value (which may be empty), and the new value.
1523 All arguments are string types.
1561 All arguments are string types.
1524
1562
1525 The return type is a ``string``. The value depends on the transport protocol.
1563 The return type is a ``string``. The value depends on the transport protocol.
1526
1564
1527 The SSH version 1 transport sends a string encoded integer followed by a
1565 The SSH version 1 transport sends a string encoded integer followed by a
1528 newline (``\n``) which indicates operation result. The server may send
1566 newline (``\n``) which indicates operation result. The server may send
1529 additional output on the ``stderr`` stream that should be displayed to the
1567 additional output on the ``stderr`` stream that should be displayed to the
1530 user.
1568 user.
1531
1569
1532 The HTTP version 1 transport sends a string encoded integer followed by a
1570 The HTTP version 1 transport sends a string encoded integer followed by a
1533 newline followed by additional server output that should be displayed to
1571 newline followed by additional server output that should be displayed to
1534 the user. This may include output from hooks, etc.
1572 the user. This may include output from hooks, etc.
1535
1573
1536 The integer result varies by namespace. ``0`` means an error has occurred
1574 The integer result varies by namespace. ``0`` means an error has occurred
1537 and there should be additional output to display to the user.
1575 and there should be additional output to display to the user.
1538
1576
1539 stream_out
1577 stream_out
1540 ----------
1578 ----------
1541
1579
1542 Obtain *streaming clone* data.
1580 Obtain *streaming clone* data.
1543
1581
1544 The return type is either a ``string`` or a ``stream``, depending on
1582 The return type is either a ``string`` or a ``stream``, depending on
1545 whether the request was fulfilled properly.
1583 whether the request was fulfilled properly.
1546
1584
1547 A return value of ``1\n`` indicates the server is not configured to serve
1585 A return value of ``1\n`` indicates the server is not configured to serve
1548 this data. If this is seen by the client, they may not have verified the
1586 this data. If this is seen by the client, they may not have verified the
1549 ``stream`` capability is set before making the request.
1587 ``stream`` capability is set before making the request.
1550
1588
1551 A return value of ``2\n`` indicates the server was unable to lock the
1589 A return value of ``2\n`` indicates the server was unable to lock the
1552 repository to generate data.
1590 repository to generate data.
1553
1591
1554 All other responses are a ``stream`` of bytes. The first line of this data
1592 All other responses are a ``stream`` of bytes. The first line of this data
1555 contains 2 space-delimited integers corresponding to the path count and
1593 contains 2 space-delimited integers corresponding to the path count and
1556 payload size, respectively::
1594 payload size, respectively::
1557
1595
1558 <path count> <payload size>\n
1596 <path count> <payload size>\n
1559
1597
1560 The ``<payload size>`` is the total size of path data: it does not include
1598 The ``<payload size>`` is the total size of path data: it does not include
1561 the size of the per-path header lines.
1599 the size of the per-path header lines.
1562
1600
1563 Following that header are ``<path count>`` entries. Each entry consists of a
1601 Following that header are ``<path count>`` entries. Each entry consists of a
1564 line with metadata followed by raw revlog data. The line consists of::
1602 line with metadata followed by raw revlog data. The line consists of::
1565
1603
1566 <store path>\0<size>\n
1604 <store path>\0<size>\n
1567
1605
1568 The ``<store path>`` is the encoded store path of the data that follows.
1606 The ``<store path>`` is the encoded store path of the data that follows.
1569 ``<size>`` is the amount of data for this store path/revlog that follows the
1607 ``<size>`` is the amount of data for this store path/revlog that follows the
1570 newline.
1608 newline.
1571
1609
1572 There is no trailer to indicate end of data. Instead, the client should stop
1610 There is no trailer to indicate end of data. Instead, the client should stop
1573 reading after ``<path count>`` entries are consumed.
1611 reading after ``<path count>`` entries are consumed.
1574
1612
1575 unbundle
1613 unbundle
1576 --------
1614 --------
1577
1615
1578 Send a bundle containing data (usually changegroup data) to the server.
1616 Send a bundle containing data (usually changegroup data) to the server.
1579
1617
1580 Accepts the argument ``heads``, which is a space-delimited list of hex nodes
1618 Accepts the argument ``heads``, which is a space-delimited list of hex nodes
1581 corresponding to server repository heads observed by the client. This is used
1619 corresponding to server repository heads observed by the client. This is used
1582 to detect race conditions and abort push operations before a server performs
1620 to detect race conditions and abort push operations before a server performs
1583 too much work or a client transfers too much data.
1621 too much work or a client transfers too much data.
1584
1622
1585 The request payload consists of a bundle to be applied to the repository,
1623 The request payload consists of a bundle to be applied to the repository,
1586 similarly to as if :hg:`unbundle` were called.
1624 similarly to as if :hg:`unbundle` were called.
1587
1625
1588 In most scenarios, a special ``push response`` type is returned. This type
1626 In most scenarios, a special ``push response`` type is returned. This type
1589 contains an integer describing the change in heads as a result of the
1627 contains an integer describing the change in heads as a result of the
1590 operation. A value of ``0`` indicates nothing changed. ``1`` means the number
1628 operation. A value of ``0`` indicates nothing changed. ``1`` means the number
1591 of heads remained the same. Values ``2`` and larger indicate the number of
1629 of heads remained the same. Values ``2`` and larger indicate the number of
1592 added heads minus 1. e.g. ``3`` means 2 heads were added. Negative values
1630 added heads minus 1. e.g. ``3`` means 2 heads were added. Negative values
1593 indicate the number of fewer heads, also off by 1. e.g. ``-2`` means there
1631 indicate the number of fewer heads, also off by 1. e.g. ``-2`` means there
1594 is 1 fewer head.
1632 is 1 fewer head.
1595
1633
1596 The encoding of the ``push response`` type varies by transport.
1634 The encoding of the ``push response`` type varies by transport.
1597
1635
1598 For the SSH version 1 transport, this type is composed of 2 ``string``
1636 For the SSH version 1 transport, this type is composed of 2 ``string``
1599 responses: an empty response (``0\n``) followed by the integer result value.
1637 responses: an empty response (``0\n``) followed by the integer result value.
1600 e.g. ``1\n2``. So the full response might be ``0\n1\n2``.
1638 e.g. ``1\n2``. So the full response might be ``0\n1\n2``.
1601
1639
1602 For the HTTP version 1 transport, the response is a ``string`` type composed
1640 For the HTTP version 1 transport, the response is a ``string`` type composed
1603 of an integer result value followed by a newline (``\n``) followed by string
1641 of an integer result value followed by a newline (``\n``) followed by string
1604 content holding server output that should be displayed on the client (output
1642 content holding server output that should be displayed on the client (output
1605 hooks, etc).
1643 hooks, etc).
1606
1644
1607 In some cases, the server may respond with a ``bundle2`` bundle. In this
1645 In some cases, the server may respond with a ``bundle2`` bundle. In this
1608 case, the response type is ``stream``. For the HTTP version 1 transport, the
1646 case, the response type is ``stream``. For the HTTP version 1 transport, the
1609 response is zlib compressed.
1647 response is zlib compressed.
1610
1648
1611 The server may also respond with a generic error type, which contains a string
1649 The server may also respond with a generic error type, which contains a string
1612 indicating the failure.
1650 indicating the failure.
@@ -1,838 +1,841 b''
1 # wireprotoframing.py - unified framing protocol for wire protocol
1 # wireprotoframing.py - unified framing protocol for wire protocol
2 #
2 #
3 # Copyright 2018 Gregory Szorc <gregory.szorc@gmail.com>
3 # Copyright 2018 Gregory Szorc <gregory.szorc@gmail.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 # This file contains functionality to support the unified frame-based wire
8 # This file contains functionality to support the unified frame-based wire
9 # protocol. For details about the protocol, see
9 # protocol. For details about the protocol, see
10 # `hg help internals.wireprotocol`.
10 # `hg help internals.wireprotocol`.
11
11
12 from __future__ import absolute_import
12 from __future__ import absolute_import
13
13
14 import struct
14 import struct
15
15
16 from .i18n import _
16 from .i18n import _
17 from .thirdparty import (
17 from .thirdparty import (
18 attr,
18 attr,
19 cbor,
19 cbor,
20 )
20 )
21 from . import (
21 from . import (
22 error,
22 error,
23 util,
23 util,
24 )
24 )
25 from .utils import (
25 from .utils import (
26 stringutil,
26 stringutil,
27 )
27 )
28
28
29 FRAME_HEADER_SIZE = 8
29 FRAME_HEADER_SIZE = 8
30 DEFAULT_MAX_FRAME_SIZE = 32768
30 DEFAULT_MAX_FRAME_SIZE = 32768
31
31
32 STREAM_FLAG_BEGIN_STREAM = 0x01
32 STREAM_FLAG_BEGIN_STREAM = 0x01
33 STREAM_FLAG_END_STREAM = 0x02
33 STREAM_FLAG_END_STREAM = 0x02
34 STREAM_FLAG_ENCODING_APPLIED = 0x04
34 STREAM_FLAG_ENCODING_APPLIED = 0x04
35
35
36 STREAM_FLAGS = {
36 STREAM_FLAGS = {
37 b'stream-begin': STREAM_FLAG_BEGIN_STREAM,
37 b'stream-begin': STREAM_FLAG_BEGIN_STREAM,
38 b'stream-end': STREAM_FLAG_END_STREAM,
38 b'stream-end': STREAM_FLAG_END_STREAM,
39 b'encoded': STREAM_FLAG_ENCODING_APPLIED,
39 b'encoded': STREAM_FLAG_ENCODING_APPLIED,
40 }
40 }
41
41
42 FRAME_TYPE_COMMAND_NAME = 0x01
42 FRAME_TYPE_COMMAND_NAME = 0x01
43 FRAME_TYPE_COMMAND_ARGUMENT = 0x02
43 FRAME_TYPE_COMMAND_ARGUMENT = 0x02
44 FRAME_TYPE_COMMAND_DATA = 0x03
44 FRAME_TYPE_COMMAND_DATA = 0x03
45 FRAME_TYPE_BYTES_RESPONSE = 0x04
45 FRAME_TYPE_BYTES_RESPONSE = 0x04
46 FRAME_TYPE_ERROR_RESPONSE = 0x05
46 FRAME_TYPE_ERROR_RESPONSE = 0x05
47 FRAME_TYPE_TEXT_OUTPUT = 0x06
47 FRAME_TYPE_TEXT_OUTPUT = 0x06
48 FRAME_TYPE_PROGRESS = 0x07
48 FRAME_TYPE_STREAM_SETTINGS = 0x08
49 FRAME_TYPE_STREAM_SETTINGS = 0x08
49
50
50 FRAME_TYPES = {
51 FRAME_TYPES = {
51 b'command-name': FRAME_TYPE_COMMAND_NAME,
52 b'command-name': FRAME_TYPE_COMMAND_NAME,
52 b'command-argument': FRAME_TYPE_COMMAND_ARGUMENT,
53 b'command-argument': FRAME_TYPE_COMMAND_ARGUMENT,
53 b'command-data': FRAME_TYPE_COMMAND_DATA,
54 b'command-data': FRAME_TYPE_COMMAND_DATA,
54 b'bytes-response': FRAME_TYPE_BYTES_RESPONSE,
55 b'bytes-response': FRAME_TYPE_BYTES_RESPONSE,
55 b'error-response': FRAME_TYPE_ERROR_RESPONSE,
56 b'error-response': FRAME_TYPE_ERROR_RESPONSE,
56 b'text-output': FRAME_TYPE_TEXT_OUTPUT,
57 b'text-output': FRAME_TYPE_TEXT_OUTPUT,
58 b'progress': FRAME_TYPE_PROGRESS,
57 b'stream-settings': FRAME_TYPE_STREAM_SETTINGS,
59 b'stream-settings': FRAME_TYPE_STREAM_SETTINGS,
58 }
60 }
59
61
60 FLAG_COMMAND_NAME_EOS = 0x01
62 FLAG_COMMAND_NAME_EOS = 0x01
61 FLAG_COMMAND_NAME_HAVE_ARGS = 0x02
63 FLAG_COMMAND_NAME_HAVE_ARGS = 0x02
62 FLAG_COMMAND_NAME_HAVE_DATA = 0x04
64 FLAG_COMMAND_NAME_HAVE_DATA = 0x04
63
65
64 FLAGS_COMMAND = {
66 FLAGS_COMMAND = {
65 b'eos': FLAG_COMMAND_NAME_EOS,
67 b'eos': FLAG_COMMAND_NAME_EOS,
66 b'have-args': FLAG_COMMAND_NAME_HAVE_ARGS,
68 b'have-args': FLAG_COMMAND_NAME_HAVE_ARGS,
67 b'have-data': FLAG_COMMAND_NAME_HAVE_DATA,
69 b'have-data': FLAG_COMMAND_NAME_HAVE_DATA,
68 }
70 }
69
71
70 FLAG_COMMAND_ARGUMENT_CONTINUATION = 0x01
72 FLAG_COMMAND_ARGUMENT_CONTINUATION = 0x01
71 FLAG_COMMAND_ARGUMENT_EOA = 0x02
73 FLAG_COMMAND_ARGUMENT_EOA = 0x02
72
74
73 FLAGS_COMMAND_ARGUMENT = {
75 FLAGS_COMMAND_ARGUMENT = {
74 b'continuation': FLAG_COMMAND_ARGUMENT_CONTINUATION,
76 b'continuation': FLAG_COMMAND_ARGUMENT_CONTINUATION,
75 b'eoa': FLAG_COMMAND_ARGUMENT_EOA,
77 b'eoa': FLAG_COMMAND_ARGUMENT_EOA,
76 }
78 }
77
79
78 FLAG_COMMAND_DATA_CONTINUATION = 0x01
80 FLAG_COMMAND_DATA_CONTINUATION = 0x01
79 FLAG_COMMAND_DATA_EOS = 0x02
81 FLAG_COMMAND_DATA_EOS = 0x02
80
82
81 FLAGS_COMMAND_DATA = {
83 FLAGS_COMMAND_DATA = {
82 b'continuation': FLAG_COMMAND_DATA_CONTINUATION,
84 b'continuation': FLAG_COMMAND_DATA_CONTINUATION,
83 b'eos': FLAG_COMMAND_DATA_EOS,
85 b'eos': FLAG_COMMAND_DATA_EOS,
84 }
86 }
85
87
86 FLAG_BYTES_RESPONSE_CONTINUATION = 0x01
88 FLAG_BYTES_RESPONSE_CONTINUATION = 0x01
87 FLAG_BYTES_RESPONSE_EOS = 0x02
89 FLAG_BYTES_RESPONSE_EOS = 0x02
88
90
89 FLAGS_BYTES_RESPONSE = {
91 FLAGS_BYTES_RESPONSE = {
90 b'continuation': FLAG_BYTES_RESPONSE_CONTINUATION,
92 b'continuation': FLAG_BYTES_RESPONSE_CONTINUATION,
91 b'eos': FLAG_BYTES_RESPONSE_EOS,
93 b'eos': FLAG_BYTES_RESPONSE_EOS,
92 }
94 }
93
95
94 FLAG_ERROR_RESPONSE_PROTOCOL = 0x01
96 FLAG_ERROR_RESPONSE_PROTOCOL = 0x01
95 FLAG_ERROR_RESPONSE_APPLICATION = 0x02
97 FLAG_ERROR_RESPONSE_APPLICATION = 0x02
96
98
97 FLAGS_ERROR_RESPONSE = {
99 FLAGS_ERROR_RESPONSE = {
98 b'protocol': FLAG_ERROR_RESPONSE_PROTOCOL,
100 b'protocol': FLAG_ERROR_RESPONSE_PROTOCOL,
99 b'application': FLAG_ERROR_RESPONSE_APPLICATION,
101 b'application': FLAG_ERROR_RESPONSE_APPLICATION,
100 }
102 }
101
103
102 # Maps frame types to their available flags.
104 # Maps frame types to their available flags.
103 FRAME_TYPE_FLAGS = {
105 FRAME_TYPE_FLAGS = {
104 FRAME_TYPE_COMMAND_NAME: FLAGS_COMMAND,
106 FRAME_TYPE_COMMAND_NAME: FLAGS_COMMAND,
105 FRAME_TYPE_COMMAND_ARGUMENT: FLAGS_COMMAND_ARGUMENT,
107 FRAME_TYPE_COMMAND_ARGUMENT: FLAGS_COMMAND_ARGUMENT,
106 FRAME_TYPE_COMMAND_DATA: FLAGS_COMMAND_DATA,
108 FRAME_TYPE_COMMAND_DATA: FLAGS_COMMAND_DATA,
107 FRAME_TYPE_BYTES_RESPONSE: FLAGS_BYTES_RESPONSE,
109 FRAME_TYPE_BYTES_RESPONSE: FLAGS_BYTES_RESPONSE,
108 FRAME_TYPE_ERROR_RESPONSE: FLAGS_ERROR_RESPONSE,
110 FRAME_TYPE_ERROR_RESPONSE: FLAGS_ERROR_RESPONSE,
109 FRAME_TYPE_TEXT_OUTPUT: {},
111 FRAME_TYPE_TEXT_OUTPUT: {},
112 FRAME_TYPE_PROGRESS: {},
110 FRAME_TYPE_STREAM_SETTINGS: {},
113 FRAME_TYPE_STREAM_SETTINGS: {},
111 }
114 }
112
115
113 ARGUMENT_FRAME_HEADER = struct.Struct(r'<HH')
116 ARGUMENT_FRAME_HEADER = struct.Struct(r'<HH')
114
117
115 @attr.s(slots=True)
118 @attr.s(slots=True)
116 class frameheader(object):
119 class frameheader(object):
117 """Represents the data in a frame header."""
120 """Represents the data in a frame header."""
118
121
119 length = attr.ib()
122 length = attr.ib()
120 requestid = attr.ib()
123 requestid = attr.ib()
121 streamid = attr.ib()
124 streamid = attr.ib()
122 streamflags = attr.ib()
125 streamflags = attr.ib()
123 typeid = attr.ib()
126 typeid = attr.ib()
124 flags = attr.ib()
127 flags = attr.ib()
125
128
126 @attr.s(slots=True)
129 @attr.s(slots=True)
127 class frame(object):
130 class frame(object):
128 """Represents a parsed frame."""
131 """Represents a parsed frame."""
129
132
130 requestid = attr.ib()
133 requestid = attr.ib()
131 streamid = attr.ib()
134 streamid = attr.ib()
132 streamflags = attr.ib()
135 streamflags = attr.ib()
133 typeid = attr.ib()
136 typeid = attr.ib()
134 flags = attr.ib()
137 flags = attr.ib()
135 payload = attr.ib()
138 payload = attr.ib()
136
139
137 def makeframe(requestid, streamid, streamflags, typeid, flags, payload):
140 def makeframe(requestid, streamid, streamflags, typeid, flags, payload):
138 """Assemble a frame into a byte array."""
141 """Assemble a frame into a byte array."""
139 # TODO assert size of payload.
142 # TODO assert size of payload.
140 frame = bytearray(FRAME_HEADER_SIZE + len(payload))
143 frame = bytearray(FRAME_HEADER_SIZE + len(payload))
141
144
142 # 24 bits length
145 # 24 bits length
143 # 16 bits request id
146 # 16 bits request id
144 # 8 bits stream id
147 # 8 bits stream id
145 # 8 bits stream flags
148 # 8 bits stream flags
146 # 4 bits type
149 # 4 bits type
147 # 4 bits flags
150 # 4 bits flags
148
151
149 l = struct.pack(r'<I', len(payload))
152 l = struct.pack(r'<I', len(payload))
150 frame[0:3] = l[0:3]
153 frame[0:3] = l[0:3]
151 struct.pack_into(r'<HBB', frame, 3, requestid, streamid, streamflags)
154 struct.pack_into(r'<HBB', frame, 3, requestid, streamid, streamflags)
152 frame[7] = (typeid << 4) | flags
155 frame[7] = (typeid << 4) | flags
153 frame[8:] = payload
156 frame[8:] = payload
154
157
155 return frame
158 return frame
156
159
157 def makeframefromhumanstring(s):
160 def makeframefromhumanstring(s):
158 """Create a frame from a human readable string
161 """Create a frame from a human readable string
159
162
160 DANGER: NOT SAFE TO USE WITH UNTRUSTED INPUT BECAUSE OF POTENTIAL
163 DANGER: NOT SAFE TO USE WITH UNTRUSTED INPUT BECAUSE OF POTENTIAL
161 eval() USAGE. DO NOT USE IN CORE.
164 eval() USAGE. DO NOT USE IN CORE.
162
165
163 Strings have the form:
166 Strings have the form:
164
167
165 <request-id> <stream-id> <stream-flags> <type> <flags> <payload>
168 <request-id> <stream-id> <stream-flags> <type> <flags> <payload>
166
169
167 This can be used by user-facing applications and tests for creating
170 This can be used by user-facing applications and tests for creating
168 frames easily without having to type out a bunch of constants.
171 frames easily without having to type out a bunch of constants.
169
172
170 Request ID and stream IDs are integers.
173 Request ID and stream IDs are integers.
171
174
172 Stream flags, frame type, and flags can be specified by integer or
175 Stream flags, frame type, and flags can be specified by integer or
173 named constant.
176 named constant.
174
177
175 Flags can be delimited by `|` to bitwise OR them together.
178 Flags can be delimited by `|` to bitwise OR them together.
176
179
177 If the payload begins with ``cbor:``, the following string will be
180 If the payload begins with ``cbor:``, the following string will be
178 evaluated as Python code and the resulting object will be fed into
181 evaluated as Python code and the resulting object will be fed into
179 a CBOR encoder. Otherwise, the payload is interpreted as a Python
182 a CBOR encoder. Otherwise, the payload is interpreted as a Python
180 byte string literal.
183 byte string literal.
181 """
184 """
182 fields = s.split(b' ', 5)
185 fields = s.split(b' ', 5)
183 requestid, streamid, streamflags, frametype, frameflags, payload = fields
186 requestid, streamid, streamflags, frametype, frameflags, payload = fields
184
187
185 requestid = int(requestid)
188 requestid = int(requestid)
186 streamid = int(streamid)
189 streamid = int(streamid)
187
190
188 finalstreamflags = 0
191 finalstreamflags = 0
189 for flag in streamflags.split(b'|'):
192 for flag in streamflags.split(b'|'):
190 if flag in STREAM_FLAGS:
193 if flag in STREAM_FLAGS:
191 finalstreamflags |= STREAM_FLAGS[flag]
194 finalstreamflags |= STREAM_FLAGS[flag]
192 else:
195 else:
193 finalstreamflags |= int(flag)
196 finalstreamflags |= int(flag)
194
197
195 if frametype in FRAME_TYPES:
198 if frametype in FRAME_TYPES:
196 frametype = FRAME_TYPES[frametype]
199 frametype = FRAME_TYPES[frametype]
197 else:
200 else:
198 frametype = int(frametype)
201 frametype = int(frametype)
199
202
200 finalflags = 0
203 finalflags = 0
201 validflags = FRAME_TYPE_FLAGS[frametype]
204 validflags = FRAME_TYPE_FLAGS[frametype]
202 for flag in frameflags.split(b'|'):
205 for flag in frameflags.split(b'|'):
203 if flag in validflags:
206 if flag in validflags:
204 finalflags |= validflags[flag]
207 finalflags |= validflags[flag]
205 else:
208 else:
206 finalflags |= int(flag)
209 finalflags |= int(flag)
207
210
208 if payload.startswith(b'cbor:'):
211 if payload.startswith(b'cbor:'):
209 payload = cbor.dumps(stringutil.evalpython(payload[5:]), canonical=True)
212 payload = cbor.dumps(stringutil.evalpython(payload[5:]), canonical=True)
210
213
211 else:
214 else:
212 payload = stringutil.unescapestr(payload)
215 payload = stringutil.unescapestr(payload)
213
216
214 return makeframe(requestid=requestid, streamid=streamid,
217 return makeframe(requestid=requestid, streamid=streamid,
215 streamflags=finalstreamflags, typeid=frametype,
218 streamflags=finalstreamflags, typeid=frametype,
216 flags=finalflags, payload=payload)
219 flags=finalflags, payload=payload)
217
220
218 def parseheader(data):
221 def parseheader(data):
219 """Parse a unified framing protocol frame header from a buffer.
222 """Parse a unified framing protocol frame header from a buffer.
220
223
221 The header is expected to be in the buffer at offset 0 and the
224 The header is expected to be in the buffer at offset 0 and the
222 buffer is expected to be large enough to hold a full header.
225 buffer is expected to be large enough to hold a full header.
223 """
226 """
224 # 24 bits payload length (little endian)
227 # 24 bits payload length (little endian)
225 # 16 bits request ID
228 # 16 bits request ID
226 # 8 bits stream ID
229 # 8 bits stream ID
227 # 8 bits stream flags
230 # 8 bits stream flags
228 # 4 bits frame type
231 # 4 bits frame type
229 # 4 bits frame flags
232 # 4 bits frame flags
230 # ... payload
233 # ... payload
231 framelength = data[0] + 256 * data[1] + 16384 * data[2]
234 framelength = data[0] + 256 * data[1] + 16384 * data[2]
232 requestid, streamid, streamflags = struct.unpack_from(r'<HBB', data, 3)
235 requestid, streamid, streamflags = struct.unpack_from(r'<HBB', data, 3)
233 typeflags = data[7]
236 typeflags = data[7]
234
237
235 frametype = (typeflags & 0xf0) >> 4
238 frametype = (typeflags & 0xf0) >> 4
236 frameflags = typeflags & 0x0f
239 frameflags = typeflags & 0x0f
237
240
238 return frameheader(framelength, requestid, streamid, streamflags,
241 return frameheader(framelength, requestid, streamid, streamflags,
239 frametype, frameflags)
242 frametype, frameflags)
240
243
241 def readframe(fh):
244 def readframe(fh):
242 """Read a unified framing protocol frame from a file object.
245 """Read a unified framing protocol frame from a file object.
243
246
244 Returns a 3-tuple of (type, flags, payload) for the decoded frame or
247 Returns a 3-tuple of (type, flags, payload) for the decoded frame or
245 None if no frame is available. May raise if a malformed frame is
248 None if no frame is available. May raise if a malformed frame is
246 seen.
249 seen.
247 """
250 """
248 header = bytearray(FRAME_HEADER_SIZE)
251 header = bytearray(FRAME_HEADER_SIZE)
249
252
250 readcount = fh.readinto(header)
253 readcount = fh.readinto(header)
251
254
252 if readcount == 0:
255 if readcount == 0:
253 return None
256 return None
254
257
255 if readcount != FRAME_HEADER_SIZE:
258 if readcount != FRAME_HEADER_SIZE:
256 raise error.Abort(_('received incomplete frame: got %d bytes: %s') %
259 raise error.Abort(_('received incomplete frame: got %d bytes: %s') %
257 (readcount, header))
260 (readcount, header))
258
261
259 h = parseheader(header)
262 h = parseheader(header)
260
263
261 payload = fh.read(h.length)
264 payload = fh.read(h.length)
262 if len(payload) != h.length:
265 if len(payload) != h.length:
263 raise error.Abort(_('frame length error: expected %d; got %d') %
266 raise error.Abort(_('frame length error: expected %d; got %d') %
264 (h.length, len(payload)))
267 (h.length, len(payload)))
265
268
266 return frame(h.requestid, h.streamid, h.streamflags, h.typeid, h.flags,
269 return frame(h.requestid, h.streamid, h.streamflags, h.typeid, h.flags,
267 payload)
270 payload)
268
271
269 def createcommandframes(stream, requestid, cmd, args, datafh=None):
272 def createcommandframes(stream, requestid, cmd, args, datafh=None):
270 """Create frames necessary to transmit a request to run a command.
273 """Create frames necessary to transmit a request to run a command.
271
274
272 This is a generator of bytearrays. Each item represents a frame
275 This is a generator of bytearrays. Each item represents a frame
273 ready to be sent over the wire to a peer.
276 ready to be sent over the wire to a peer.
274 """
277 """
275 flags = 0
278 flags = 0
276 if args:
279 if args:
277 flags |= FLAG_COMMAND_NAME_HAVE_ARGS
280 flags |= FLAG_COMMAND_NAME_HAVE_ARGS
278 if datafh:
281 if datafh:
279 flags |= FLAG_COMMAND_NAME_HAVE_DATA
282 flags |= FLAG_COMMAND_NAME_HAVE_DATA
280
283
281 if not flags:
284 if not flags:
282 flags |= FLAG_COMMAND_NAME_EOS
285 flags |= FLAG_COMMAND_NAME_EOS
283
286
284 yield stream.makeframe(requestid=requestid, typeid=FRAME_TYPE_COMMAND_NAME,
287 yield stream.makeframe(requestid=requestid, typeid=FRAME_TYPE_COMMAND_NAME,
285 flags=flags, payload=cmd)
288 flags=flags, payload=cmd)
286
289
287 for i, k in enumerate(sorted(args)):
290 for i, k in enumerate(sorted(args)):
288 v = args[k]
291 v = args[k]
289 last = i == len(args) - 1
292 last = i == len(args) - 1
290
293
291 # TODO handle splitting of argument values across frames.
294 # TODO handle splitting of argument values across frames.
292 payload = bytearray(ARGUMENT_FRAME_HEADER.size + len(k) + len(v))
295 payload = bytearray(ARGUMENT_FRAME_HEADER.size + len(k) + len(v))
293 offset = 0
296 offset = 0
294 ARGUMENT_FRAME_HEADER.pack_into(payload, offset, len(k), len(v))
297 ARGUMENT_FRAME_HEADER.pack_into(payload, offset, len(k), len(v))
295 offset += ARGUMENT_FRAME_HEADER.size
298 offset += ARGUMENT_FRAME_HEADER.size
296 payload[offset:offset + len(k)] = k
299 payload[offset:offset + len(k)] = k
297 offset += len(k)
300 offset += len(k)
298 payload[offset:offset + len(v)] = v
301 payload[offset:offset + len(v)] = v
299
302
300 flags = FLAG_COMMAND_ARGUMENT_EOA if last else 0
303 flags = FLAG_COMMAND_ARGUMENT_EOA if last else 0
301 yield stream.makeframe(requestid=requestid,
304 yield stream.makeframe(requestid=requestid,
302 typeid=FRAME_TYPE_COMMAND_ARGUMENT,
305 typeid=FRAME_TYPE_COMMAND_ARGUMENT,
303 flags=flags,
306 flags=flags,
304 payload=payload)
307 payload=payload)
305
308
306 if datafh:
309 if datafh:
307 while True:
310 while True:
308 data = datafh.read(DEFAULT_MAX_FRAME_SIZE)
311 data = datafh.read(DEFAULT_MAX_FRAME_SIZE)
309
312
310 done = False
313 done = False
311 if len(data) == DEFAULT_MAX_FRAME_SIZE:
314 if len(data) == DEFAULT_MAX_FRAME_SIZE:
312 flags = FLAG_COMMAND_DATA_CONTINUATION
315 flags = FLAG_COMMAND_DATA_CONTINUATION
313 else:
316 else:
314 flags = FLAG_COMMAND_DATA_EOS
317 flags = FLAG_COMMAND_DATA_EOS
315 assert datafh.read(1) == b''
318 assert datafh.read(1) == b''
316 done = True
319 done = True
317
320
318 yield stream.makeframe(requestid=requestid,
321 yield stream.makeframe(requestid=requestid,
319 typeid=FRAME_TYPE_COMMAND_DATA,
322 typeid=FRAME_TYPE_COMMAND_DATA,
320 flags=flags,
323 flags=flags,
321 payload=data)
324 payload=data)
322
325
323 if done:
326 if done:
324 break
327 break
325
328
326 def createbytesresponseframesfrombytes(stream, requestid, data,
329 def createbytesresponseframesfrombytes(stream, requestid, data,
327 maxframesize=DEFAULT_MAX_FRAME_SIZE):
330 maxframesize=DEFAULT_MAX_FRAME_SIZE):
328 """Create a raw frame to send a bytes response from static bytes input.
331 """Create a raw frame to send a bytes response from static bytes input.
329
332
330 Returns a generator of bytearrays.
333 Returns a generator of bytearrays.
331 """
334 """
332
335
333 # Simple case of a single frame.
336 # Simple case of a single frame.
334 if len(data) <= maxframesize:
337 if len(data) <= maxframesize:
335 yield stream.makeframe(requestid=requestid,
338 yield stream.makeframe(requestid=requestid,
336 typeid=FRAME_TYPE_BYTES_RESPONSE,
339 typeid=FRAME_TYPE_BYTES_RESPONSE,
337 flags=FLAG_BYTES_RESPONSE_EOS,
340 flags=FLAG_BYTES_RESPONSE_EOS,
338 payload=data)
341 payload=data)
339 return
342 return
340
343
341 offset = 0
344 offset = 0
342 while True:
345 while True:
343 chunk = data[offset:offset + maxframesize]
346 chunk = data[offset:offset + maxframesize]
344 offset += len(chunk)
347 offset += len(chunk)
345 done = offset == len(data)
348 done = offset == len(data)
346
349
347 if done:
350 if done:
348 flags = FLAG_BYTES_RESPONSE_EOS
351 flags = FLAG_BYTES_RESPONSE_EOS
349 else:
352 else:
350 flags = FLAG_BYTES_RESPONSE_CONTINUATION
353 flags = FLAG_BYTES_RESPONSE_CONTINUATION
351
354
352 yield stream.makeframe(requestid=requestid,
355 yield stream.makeframe(requestid=requestid,
353 typeid=FRAME_TYPE_BYTES_RESPONSE,
356 typeid=FRAME_TYPE_BYTES_RESPONSE,
354 flags=flags,
357 flags=flags,
355 payload=chunk)
358 payload=chunk)
356
359
357 if done:
360 if done:
358 break
361 break
359
362
360 def createerrorframe(stream, requestid, msg, protocol=False, application=False):
363 def createerrorframe(stream, requestid, msg, protocol=False, application=False):
361 # TODO properly handle frame size limits.
364 # TODO properly handle frame size limits.
362 assert len(msg) <= DEFAULT_MAX_FRAME_SIZE
365 assert len(msg) <= DEFAULT_MAX_FRAME_SIZE
363
366
364 flags = 0
367 flags = 0
365 if protocol:
368 if protocol:
366 flags |= FLAG_ERROR_RESPONSE_PROTOCOL
369 flags |= FLAG_ERROR_RESPONSE_PROTOCOL
367 if application:
370 if application:
368 flags |= FLAG_ERROR_RESPONSE_APPLICATION
371 flags |= FLAG_ERROR_RESPONSE_APPLICATION
369
372
370 yield stream.makeframe(requestid=requestid,
373 yield stream.makeframe(requestid=requestid,
371 typeid=FRAME_TYPE_ERROR_RESPONSE,
374 typeid=FRAME_TYPE_ERROR_RESPONSE,
372 flags=flags,
375 flags=flags,
373 payload=msg)
376 payload=msg)
374
377
375 def createtextoutputframe(stream, requestid, atoms):
378 def createtextoutputframe(stream, requestid, atoms):
376 """Create a text output frame to render text to people.
379 """Create a text output frame to render text to people.
377
380
378 ``atoms`` is a 3-tuple of (formatting string, args, labels).
381 ``atoms`` is a 3-tuple of (formatting string, args, labels).
379
382
380 The formatting string contains ``%s`` tokens to be replaced by the
383 The formatting string contains ``%s`` tokens to be replaced by the
381 corresponding indexed entry in ``args``. ``labels`` is an iterable of
384 corresponding indexed entry in ``args``. ``labels`` is an iterable of
382 formatters to be applied at rendering time. In terms of the ``ui``
385 formatters to be applied at rendering time. In terms of the ``ui``
383 class, each atom corresponds to a ``ui.write()``.
386 class, each atom corresponds to a ``ui.write()``.
384 """
387 """
385 bytesleft = DEFAULT_MAX_FRAME_SIZE
388 bytesleft = DEFAULT_MAX_FRAME_SIZE
386 atomchunks = []
389 atomchunks = []
387
390
388 for (formatting, args, labels) in atoms:
391 for (formatting, args, labels) in atoms:
389 if len(args) > 255:
392 if len(args) > 255:
390 raise ValueError('cannot use more than 255 formatting arguments')
393 raise ValueError('cannot use more than 255 formatting arguments')
391 if len(labels) > 255:
394 if len(labels) > 255:
392 raise ValueError('cannot use more than 255 labels')
395 raise ValueError('cannot use more than 255 labels')
393
396
394 # TODO look for localstr, other types here?
397 # TODO look for localstr, other types here?
395
398
396 if not isinstance(formatting, bytes):
399 if not isinstance(formatting, bytes):
397 raise ValueError('must use bytes formatting strings')
400 raise ValueError('must use bytes formatting strings')
398 for arg in args:
401 for arg in args:
399 if not isinstance(arg, bytes):
402 if not isinstance(arg, bytes):
400 raise ValueError('must use bytes for arguments')
403 raise ValueError('must use bytes for arguments')
401 for label in labels:
404 for label in labels:
402 if not isinstance(label, bytes):
405 if not isinstance(label, bytes):
403 raise ValueError('must use bytes for labels')
406 raise ValueError('must use bytes for labels')
404
407
405 # Formatting string must be UTF-8.
408 # Formatting string must be UTF-8.
406 formatting = formatting.decode(r'utf-8', r'replace').encode(r'utf-8')
409 formatting = formatting.decode(r'utf-8', r'replace').encode(r'utf-8')
407
410
408 # Arguments must be UTF-8.
411 # Arguments must be UTF-8.
409 args = [a.decode(r'utf-8', r'replace').encode(r'utf-8') for a in args]
412 args = [a.decode(r'utf-8', r'replace').encode(r'utf-8') for a in args]
410
413
411 # Labels must be ASCII.
414 # Labels must be ASCII.
412 labels = [l.decode(r'ascii', r'strict').encode(r'ascii')
415 labels = [l.decode(r'ascii', r'strict').encode(r'ascii')
413 for l in labels]
416 for l in labels]
414
417
415 if len(formatting) > 65535:
418 if len(formatting) > 65535:
416 raise ValueError('formatting string cannot be longer than 64k')
419 raise ValueError('formatting string cannot be longer than 64k')
417
420
418 if any(len(a) > 65535 for a in args):
421 if any(len(a) > 65535 for a in args):
419 raise ValueError('argument string cannot be longer than 64k')
422 raise ValueError('argument string cannot be longer than 64k')
420
423
421 if any(len(l) > 255 for l in labels):
424 if any(len(l) > 255 for l in labels):
422 raise ValueError('label string cannot be longer than 255 bytes')
425 raise ValueError('label string cannot be longer than 255 bytes')
423
426
424 chunks = [
427 chunks = [
425 struct.pack(r'<H', len(formatting)),
428 struct.pack(r'<H', len(formatting)),
426 struct.pack(r'<BB', len(labels), len(args)),
429 struct.pack(r'<BB', len(labels), len(args)),
427 struct.pack(r'<' + r'B' * len(labels), *map(len, labels)),
430 struct.pack(r'<' + r'B' * len(labels), *map(len, labels)),
428 struct.pack(r'<' + r'H' * len(args), *map(len, args)),
431 struct.pack(r'<' + r'H' * len(args), *map(len, args)),
429 ]
432 ]
430 chunks.append(formatting)
433 chunks.append(formatting)
431 chunks.extend(labels)
434 chunks.extend(labels)
432 chunks.extend(args)
435 chunks.extend(args)
433
436
434 atom = b''.join(chunks)
437 atom = b''.join(chunks)
435 atomchunks.append(atom)
438 atomchunks.append(atom)
436 bytesleft -= len(atom)
439 bytesleft -= len(atom)
437
440
438 if bytesleft < 0:
441 if bytesleft < 0:
439 raise ValueError('cannot encode data in a single frame')
442 raise ValueError('cannot encode data in a single frame')
440
443
441 yield stream.makeframe(requestid=requestid,
444 yield stream.makeframe(requestid=requestid,
442 typeid=FRAME_TYPE_TEXT_OUTPUT,
445 typeid=FRAME_TYPE_TEXT_OUTPUT,
443 flags=0,
446 flags=0,
444 payload=b''.join(atomchunks))
447 payload=b''.join(atomchunks))
445
448
446 class stream(object):
449 class stream(object):
447 """Represents a logical unidirectional series of frames."""
450 """Represents a logical unidirectional series of frames."""
448
451
449 def __init__(self, streamid, active=False):
452 def __init__(self, streamid, active=False):
450 self.streamid = streamid
453 self.streamid = streamid
451 self._active = False
454 self._active = False
452
455
453 def makeframe(self, requestid, typeid, flags, payload):
456 def makeframe(self, requestid, typeid, flags, payload):
454 """Create a frame to be sent out over this stream.
457 """Create a frame to be sent out over this stream.
455
458
456 Only returns the frame instance. Does not actually send it.
459 Only returns the frame instance. Does not actually send it.
457 """
460 """
458 streamflags = 0
461 streamflags = 0
459 if not self._active:
462 if not self._active:
460 streamflags |= STREAM_FLAG_BEGIN_STREAM
463 streamflags |= STREAM_FLAG_BEGIN_STREAM
461 self._active = True
464 self._active = True
462
465
463 return makeframe(requestid, self.streamid, streamflags, typeid, flags,
466 return makeframe(requestid, self.streamid, streamflags, typeid, flags,
464 payload)
467 payload)
465
468
466 def ensureserverstream(stream):
469 def ensureserverstream(stream):
467 if stream.streamid % 2:
470 if stream.streamid % 2:
468 raise error.ProgrammingError('server should only write to even '
471 raise error.ProgrammingError('server should only write to even '
469 'numbered streams; %d is not even' %
472 'numbered streams; %d is not even' %
470 stream.streamid)
473 stream.streamid)
471
474
472 class serverreactor(object):
475 class serverreactor(object):
473 """Holds state of a server handling frame-based protocol requests.
476 """Holds state of a server handling frame-based protocol requests.
474
477
475 This class is the "brain" of the unified frame-based protocol server
478 This class is the "brain" of the unified frame-based protocol server
476 component. While the protocol is stateless from the perspective of
479 component. While the protocol is stateless from the perspective of
477 requests/commands, something needs to track which frames have been
480 requests/commands, something needs to track which frames have been
478 received, what frames to expect, etc. This class is that thing.
481 received, what frames to expect, etc. This class is that thing.
479
482
480 Instances are modeled as a state machine of sorts. Instances are also
483 Instances are modeled as a state machine of sorts. Instances are also
481 reactionary to external events. The point of this class is to encapsulate
484 reactionary to external events. The point of this class is to encapsulate
482 the state of the connection and the exchange of frames, not to perform
485 the state of the connection and the exchange of frames, not to perform
483 work. Instead, callers tell this class when something occurs, like a
486 work. Instead, callers tell this class when something occurs, like a
484 frame arriving. If that activity is worthy of a follow-up action (say
487 frame arriving. If that activity is worthy of a follow-up action (say
485 *run a command*), the return value of that handler will say so.
488 *run a command*), the return value of that handler will say so.
486
489
487 I/O and CPU intensive operations are purposefully delegated outside of
490 I/O and CPU intensive operations are purposefully delegated outside of
488 this class.
491 this class.
489
492
490 Consumers are expected to tell instances when events occur. They do so by
493 Consumers are expected to tell instances when events occur. They do so by
491 calling the various ``on*`` methods. These methods return a 2-tuple
494 calling the various ``on*`` methods. These methods return a 2-tuple
492 describing any follow-up action(s) to take. The first element is the
495 describing any follow-up action(s) to take. The first element is the
493 name of an action to perform. The second is a data structure (usually
496 name of an action to perform. The second is a data structure (usually
494 a dict) specific to that action that contains more information. e.g.
497 a dict) specific to that action that contains more information. e.g.
495 if the server wants to send frames back to the client, the data structure
498 if the server wants to send frames back to the client, the data structure
496 will contain a reference to those frames.
499 will contain a reference to those frames.
497
500
498 Valid actions that consumers can be instructed to take are:
501 Valid actions that consumers can be instructed to take are:
499
502
500 sendframes
503 sendframes
501 Indicates that frames should be sent to the client. The ``framegen``
504 Indicates that frames should be sent to the client. The ``framegen``
502 key contains a generator of frames that should be sent. The server
505 key contains a generator of frames that should be sent. The server
503 assumes that all frames are sent to the client.
506 assumes that all frames are sent to the client.
504
507
505 error
508 error
506 Indicates that an error occurred. Consumer should probably abort.
509 Indicates that an error occurred. Consumer should probably abort.
507
510
508 runcommand
511 runcommand
509 Indicates that the consumer should run a wire protocol command. Details
512 Indicates that the consumer should run a wire protocol command. Details
510 of the command to run are given in the data structure.
513 of the command to run are given in the data structure.
511
514
512 wantframe
515 wantframe
513 Indicates that nothing of interest happened and the server is waiting on
516 Indicates that nothing of interest happened and the server is waiting on
514 more frames from the client before anything interesting can be done.
517 more frames from the client before anything interesting can be done.
515
518
516 noop
519 noop
517 Indicates no additional action is required.
520 Indicates no additional action is required.
518
521
519 Known Issues
522 Known Issues
520 ------------
523 ------------
521
524
522 There are no limits to the number of partially received commands or their
525 There are no limits to the number of partially received commands or their
523 size. A malicious client could stream command request data and exhaust the
526 size. A malicious client could stream command request data and exhaust the
524 server's memory.
527 server's memory.
525
528
526 Partially received commands are not acted upon when end of input is
529 Partially received commands are not acted upon when end of input is
527 reached. Should the server error if it receives a partial request?
530 reached. Should the server error if it receives a partial request?
528 Should the client send a message to abort a partially transmitted request
531 Should the client send a message to abort a partially transmitted request
529 to facilitate graceful shutdown?
532 to facilitate graceful shutdown?
530
533
531 Active requests that haven't been responded to aren't tracked. This means
534 Active requests that haven't been responded to aren't tracked. This means
532 that if we receive a command and instruct its dispatch, another command
535 that if we receive a command and instruct its dispatch, another command
533 with its request ID can come in over the wire and there will be a race
536 with its request ID can come in over the wire and there will be a race
534 between who responds to what.
537 between who responds to what.
535 """
538 """
536
539
537 def __init__(self, deferoutput=False):
540 def __init__(self, deferoutput=False):
538 """Construct a new server reactor.
541 """Construct a new server reactor.
539
542
540 ``deferoutput`` can be used to indicate that no output frames should be
543 ``deferoutput`` can be used to indicate that no output frames should be
541 instructed to be sent until input has been exhausted. In this mode,
544 instructed to be sent until input has been exhausted. In this mode,
542 events that would normally generate output frames (such as a command
545 events that would normally generate output frames (such as a command
543 response being ready) will instead defer instructing the consumer to
546 response being ready) will instead defer instructing the consumer to
544 send those frames. This is useful for half-duplex transports where the
547 send those frames. This is useful for half-duplex transports where the
545 sender cannot receive until all data has been transmitted.
548 sender cannot receive until all data has been transmitted.
546 """
549 """
547 self._deferoutput = deferoutput
550 self._deferoutput = deferoutput
548 self._state = 'idle'
551 self._state = 'idle'
549 self._nextoutgoingstreamid = 2
552 self._nextoutgoingstreamid = 2
550 self._bufferedframegens = []
553 self._bufferedframegens = []
551 # stream id -> stream instance for all active streams from the client.
554 # stream id -> stream instance for all active streams from the client.
552 self._incomingstreams = {}
555 self._incomingstreams = {}
553 self._outgoingstreams = {}
556 self._outgoingstreams = {}
554 # request id -> dict of commands that are actively being received.
557 # request id -> dict of commands that are actively being received.
555 self._receivingcommands = {}
558 self._receivingcommands = {}
556 # Request IDs that have been received and are actively being processed.
559 # Request IDs that have been received and are actively being processed.
557 # Once all output for a request has been sent, it is removed from this
560 # Once all output for a request has been sent, it is removed from this
558 # set.
561 # set.
559 self._activecommands = set()
562 self._activecommands = set()
560
563
561 def onframerecv(self, frame):
564 def onframerecv(self, frame):
562 """Process a frame that has been received off the wire.
565 """Process a frame that has been received off the wire.
563
566
564 Returns a dict with an ``action`` key that details what action,
567 Returns a dict with an ``action`` key that details what action,
565 if any, the consumer should take next.
568 if any, the consumer should take next.
566 """
569 """
567 if not frame.streamid % 2:
570 if not frame.streamid % 2:
568 self._state = 'errored'
571 self._state = 'errored'
569 return self._makeerrorresult(
572 return self._makeerrorresult(
570 _('received frame with even numbered stream ID: %d') %
573 _('received frame with even numbered stream ID: %d') %
571 frame.streamid)
574 frame.streamid)
572
575
573 if frame.streamid not in self._incomingstreams:
576 if frame.streamid not in self._incomingstreams:
574 if not frame.streamflags & STREAM_FLAG_BEGIN_STREAM:
577 if not frame.streamflags & STREAM_FLAG_BEGIN_STREAM:
575 self._state = 'errored'
578 self._state = 'errored'
576 return self._makeerrorresult(
579 return self._makeerrorresult(
577 _('received frame on unknown inactive stream without '
580 _('received frame on unknown inactive stream without '
578 'beginning of stream flag set'))
581 'beginning of stream flag set'))
579
582
580 self._incomingstreams[frame.streamid] = stream(frame.streamid)
583 self._incomingstreams[frame.streamid] = stream(frame.streamid)
581
584
582 if frame.streamflags & STREAM_FLAG_ENCODING_APPLIED:
585 if frame.streamflags & STREAM_FLAG_ENCODING_APPLIED:
583 # TODO handle decoding frames
586 # TODO handle decoding frames
584 self._state = 'errored'
587 self._state = 'errored'
585 raise error.ProgrammingError('support for decoding stream payloads '
588 raise error.ProgrammingError('support for decoding stream payloads '
586 'not yet implemented')
589 'not yet implemented')
587
590
588 if frame.streamflags & STREAM_FLAG_END_STREAM:
591 if frame.streamflags & STREAM_FLAG_END_STREAM:
589 del self._incomingstreams[frame.streamid]
592 del self._incomingstreams[frame.streamid]
590
593
591 handlers = {
594 handlers = {
592 'idle': self._onframeidle,
595 'idle': self._onframeidle,
593 'command-receiving': self._onframecommandreceiving,
596 'command-receiving': self._onframecommandreceiving,
594 'errored': self._onframeerrored,
597 'errored': self._onframeerrored,
595 }
598 }
596
599
597 meth = handlers.get(self._state)
600 meth = handlers.get(self._state)
598 if not meth:
601 if not meth:
599 raise error.ProgrammingError('unhandled state: %s' % self._state)
602 raise error.ProgrammingError('unhandled state: %s' % self._state)
600
603
601 return meth(frame)
604 return meth(frame)
602
605
603 def onbytesresponseready(self, stream, requestid, data):
606 def onbytesresponseready(self, stream, requestid, data):
604 """Signal that a bytes response is ready to be sent to the client.
607 """Signal that a bytes response is ready to be sent to the client.
605
608
606 The raw bytes response is passed as an argument.
609 The raw bytes response is passed as an argument.
607 """
610 """
608 ensureserverstream(stream)
611 ensureserverstream(stream)
609
612
610 def sendframes():
613 def sendframes():
611 for frame in createbytesresponseframesfrombytes(stream, requestid,
614 for frame in createbytesresponseframesfrombytes(stream, requestid,
612 data):
615 data):
613 yield frame
616 yield frame
614
617
615 self._activecommands.remove(requestid)
618 self._activecommands.remove(requestid)
616
619
617 result = sendframes()
620 result = sendframes()
618
621
619 if self._deferoutput:
622 if self._deferoutput:
620 self._bufferedframegens.append(result)
623 self._bufferedframegens.append(result)
621 return 'noop', {}
624 return 'noop', {}
622 else:
625 else:
623 return 'sendframes', {
626 return 'sendframes', {
624 'framegen': result,
627 'framegen': result,
625 }
628 }
626
629
627 def oninputeof(self):
630 def oninputeof(self):
628 """Signals that end of input has been received.
631 """Signals that end of input has been received.
629
632
630 No more frames will be received. All pending activity should be
633 No more frames will be received. All pending activity should be
631 completed.
634 completed.
632 """
635 """
633 # TODO should we do anything about in-flight commands?
636 # TODO should we do anything about in-flight commands?
634
637
635 if not self._deferoutput or not self._bufferedframegens:
638 if not self._deferoutput or not self._bufferedframegens:
636 return 'noop', {}
639 return 'noop', {}
637
640
638 # If we buffered all our responses, emit those.
641 # If we buffered all our responses, emit those.
639 def makegen():
642 def makegen():
640 for gen in self._bufferedframegens:
643 for gen in self._bufferedframegens:
641 for frame in gen:
644 for frame in gen:
642 yield frame
645 yield frame
643
646
644 return 'sendframes', {
647 return 'sendframes', {
645 'framegen': makegen(),
648 'framegen': makegen(),
646 }
649 }
647
650
648 def onapplicationerror(self, stream, requestid, msg):
651 def onapplicationerror(self, stream, requestid, msg):
649 ensureserverstream(stream)
652 ensureserverstream(stream)
650
653
651 return 'sendframes', {
654 return 'sendframes', {
652 'framegen': createerrorframe(stream, requestid, msg,
655 'framegen': createerrorframe(stream, requestid, msg,
653 application=True),
656 application=True),
654 }
657 }
655
658
656 def makeoutputstream(self):
659 def makeoutputstream(self):
657 """Create a stream to be used for sending data to the client."""
660 """Create a stream to be used for sending data to the client."""
658 streamid = self._nextoutgoingstreamid
661 streamid = self._nextoutgoingstreamid
659 self._nextoutgoingstreamid += 2
662 self._nextoutgoingstreamid += 2
660
663
661 s = stream(streamid)
664 s = stream(streamid)
662 self._outgoingstreams[streamid] = s
665 self._outgoingstreams[streamid] = s
663
666
664 return s
667 return s
665
668
666 def _makeerrorresult(self, msg):
669 def _makeerrorresult(self, msg):
667 return 'error', {
670 return 'error', {
668 'message': msg,
671 'message': msg,
669 }
672 }
670
673
671 def _makeruncommandresult(self, requestid):
674 def _makeruncommandresult(self, requestid):
672 entry = self._receivingcommands[requestid]
675 entry = self._receivingcommands[requestid]
673 del self._receivingcommands[requestid]
676 del self._receivingcommands[requestid]
674
677
675 if self._receivingcommands:
678 if self._receivingcommands:
676 self._state = 'command-receiving'
679 self._state = 'command-receiving'
677 else:
680 else:
678 self._state = 'idle'
681 self._state = 'idle'
679
682
680 assert requestid not in self._activecommands
683 assert requestid not in self._activecommands
681 self._activecommands.add(requestid)
684 self._activecommands.add(requestid)
682
685
683 return 'runcommand', {
686 return 'runcommand', {
684 'requestid': requestid,
687 'requestid': requestid,
685 'command': entry['command'],
688 'command': entry['command'],
686 'args': entry['args'],
689 'args': entry['args'],
687 'data': entry['data'].getvalue() if entry['data'] else None,
690 'data': entry['data'].getvalue() if entry['data'] else None,
688 }
691 }
689
692
690 def _makewantframeresult(self):
693 def _makewantframeresult(self):
691 return 'wantframe', {
694 return 'wantframe', {
692 'state': self._state,
695 'state': self._state,
693 }
696 }
694
697
695 def _onframeidle(self, frame):
698 def _onframeidle(self, frame):
696 # The only frame type that should be received in this state is a
699 # The only frame type that should be received in this state is a
697 # command request.
700 # command request.
698 if frame.typeid != FRAME_TYPE_COMMAND_NAME:
701 if frame.typeid != FRAME_TYPE_COMMAND_NAME:
699 self._state = 'errored'
702 self._state = 'errored'
700 return self._makeerrorresult(
703 return self._makeerrorresult(
701 _('expected command frame; got %d') % frame.typeid)
704 _('expected command frame; got %d') % frame.typeid)
702
705
703 if frame.requestid in self._receivingcommands:
706 if frame.requestid in self._receivingcommands:
704 self._state = 'errored'
707 self._state = 'errored'
705 return self._makeerrorresult(
708 return self._makeerrorresult(
706 _('request with ID %d already received') % frame.requestid)
709 _('request with ID %d already received') % frame.requestid)
707
710
708 if frame.requestid in self._activecommands:
711 if frame.requestid in self._activecommands:
709 self._state = 'errored'
712 self._state = 'errored'
710 return self._makeerrorresult((
713 return self._makeerrorresult((
711 _('request with ID %d is already active') % frame.requestid))
714 _('request with ID %d is already active') % frame.requestid))
712
715
713 expectingargs = bool(frame.flags & FLAG_COMMAND_NAME_HAVE_ARGS)
716 expectingargs = bool(frame.flags & FLAG_COMMAND_NAME_HAVE_ARGS)
714 expectingdata = bool(frame.flags & FLAG_COMMAND_NAME_HAVE_DATA)
717 expectingdata = bool(frame.flags & FLAG_COMMAND_NAME_HAVE_DATA)
715
718
716 self._receivingcommands[frame.requestid] = {
719 self._receivingcommands[frame.requestid] = {
717 'command': frame.payload,
720 'command': frame.payload,
718 'args': {},
721 'args': {},
719 'data': None,
722 'data': None,
720 'expectingargs': expectingargs,
723 'expectingargs': expectingargs,
721 'expectingdata': expectingdata,
724 'expectingdata': expectingdata,
722 }
725 }
723
726
724 if frame.flags & FLAG_COMMAND_NAME_EOS:
727 if frame.flags & FLAG_COMMAND_NAME_EOS:
725 return self._makeruncommandresult(frame.requestid)
728 return self._makeruncommandresult(frame.requestid)
726
729
727 if expectingargs or expectingdata:
730 if expectingargs or expectingdata:
728 self._state = 'command-receiving'
731 self._state = 'command-receiving'
729 return self._makewantframeresult()
732 return self._makewantframeresult()
730 else:
733 else:
731 self._state = 'errored'
734 self._state = 'errored'
732 return self._makeerrorresult(_('missing frame flags on '
735 return self._makeerrorresult(_('missing frame flags on '
733 'command frame'))
736 'command frame'))
734
737
735 def _onframecommandreceiving(self, frame):
738 def _onframecommandreceiving(self, frame):
736 # It could be a new command request. Process it as such.
739 # It could be a new command request. Process it as such.
737 if frame.typeid == FRAME_TYPE_COMMAND_NAME:
740 if frame.typeid == FRAME_TYPE_COMMAND_NAME:
738 return self._onframeidle(frame)
741 return self._onframeidle(frame)
739
742
740 # All other frames should be related to a command that is currently
743 # All other frames should be related to a command that is currently
741 # receiving but is not active.
744 # receiving but is not active.
742 if frame.requestid in self._activecommands:
745 if frame.requestid in self._activecommands:
743 self._state = 'errored'
746 self._state = 'errored'
744 return self._makeerrorresult(
747 return self._makeerrorresult(
745 _('received frame for request that is still active: %d') %
748 _('received frame for request that is still active: %d') %
746 frame.requestid)
749 frame.requestid)
747
750
748 if frame.requestid not in self._receivingcommands:
751 if frame.requestid not in self._receivingcommands:
749 self._state = 'errored'
752 self._state = 'errored'
750 return self._makeerrorresult(
753 return self._makeerrorresult(
751 _('received frame for request that is not receiving: %d') %
754 _('received frame for request that is not receiving: %d') %
752 frame.requestid)
755 frame.requestid)
753
756
754 entry = self._receivingcommands[frame.requestid]
757 entry = self._receivingcommands[frame.requestid]
755
758
756 if frame.typeid == FRAME_TYPE_COMMAND_ARGUMENT:
759 if frame.typeid == FRAME_TYPE_COMMAND_ARGUMENT:
757 if not entry['expectingargs']:
760 if not entry['expectingargs']:
758 self._state = 'errored'
761 self._state = 'errored'
759 return self._makeerrorresult(_(
762 return self._makeerrorresult(_(
760 'received command argument frame for request that is not '
763 'received command argument frame for request that is not '
761 'expecting arguments: %d') % frame.requestid)
764 'expecting arguments: %d') % frame.requestid)
762
765
763 return self._handlecommandargsframe(frame, entry)
766 return self._handlecommandargsframe(frame, entry)
764
767
765 elif frame.typeid == FRAME_TYPE_COMMAND_DATA:
768 elif frame.typeid == FRAME_TYPE_COMMAND_DATA:
766 if not entry['expectingdata']:
769 if not entry['expectingdata']:
767 self._state = 'errored'
770 self._state = 'errored'
768 return self._makeerrorresult(_(
771 return self._makeerrorresult(_(
769 'received command data frame for request that is not '
772 'received command data frame for request that is not '
770 'expecting data: %d') % frame.requestid)
773 'expecting data: %d') % frame.requestid)
771
774
772 if entry['data'] is None:
775 if entry['data'] is None:
773 entry['data'] = util.bytesio()
776 entry['data'] = util.bytesio()
774
777
775 return self._handlecommanddataframe(frame, entry)
778 return self._handlecommanddataframe(frame, entry)
776
779
777 def _handlecommandargsframe(self, frame, entry):
780 def _handlecommandargsframe(self, frame, entry):
778 # The frame and state of command should have already been validated.
781 # The frame and state of command should have already been validated.
779 assert frame.typeid == FRAME_TYPE_COMMAND_ARGUMENT
782 assert frame.typeid == FRAME_TYPE_COMMAND_ARGUMENT
780
783
781 offset = 0
784 offset = 0
782 namesize, valuesize = ARGUMENT_FRAME_HEADER.unpack_from(frame.payload)
785 namesize, valuesize = ARGUMENT_FRAME_HEADER.unpack_from(frame.payload)
783 offset += ARGUMENT_FRAME_HEADER.size
786 offset += ARGUMENT_FRAME_HEADER.size
784
787
785 # The argument name MUST fit inside the frame.
788 # The argument name MUST fit inside the frame.
786 argname = bytes(frame.payload[offset:offset + namesize])
789 argname = bytes(frame.payload[offset:offset + namesize])
787 offset += namesize
790 offset += namesize
788
791
789 if len(argname) != namesize:
792 if len(argname) != namesize:
790 self._state = 'errored'
793 self._state = 'errored'
791 return self._makeerrorresult(_('malformed argument frame: '
794 return self._makeerrorresult(_('malformed argument frame: '
792 'partial argument name'))
795 'partial argument name'))
793
796
794 argvalue = bytes(frame.payload[offset:])
797 argvalue = bytes(frame.payload[offset:])
795
798
796 # Argument value spans multiple frames. Record our active state
799 # Argument value spans multiple frames. Record our active state
797 # and wait for the next frame.
800 # and wait for the next frame.
798 if frame.flags & FLAG_COMMAND_ARGUMENT_CONTINUATION:
801 if frame.flags & FLAG_COMMAND_ARGUMENT_CONTINUATION:
799 raise error.ProgrammingError('not yet implemented')
802 raise error.ProgrammingError('not yet implemented')
800
803
801 # Common case: the argument value is completely contained in this
804 # Common case: the argument value is completely contained in this
802 # frame.
805 # frame.
803
806
804 if len(argvalue) != valuesize:
807 if len(argvalue) != valuesize:
805 self._state = 'errored'
808 self._state = 'errored'
806 return self._makeerrorresult(_('malformed argument frame: '
809 return self._makeerrorresult(_('malformed argument frame: '
807 'partial argument value'))
810 'partial argument value'))
808
811
809 entry['args'][argname] = argvalue
812 entry['args'][argname] = argvalue
810
813
811 if frame.flags & FLAG_COMMAND_ARGUMENT_EOA:
814 if frame.flags & FLAG_COMMAND_ARGUMENT_EOA:
812 if entry['expectingdata']:
815 if entry['expectingdata']:
813 # TODO signal request to run a command once we don't
816 # TODO signal request to run a command once we don't
814 # buffer data frames.
817 # buffer data frames.
815 return self._makewantframeresult()
818 return self._makewantframeresult()
816 else:
819 else:
817 return self._makeruncommandresult(frame.requestid)
820 return self._makeruncommandresult(frame.requestid)
818 else:
821 else:
819 return self._makewantframeresult()
822 return self._makewantframeresult()
820
823
821 def _handlecommanddataframe(self, frame, entry):
824 def _handlecommanddataframe(self, frame, entry):
822 assert frame.typeid == FRAME_TYPE_COMMAND_DATA
825 assert frame.typeid == FRAME_TYPE_COMMAND_DATA
823
826
824 # TODO support streaming data instead of buffering it.
827 # TODO support streaming data instead of buffering it.
825 entry['data'].write(frame.payload)
828 entry['data'].write(frame.payload)
826
829
827 if frame.flags & FLAG_COMMAND_DATA_CONTINUATION:
830 if frame.flags & FLAG_COMMAND_DATA_CONTINUATION:
828 return self._makewantframeresult()
831 return self._makewantframeresult()
829 elif frame.flags & FLAG_COMMAND_DATA_EOS:
832 elif frame.flags & FLAG_COMMAND_DATA_EOS:
830 entry['data'].seek(0)
833 entry['data'].seek(0)
831 return self._makeruncommandresult(frame.requestid)
834 return self._makeruncommandresult(frame.requestid)
832 else:
835 else:
833 self._state = 'errored'
836 self._state = 'errored'
834 return self._makeerrorresult(_('command data frame without '
837 return self._makeerrorresult(_('command data frame without '
835 'flags'))
838 'flags'))
836
839
837 def _onframeerrored(self, frame):
840 def _onframeerrored(self, frame):
838 return self._makeerrorresult(_('server already errored'))
841 return self._makeerrorresult(_('server already errored'))
General Comments 0
You need to be logged in to leave comments. Login now