Patchwork [4,of,5,V3] help: document wire protocol "handshake" protocol

mail settings
Submitter Gregory Szorc
Date Aug. 23, 2016, 2:51 a.m.
Message ID <29ae08b47cfa31d52197.1471920670@ubuntu-vm-main>
Download mbox | patch
Permalink /patch/16387/
State Accepted
Headers show


Gregory Szorc - Aug. 23, 2016, 2:51 a.m.
# HG changeset patch
# User Gregory Szorc <>
# Date 1471920599 25200
#      Mon Aug 22 19:49:59 2016 -0700
# Node ID 29ae08b47cfa31d5219707240e8ac9ec8634aa9e
# Parent  98505b32869ea6121dfdd5a732d71fbd1548462d
help: document wire protocol "handshake" protocol

There isn't a formal handshake protocol in the wire protocol. But
clients almost certainly need to perform particular actions before they
can communicate with a server optimally. So document what that is
so people understand what's going on at connection establishment time.


diff --git a/mercurial/help/internals/wireprotocol.txt b/mercurial/help/internals/wireprotocol.txt
--- a/mercurial/help/internals/wireprotocol.txt
+++ b/mercurial/help/internals/wireprotocol.txt
@@ -363,8 +363,55 @@  Whether the server supports pushing via 
 This capability/command has been present since Mercurial 0.9.1 (released
 July 2006).
 Mercurial 0.9.2 (released December 2006) added values to the capability
 indicating which bundle types the server supports receiving. This value is a
 comma-delimited list. e.g. ``HG10GZ,HG10BZ,HG10UN``. The order of values
 reflects the priority/preference of that type, where the first value is the
 most preferred type.
+Handshake Protocol
+While not explicitly required, it is common for clients to perform a
+*handshake* when connecting to a server. The handshake accomplishes 2 things:
+* Obtaining capabilities and other server features
+* Flushing extra server output (e.g. SSH servers may print extra text
+  when connecting that may confuse the wire protocol)
+This isn't a traditional *handshake* as far as network protocols go because
+there is no persistent state as a result of the handshake: the handshake is
+simply the issuing of commands and commands are stateless.
+The canonical clients perform a capabilities lookup at connection establishment
+time. This is because clients must assume a server only supports the features
+of the original Mercurial server implementation until proven otherwise (from
+advertised capabilities). Nearly every server running today supports features
+that weren't present in the original Mercurial server implementation. Rather
+than wait for a client to perform functionality that needs to consult
+capabilities, it issues the lookup at connection start to avoid any delay later.
+For HTTP servers, the client sends a ``capabilities`` command request as
+soon as the connection is established. The server responds with a capabilities
+string, which the client parses.
+For SSH servers, the client sends the ``hello`` command (no arguments)
+and a ``between`` command with the ``pairs`` argument having the value
+The ``between`` command has been supported since the original Mercurial
+server. Requesting the empty range will return a ``\n`` string response,
+which will be encoded as ``1\n\n`` (value length of ``1`` followed by a newline
+followed by the value, which happens to  be a newline).
+The ``hello`` command was later introduced. Servers supporting it will issue
+a response to that command before sending the ``1\n\n`` response to the
+``between`` command. Servers not supporting ``hello`` will send an empty
+response (``0\n``).
+In addition to the expected output from the ``hello`` and ``between`` commands,
+servers may also send other output, such as *message of the day (MOTD)*
+announcements. Clients assume servers will send this output before the
+Mercurial server replies to the client-issued commands. So any server output
+not conforming to the expected command responses is assumed to be not related
+to Mercurial and can be ignored.