[MERGE][RFC] Proposed version 3 of smart server protocol

Andrew Bennetts andrew at canonical.com
Wed Feb 20 12:22:10 GMT 2008


Andrew Bennetts wrote:
> Hi,
> 
> This is an update of the proposed version 3 of the smart server protocol.

Here's what I hope is the final version.  It's significantly changed from the
initial draft from a few weeks ago, so if you're interested take a look.

This version leaves considerably more flexibility in the protocol, so hopefully
there's plenty of room to implement new methods without wanting yet another
protocol revision.  This was done after a lengthy discussion between Robert,
Martin and myself, so hopefully now everyone should be happy :)

-Andrew.

-------------- next part --------------
# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: andrew.bennetts at canonical.com-20080220121704-\
#   h65l9ol4g1d4dk0v
# target_branch: http://bazaar-vcs.org/bzr/bzr.dev
# testament_sha1: c75cf882fdc20edf9e9b547f6d3a05cfa1018bb5
# timestamp: 2008-02-20 23:17:27 +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-20 12:17:04 +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,107 @@
 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
+
+Unlike earlier versions, clients and servers are no longer required to
+know which request verbs and responses will have bodies attached.  Because
+of length-prefixing and other changes, it is always possible to know when
+a complete request or response has been read, even if the server
+implements no verbs.
+
+The underlying message format is::
+
+  MESSAGE := "bzr message 3" NEWLINE HEADERS MESSAGE_PARTS
+  HEADERS := LENGTH_PREFIX bencoded_dict
+  MESSAGE_PARTS := MESSAGE_PART [MORE_MESSAGE_PARTS]
+  MORE_MESSAGE_PARTS := END_MESSAGE_PARTS | MESSAGE_PARTS
+  END_MESSAGE_PARTS := "e"
+
+  MESSAGE_PART := ONE_BYTE | STRUCTURE | BYTES
+  ONE_BYTE := "o" byte
+  STRUCTURE := "s" LENGTH_PREFIX bencoded_structure
+  BYTES := "b" LENGTH_PREFIX bytes
+
+This format allows an arbitrary sequence of message parts to be encoded
+in a single message.
+
+Headers
+~~~~~~~
+
+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.
+
+Conventional requests and responses
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+By convention, most requests and responses have a simple ?arguments plus
+optional body? structure, as in earlier protocol versions.  This section
+describes how such messages are encoded.  All requests and responses
+defined by earlier protocol versions must be encoded in this way.
+
+Conventional requests will send a sequence of:
+
+* Arguments (a STRUCTURE of a tuple)
+
+* (Optional) body
+
+  * Single body (BYTES), or
+
+  * Streamed body (multiple BYTES parts), followed by a status (ONE_BYTE)
+
+    * if status is "E", followed by an Error (STRUCTURE)
+
+Conventional responses will send a sequence of:
+
+* Status (ONE_BYTE)
+
+* Arguments (a STRUCTURE of a tuple)
+
+* (Optional) body
+
+  * Single body (BYTES), or
+
+  * Streamed body (multiple BYTES parts), followed by a status (ONE_BYTE)
+
+    * if status is "E", followed by an Error (STRUCTURE)
+
+In all cases, the ONE_BYTE status is either "S" for Success or "E" for
+Error.  Note that the streamed body from version two is now just multiple
+BYTES parts.
+
+For new methods, these sequences are just a convention and may be varied
+if appropriate for a particular request or response.  However, each
+request should at least start with a STRUCTURE encoding the arguments
+tuple.  The first element of that tuple must be a string that names the
+request method.  (Note that arguments in this protocol version are
+bencoded.  As a result, unlike previous protocol versions, arguments in
+this version are 8-bit clean.)
+
+For errors (where the Status byte of a response or a streamed body is
+"E"), 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).
+
 Paths
 =====
 
@@ -230,6 +332,18 @@
 Contributions welcome!
 
 
+Recognised errors
+=================
+
+The first argument of an error response specifies the error type.
+
+One possible error name is ``UnknownRequestVerb``, which means the server does
+not recognise the verb used by the client's request.  This error was
+introduced in version three.
+
+**XXX**: ideally the error types should be documented here.  Contributions
+welcome!
+
 ..
    vim: ft=rst tw=74 ai
 

# Begin bundle
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
D/YHuD+IP8QbDx0bXrzw/sLuSKcKEgVrk2wg


More information about the bazaar mailing list