[MERGE][RFC] Proposed version 3 of smart server protocol
Andrew Bennetts
andrew at canonical.com
Thu Feb 14 23:02:45 GMT 2008
Hi,
This is an update of the proposed version 3 of the smart server protocol.
It's not radically different to the originally posted version. Robert did
suggest putting the response args after the response body to avoid having two
sets of arguments in the response, but Martin convinced me that this isn't worth
doing. Martin would like to keep the symmetry between requests and responses,
and also pointed out that it would be useful for a client to have a way to
explicitly interrupt a streamed body with an error.
I'm well on the way to implementing this, patches should be on the list soon. I
expect this protocol will be in 1.3. Comments, as always, are very welcome.
-Andrew.
-------------- next part --------------
# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: andrew.bennetts at canonical.com-20080214225755-\
# fzmw8cgiw3thn9uk
# target_branch: http://bazaar-vcs.org/bzr/bzr.dev
# testament_sha1: adc68fbc01525afbcd9702fa1a8a4b5fce455439
# timestamp: 2008-02-15 09:58:28 +1100
# source_branch: http://people.ubuntu.com/~andrew/bzr/protocol-v3-doc
# base_revision_id: pqm at pqm.ubuntu.com-20080201053934-q32y2nk5vvo13c6v
#
# Begin patch
=== modified file 'doc/default.css'
--- doc/default.css 2007-08-07 14:56:50 +0000
+++ doc/default.css 2008-02-07 07:05:13 +0000
@@ -35,6 +35,21 @@
color: inherit;
}
+/* Format ".. note:" sections nicely */
+div.note {
+ margin-left: 5em;
+ margin-right: 5em;
+ color: #000000;
+ background-color: #c1d1ff;
+ border: 1px solid #888888;
+ padding-left: 1em;
+ padding-right: 1em;
+ }
+
+div.note .first {
+ font-weight: bold;
+ }
+
h1 {
color: #b52b2b;
/* DKREDcolor: #966b72; */
@@ -124,7 +139,6 @@
margin-right: 5em;
color: #000000;
font-weight: normal;
- background-color: #c1d1ff;
background-color: #e5ecf9;
border: 1px solid #888888;
padding: 1em;
=== modified file 'doc/developers/network-protocol.txt'
--- doc/developers/network-protocol.txt 2007-11-09 20:49:54 +0000
+++ doc/developers/network-protocol.txt 2008-02-14 22:57:55 +0000
@@ -118,7 +118,7 @@
REQUEST := MESSAGE_V1
RESPONSE := MESSAGE_V1
- MESSAGE_V1 := ARGS BODY
+ MESSAGE_V1 := ARGS [BODY]
ARGS := ARG [MORE_ARGS] NEWLINE
MORE_ARGS := SEP ARG [MORE_ARGS]
@@ -144,7 +144,8 @@
The response protocol is::
- RESPONSE_V2 := "bzr response 2" NEWLINE MESSAGE_V2
+ RESPONSE_V2 := "bzr response 2" NEWLINE RESPONSE_STATUS NEWLINE MESSAGE_V2
+ RESPONSE_STATUS := "success" | "failed"
Future versions should follow this structure, like version two does::
@@ -160,7 +161,7 @@
Version two of the message protocol is::
- MESSAGE_V2 := ARGS BODY
+ MESSAGE_V2 := ARGS [BODY_V2]
BODY_V2 := BODY | STREAMED_BODY
That is, a version one length-prefixed body, or a version two streamed
@@ -174,8 +175,8 @@
STREAMED_BODY := "chunked" NEWLINE CHUNKS TERMINATOR
CHUNKS := CHUNK [CHUNKS]
- CHUNK := CHUNK_LENGTH CHUNK_CONTENT
- CHUNK_LENGTH := HEX_DIGITS NEWLINE
+ CHUNK := HEX_LENGTH CHUNK_CONTENT
+ HEX_LENGTH := HEX_DIGITS NEWLINE
CHUNK_CONTENT := bytes
TERMINATOR := SUCCESS_TERMINATOR | ERROR_TERMINATOR
@@ -196,6 +197,104 @@
same for a given request method. Only new request methods introduced in
Bazaar 0.91 and later use streamed bodies.
+Version three
+-------------
+
+.. note::
+
+ For some discussion of the requirements that led to this new protocol
+ version, see `bug #83935`_.
+
+.. _bug #83935: https://bugs.launchpad.net/bzr/+bug/83935
+
+Version three has bencoding of most protocol structures, to make parsing
+simpler. For extra parsing convenience, these structures are length
+prefixed::
+
+ LENGTH_PREFIX := 32-bit unsigned integer in network byte order
+
+The request and response protocol is::
+
+ REQUEST_V3 := "bzr request 3" NEWLINE HEADERS ARGS_V3 BODY_V3
+ RESPONSE_V3 := "bzr response 3" NEWLINE HEADERS RESPONSE_STATUS
+ ARGS_V3 BODY_V3
+ RESPONSE_STATUS_V3 := SUCCESS_STATUS | ERROR_STATUS
+ SUCCESS_STATUS := "S"
+ ERROR_STATUS := "E"
+ HEADERS := LENGTH_PREFIX bencoded_dictionary
+
+Each request and response will have ?headers?, a dictionary of key-value pairs.
+The keys must be strings, not any other type of value.
+
+Currently, the only defined header is ?Software version?. Both the client and
+the server should include a ?Software version? header, with a value of a
+free-form string such as ?bzrlib 1.3?, to aid debugging and logging. Clients
+and servers **should not** vary behaviour based on this string.
+
+The argument encoding is::
+
+ ARGS_V3 := LENGTH_PREFIX bencoded_sequence
+
+Arguments in this protocol version are bencoded, and the entire argument
+structure is length-prefixed. As a result, unlike previous protocol versions,
+arguments in this version are 8-bit clean.
+
+For requests, the first item in the encoded sequence must be a string of
+the request's verb, e.g. ``Branch.last_revision_info``. Thus requests must
+always have at least one item in their ARGS_V3 sequence.
+
+For error responses (where the RESPONSE_STATUS_V3 is ERROR_STATUS), the
+situation is analagous to requests. The first item in the encoded sequence must
+be a string of the error name. The other arguments supply details about the
+error, and their number and types will depend on the type of error (as
+identified by the error name).
+
+For success responses, there are no restrictions on the sequence. It may
+be empty, and the first element does not have to be a string. The
+contents are entirely dependent on the verb.
+
+One possible error name is ``UnknownRequestVerb``, which means the server does
+not recognise the verb used by the client's request.
+
+The body encoding is::
+
+ BODY_V3 := NO_BODY | LENGTH_PREFIXED_BODY | STREAMED_BODY_V2
+ NO_BODY := "n"
+ LENGTH_PREFIXED_BODY := "p" LENGTH_PREFIX BODY_BYTES
+ STREAMED_BODY_V2 := "s" CHUNKS_V2
+
+ CHUNKS_V2 := CHUNK_V2 | CHUNKS_TERMINATOR
+ CHUNK_V2 := "c" LENGTH_PREFIX CHUNK_CONTENT CHUNK_V2
+ CHUNKS_TERMINATOR := "t" BODY_STATUS
+ BODY_STATUS := SUCCESS_STATUS | BODY_ERROR
+ BODY_ERROR := ERROR_STATUS ARGS_V3
+
+Version 3 messages always explicitly declare if a body is included. The
+absence of a body is signalled by sending NO_BODY as the body type. If
+present, bodies may be a single length-prefixed string (similar to
+protocol 1) or a stream of chunks (similar to the streamed bodies in
+protocol 2).
+
+Unlike earlier versions, clients and servers are no longer required to
+know which request verbs and responses will have bodies attached. It is
+always possible to know when a complete request or response has been read,
+even if the server implements no verbs.
+
+If an error occurs while a client or a server is generating a streamed
+body, the sender should finish the stream and use BODY_ERROR as the
+BODY_STATUS. The ARGS_V3 in an BODY_ERROR should be encoded the same way
+as errors in the ARGS_V3 of RESPONSE_V3: the first argument should be a
+string of the error name, and the rest of the arguments are details about
+that error.
+
+Note that clients can interrupt a stream with an error, not just servers.
+Clients can use this to signal to the server that the request should be
+aborted, due to an unexpected failure while generating the request.
+Servers are still required to respond to these requests (a possible
+response in this case could be an ``InterruptedRequest`` error). Clients
+should be aware that, depending on the verb, servers may have already
+successful processed the chunks received before the interruption.
+
Paths
=====
@@ -230,6 +329,14 @@
Contributions welcome!
+Recognised errors
+=================
+
+The first argument of an error response specifies the error type.
+
+**XXX**: ideally the error types should be documented here. Contributions
+welcome!
+
..
vim: ft=rst tw=74 ai
# Begin bundle
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
More information about the bazaar
mailing list