RFC: Command server protocol

Martin Geisler mg at aragost.com
Wed Jun 15 07:01:54 CDT 2011

Idan Kamara <idankk86 at gmail.com> writes:

> Here's an overview of the current protocol used by the command server
> (also available here http://mercurial.selenic.com/wiki/CommandServer).
> Feedback is appreciated.

I'm happy to see all the good progress on this topic!

> All communication with the server is done on stdin/stdout. The byte
> order used by the server is big-endian. Data sent from the server is
> channel based, meaning a (channel [character], length [unsigned int])
> pair is sent before the actual data. For example:
> o
> 1234
> <data: 1234 bytes>
> that is 1234 bytes sent on channel 'o', with the data following.

Could we please use full words for the channels? I think it makes it
much easier to remember what's going on if we talk about the 'result'
channel instead of the 'r' channel (and there might be new channels in
the feature that naturally would start with 'r').

One could even consider sending all responses in a standard format, such
as RFC 822 email headers:

  Channel: stdout\r\n
  Length: 1234\r\n
  <data: 1234 bytes>

My hope is that this will make it easier to implement clients since
people can use their favority library for parsing email-like headers.

> Encoding
> -------------
> Strings are encoded in the local encoding.

Uhh, that seems like a bad idea since there can be many things that
cannot be encoded in that encoding. Since we are defining a new
protocol, I think we should take the chance to specify that all strings
must be UTF-8 encoded. On the server-side, you will call tolocal on the
incoming strings to cache the UTF-8 encoding.

(It is of course not all strings that are encoded in this encoding: the
result of a 'hg cat' command is raw binary data.)

> Capabilities
> -----------------
> The server is running on an endless loop (until stdin is closed) waiting for
> commands. A command request looks like this:
> commandname\n
> <command specific request>
> * runcommand - Run the command specified by a list of \0-terminated strings.
> An unsigned int indicating the length of the arguments should be sent before
> the list. Example:
> runcommand\n
> 8
> log\0
> -l\0
> 5

With my idea of using headers above, a request could look like

  Command: runcommand\r\n
  Length: 8\r\n

Martin Geisler

aragost Trifork
Professional Mercurial support

More information about the Mercurial-devel mailing list