1 This is a draft, and subject to change. Please do not implement it
4 Examples can be found at the bottom of the file.
6 Thank you for your feedback!
13 The Binmode RPC Protocol
14 ========================
16 Binmode RPC is an ultra-lightweight RPC protocol designed for 100%
17 compatibility with XML-RPC <http://www.xmlrpc.com/>. It emphasizes
18 simplicity, dynamically-typed data, and extreme ease of implementation.
20 Two XML-RPC implementations that support 'binmode-rpc' may negotiate away
21 the XML part of XML-RPC, and replace it with a simple binary protocol.
25 * The complete specification should fit in a 350-line text file. :-)
26 * The protocol should be easy to implement.
27 * The protocol should provide a high degree of compression.
28 * The protocol should be very fast--faster than zlib compression.
29 * The protocol must be implementable in portable ANSI C, with no
31 * The protocol must not contain any options, variant encodings
32 or similar hair. If you want DCE/RPC, you know where to find it.
33 * All protocol operations must be performed at the byte level
34 (except for UTF-8 encoding and decoding).
35 * The protocol must be semi-readable in a hex dump or Emacs buffer.
36 * The protocol must efficiently encode boxcarred calls that are
37 implemented using 'system.multicall'.
38 * The protocol must support an efficient encoding for
39 frequently-repeated string values.
41 * The protocol must never be sent to clients or servers which
43 * There must be a way for clients and servers to active the protocol
44 if both ends of the connection support it.
47 The X-XML-RPC-Extensions Header
48 -------------------------------
50 (First, we'll need a mechanism for unobtrusively announcing the presence of
51 non-standard capabilities.)
53 An XML-RPC implementation MAY advertise additional, non-standard
54 capabilities using the 'X-XML-RPC-Extensions' header.
56 Rationale: The 'X-XML-RPC-Extensions' header should be available to CGI
57 scripts in the environment variable HTTP_X_XML_RPC_EXTENSIONS.
59 If present, this header MUST contain a comma-separated list of
60 keywords. Parameter information MAY be included, if desired, in the
61 standard fashion used by HTTP 1.1 'Accept-Encoding' headers.
63 X-XML-RPC-Extensions: binmode-rpc
64 X-XML-RPC-Extensions: binmode-rpc, x-telepathic-transport
65 X-XML-RPC-Extensions: binmode-rpc,x-telepathic-transport
66 X-XML-RPC-Extensions: binmode-rpc, x-telepathic-transport;speed=low
68 If a client sends the X-XML-RPC-Extensions header in a request, the server
69 MAY use any of the specified extensions in its response.
71 Rationale: No client may be sent non-standard data without first having
72 advertised the ability to accept it.
74 If the server includes the X-XML-RPC-Extensions header in a response, the
75 client MAY use any of the specified extensions in further requests to that
76 URL. The client MUST NOT assume that the same extensions are available for
77 any other URL on the same server.
79 Rationale: No server may be sent non-standard data without first having
80 advertised the ability to accept it. Furthermore, this permission is
81 URL-specific, since different XML-RPC implementations may be located at
82 different URLs on a single server.
84 The client SHOULD NOT cache extension information about a particular server
85 for an excessive length of time (typically beyond a single program
86 invocation). If the client does cache this information indefinitely, it
87 SHOULD be able to cope if an extension is disabled.
89 Rationale: The XML-RPC implementation used on the server may be changed by
93 The 'binmode-rpc' Extension
94 -----------------------
96 A client or server which sends the 'binmode-rpc' extension MUST accept
97 message bodies of type 'application/x-binmode-rpc' in addition to the
100 All servers which accept the binmode-rpc extension MUST also support
101 standard XML-RPC, as described by <http://www.xmlrpc.org/spec>.
104 The 'application/x-binmode-rpc' Format
105 --------------------------------------
107 All documents of the type 'application/x-binmode-rpc' MUST begin with the
108 following byte sequence (represented here as a C string):
112 This MUST be followed by a Call or a Response, encoded as described below:
114 Call := 'C' String Array
116 A Call consists of a single octet with the ASCII value 'C', followed by a
117 String containing the method name and an Array containing the parameters.
119 Response := 'R' (Value|Fault)
121 A Response MUST contain either a Value or a Fault.
125 A Fault contains a regular Struct (with members as specified by the the
126 XML-RPC specification).
128 Trailing data at the end of an 'application/x-binmode-rpc' document MUST be
132 Byte-Order of Integers
133 ----------------------
135 (The following integer types don't correspond directly to XML-RPC
136 integers--instead, they'll be used to *build* more complicated types.)
138 SignedLSB := a four-octet, signed, twos'-complement integer,
139 least-significant byte (LSB) first
140 UnsignedLSB := a four-octet, unsigned integer, LSB first
142 Raw integer data is encoded in little-endian format.
144 Rationale: A fixed, mandatory byte ordering is easier to implement than
145 approaches which allow multiple byte orderings, and little-endian CPUs
146 outnumber big-endian CPUs at the time of writing.
152 Value := (Integer|Boolean|Double|DateTimeISO8601Binary|Array|Struct|
155 Integer := 'I' SignedLSB
158 Double := 'D' SizeOctet AsciiChar...
159 DateTimeISO8601 := '8' SizeOctet AsciiChar...
161 These two types are encoded with an unsigned size octet followed by the
162 specified number of ASCII characters. The values are encoded in the fashion
163 described by the XML-RPC specification.
165 Rationale: In both these cases, we're punting. Binary floating point
166 formats are highly non-portable, and cannot be easily manipulated by most
167 programming languages. XML-RPC <dateTime.iso8601> values lack timezone
168 information, and are therefore difficult to convert to a binary format.
170 Binary := 'B' UnsignedLSB Octet...
172 This corresponds to the XML-RPC <base64> type, but without any encoding.
173 The UnsignedLSB specifies the number of octets of data.
175 Array := 'A' UnsignedLSB Value...
177 The UnsignedLSB specifies the number of values in the array.
179 Struct := 'S' UnsignedLSB (String,Value)...
181 The UnsignedLSB specifies the number of String,Value pairs in the struct.
182 The strings are keys; the values may be of any type.
184 Other := 'O' String Binary
186 Future XML-RPC types (if any) may be sent a String containing the type name
187 and a Binary block (as above) containing type-specific data.
188 Implementations MUST NOT encode any of the standard types using this
189 construct. Implementations MAY signal an error if data of type Other is
192 Rationale: This is allowed to cause an error because most applications
193 won't understand the contents anyway. But if new types are added, dumb
194 gateways will be able to manipulate them in encapsulated format (if they so
201 String := (RegularString|RecordedString|RecalledString)
203 We have three types of strings.
205 RegularString := 'U' StringData
206 StringData := UnsignedLSB Utf8Octet...
208 Strings are encoded in UTF-8 format. The UnsignedLSB specifies the number
209 of UTF-8 octets. Implementations SHOULD raise an error if they encounter
210 invalid UTF-8 data (e.g., ISO Latin 1 characters).
212 Rationale: Technically speaking, XML-RPC is limited to plain ASCII
213 characters, and may not contain 8-bit or 16-bit characters in any coding
214 system. But since XML-RPC is based on XML, adding Unicode is a trivial
215 enhancement to the basic protocol, and *somebody* will make it sooner or
216 later. When that day arrives, we want to be able to encode Unicode
219 Implements MUST encode UTF-8 characters using the minimum number of octets.
220 Implementations SHOULD raise an error if they encounter any UTF-8
221 characters encoded using more than the minimum number of octets.
223 Rationale: Overlong UTF-8 encodings are sometimes used to bypass string
224 validation in security code. They serve no legitimate purpose, either. So
225 to improve the overall security of the Universe, we work hard to discourage
228 UTF-8 & Unicode FAQ: http://www.cl.cam.ac.uk/~mgk25/unicode.html
230 RecordedString := '>' CodebookPosition StringData
231 RecalledString := '<' CodebookPosition
232 CodebookPosition := UnsignedOctet
234 The 'binmode' format supports a 256-entry "codebook" of strings. At the
235 start of a data stream, the codebook is empty. When the decoder
236 encounters a RecordedString, it MUST store it into the specified codebook
237 position (and then proceed to decode it as a regular string).
239 When the decoder encounters a RecalledString, it MUST look it up in the
240 specified codebook position. If that codebook position has been set, the
241 implementation MUST use the string value found in the codebook. If the
242 position has not been set, the implementation MUST stop decoding and raise
243 an error. It is legal to change a codebook position once it has been set;
244 the most recent value applies.
246 A RecordedString or a RecalledString may be used anywhere a RegularString
249 Rationale: XML-RPC data tends to contain large numbers of identical
250 strings. (These are typically the names of <struct> members or the names of
251 methods in a multicall.) To get any kind of reasonable data compression,
252 it's necessary to have some way of compressing these values. The codebook
253 mechanism is relatively simple and uncomplicated.
255 Implementations MAY choose not to use this feature when encoding data, but
256 MUST understand it when decoding data.
258 Rationale: On the decoding end of things, this feature is trivial to
259 implement, and must be present for the sake of interoperability. On the
260 encoding end of things, however, making effective use of this feature is
261 slightly trickier, so implementations are allowed (but not encouraged) to
268 Implementations MUST implement all features of this protocol correctly,
269 particularly on the decoding end. In the case of this protocol, a 95% correct
270 implementation is 100% broken. Yes, this statement is redundant. ;-)
276 Non-ASCII octets are specified as in C strings. Continued lines are
277 indicated by a trailing '\'; these should be joined together as one
280 binmode-rpc:CU\003\0\0\0addA\002\0\0\0I\002\0\0\0I\002\0\0\0
282 binmode-rpc:RI\004\0\0\0
284 binmode-rpc:RFS\002\0\0\0 \
285 U\011\0\0\0faultCodeI\001\0\0\0 \
286 U\013\0\0\0faultStringU\021\0\0\0An error occurred
288 binmode-rpc:RA\006\0\0\0 \
296 (This deserializes to ['foo', 'bar', 'foo', 'baz', 'baz', 'bar'].)
298 binmode-rpc:RU\042\0\0\0Copyright \302\251 1995 J. Random Hacker
300 (This is based on an example in the Unicode/UTF-8 FAQ (see above).)
302 binmode-rpc:RA\010\0\0\0 \
306 8\02119980717T14:08:55 \
309 S\002\0\0\0U\003\0\0\0runt
314 The following specimens are illegal, and SHOULD be rejected by a compliant
315 implementation. Please test your code.
317 * A different format name:
319 binmode-rpc2:RI\004\0\0\0
321 * A built-in type incorrectly encoded using 'O':
323 binmode-rpc:ROU\006\0\0\0stringB\003\0\0\0xyz
325 * A recall of an unrecorded string:
329 * ISO Latin 1 data in a string. (UTF-8 required!)
331 binmode-rpc:RU\041\0\0\0Copyright \251 1995 J. Random Hacker
333 * UTF-8 character encoded with too many octets (based on an example in the
336 binmode-rpc:RU\041\0\0\0Bad linefeed: \300\212 (too many bytes)
338 A compliant implementation MUST NOT send any of these sequences.