diff -r 37d7a1d18b97 -r 40206e227412 mercurial/help/internals/wireprotocol.txt --- a/mercurial/help/internals/wireprotocol.txt Tue Mar 13 19:44:59 2018 -0700 +++ b/mercurial/help/internals/wireprotocol.txt Mon Mar 19 16:49:53 2018 -0700 @@ -187,12 +187,15 @@ Requests to unknown commands or URLS result in an HTTP 404. TODO formally define response type, how error is communicated, etc. -HTTP request and response bodies use the *TBD Protocol* for media exchange. +HTTP request and response bodies use the *Unified Frame-Based Protocol* +(defined below) for media exchange. The entirety of the HTTP message +body is 0 or more frames as defined by this protocol. Clients and servers MUST advertise the ``TBD`` media type via the ``Content-Type`` request and response headers. In addition, clients MUST advertise this media type value in their ``Accept`` request header in all requests. +TODO finalize the media type. For now, it is defined in wireprotoserver.py. Servers receiving requests without an ``Accept`` header SHOULD respond with an HTTP 406. @@ -429,7 +432,7 @@ SSH Version 2 Transport ----------------------- -**Experimental** +**Experimental and under development** Version 2 of the SSH transport behaves identically to version 1 of the SSH transport with the exception of handshake semantics. See above for how @@ -451,6 +454,164 @@ Following capabilities advertisement, the peers communicate using version 1 of the SSH transport. +Unified Frame-Based Protocol +============================ + +**Experimental and under development** + +The *Unified Frame-Based Protocol* is a communications protocol between +Mercurial peers. The protocol aims to be mostly transport agnostic +(works similarly on HTTP, SSH, etc). + +To operate the protocol, a bi-directional, half-duplex pipe supporting +ordered sends and receives is required. That is, each peer has one pipe +for sending data and another for receiving. + +The protocol is request-response based: the client issues requests to +the server, which issues replies to those requests. Server-initiated +messaging is not supported. + +All data is read and written in atomic units called *frames*. These +are conceptually similar to TCP packets. Higher-level functionality +is built on the exchange and processing of frames. + +Frames begin with a 4 octet header followed by a variable length +payload:: + + +-----------------------------------------------+ + | Length (24) | + +-----------+-----------------------------------+ + | Type (4) | + +-----------+ + | Flags (4) | + +===========+===================================================| + | Frame Payload (0...) ... + +---------------------------------------------------------------+ + +The length of the frame payload is expressed as an unsigned 24 bit +little endian integer. Values larger than 65535 MUST NOT be used unless +given permission by the server as part of the negotiated capabilities +during the handshake. The frame header is not part of the advertised +frame length. + +The 4-bit ``Type`` field denotes the type of message being sent. + +The 4-bit ``Flags`` field defines special, per-type attributes for +the frame. + +The sections below define the frame types and their behavior. + +Command Request (``0x01``) +-------------------------- + +This frame contains a request to run a command. + +The name of the command to run constitutes the entirety of the frame +payload. + +This frame type MUST ONLY be sent from clients to servers: it is illegal +for a server to send this frame to a client. + +The following flag values are defined for this type: + +0x01 + End of command data. When set, the client will not send any command + arguments or additional command data. When set, the command has been + fully issued and the server has the full context to process the command. + The next frame issued by the client is not part of this command. +0x02 + Command argument frames expected. When set, the client will send + *Command Argument* frames containing command argument data. +0x04 + Command data frames expected. When set, the client will send + *Command Data* frames containing a raw stream of data for this + command. + +The ``0x01`` flag is mutually exclusive with both the ``0x02`` and ``0x04`` +flags. + +Command Argument (``0x02``) +--------------------------- + +This frame contains a named argument for a command. + +The frame type MUST ONLY be sent from clients to servers: it is illegal +for a server to send this frame to a client. + +The payload consists of: + +* A 16-bit little endian integer denoting the length of the + argument name. +* A 16-bit little endian integer denoting the length of the + argument value. +* N bytes of ASCII data containing the argument name. +* N bytes of binary data containing the argument value. + +The payload MUST hold the entirety of the 32-bit header and the +argument name. The argument value MAY span multiple frames. If this +occurs, the appropriate frame flag should be set to indicate this. + +The following flag values are defined for this type: + +0x01 + Argument data continuation. When set, the data for this argument did + not fit in a single frame and the next frame will contain additional + argument data. + +0x02 + End of arguments data. When set, the client will not send any more + command arguments for the command this frame is associated with. + The next frame issued by the client will be command data or + belong to a separate request. + +Command Data (``0x03``) +----------------------- + +This frame contains raw data for a command. + +Most commands can be executed by specifying arguments. However, +arguments have an upper bound to their length. For commands that +accept data that is beyond this length or whose length isn't known +when the command is initially sent, they will need to stream +arbitrary data to the server. This frame type facilitates the sending +of this data. + +The payload of this frame type consists of a stream of raw data to be +consumed by the command handler on the server. The format of the data +is command specific. + +The following flag values are defined for this type: + +0x01 + Command data continuation. When set, the data for this command + continues into a subsequent frame. + +0x02 + End of data. When set, command data has been fully sent to the + server. The command has been fully issued and no new data for this + command will be sent. The next frame will belong to a new command. + +Issuing Commands +---------------- + +A client can request that a remote run a command by sending it +frames defining that command. This logical stream is composed of +1 ``Command Request`` frame, 0 or more ``Command Argument`` frames, +and 0 or more ``Command Data`` frames. + +Argument frames are the recommended mechanism for transferring fixed +sets of parameters to a command. Data frames are appropriate for +transferring variable data. A similar comparison would be to HTTP: +argument frames are headers and the message body is data frames. + +It is recommended for servers to delay the dispatch of a command +until all argument frames for that command have been received. Servers +MAY impose limits on the maximum argument size. +TODO define failure mechanism. + +Servers MAY dispatch to commands immediately once argument data +is available or delay until command data is received in full. + Capabilities ============