Subject: Re: [hybi] header for negotiating extensions

From: John Tamplin <[email-masked]>
Date: Sun, 23 Jan 2011 14:22:22 -0500

I brought this up before and there seemed to be general agreement, but
it never made its way into the draft, so I thought I would write up a
proposal of how the discussion ended up for defining the extension
header and parameters.

- In section 4.7, add a reference to section 8 to the sentence talking
about negotiating extensions during the handshake.

- In section 5.1, step #44, add an entry:

-> If the entry's name is "sec-websocket-extension":
Parse the value of the field as described in section 8.1 into a list
of extension tokens and a possibly empty set of parameters for each.
If any extension token was received which was not advertised by this
client during this handshake, the client MUST fail the connection and
abort these steps.  Otherwise, process the accepted extensions and
their parameters as defined for each extension.

- In section 5.2.1, add an entry:

|Sec-WebSocket-Extension|
The value is a list of extensions offered by the client, with a
possibly empty set of parameters for each (see 8.1).

- In section 5.2.2, step #11, add:

|Sec-WebSocket-Extension|
The value is a list of accepted extensions and parameters for each
which the server understands and is willing to use on this connection
(see 8.1).  Extensions not listed by the client MUST NOT be included.
Note that the parameters do not have to be the same as sent by the
client; their meaning and how the returned value should be calculated
is defined by each extension.

- Renumber the existing section 8 to 8.2, and add section 8
"Extensions".   The intro for section 8 is:

WebSocket clients MAY request extensions to this specification,
and WebSocket servers MAY accept some or all extensions
requested by the client.  A server MUST NOT respond with any
extension not requested by the client, and any extension
parameters sent from the server MUST be chosen in accordance
with the specification defining that extension.

- Add section 8.1 "Sec-WebSocket-Extension Header"

A client requests extensions by including a "Sec-WebSocket-Extension"
header, which follows the normal rules for HTTP headers (see RFC2616
section 4.2) and the value of the header is defined by the following BNF:

extension-list = 1#extension
extension = extension-token *( ";" extension-param )
extension-token = registered-token | private-use-token
registered-token = token
private-use-token = "x-" token
extension-param = token [ "=" ( token | quoted-string ) ]

Note that like other HTTP headers, this header may be split or
combined across multiple lines.

That is,

  Sec-WebSocket-Extension: foo
  Sec-WebSocket-Extension: bar; baz=2

is exactly equivalent to

  Sec-WebSocket-Extension: foo, bar; baz=2

Any extension-token used must either be a registered token
(registration TBD), or have a prefix of "x-" to indicate a private-use
token.  The parameters supplied with any given extension MUST be
defined for that extension.  Note that the client is only offering to
use any advertised extensions, and MUST NOT use them unless the server
accepts the extension.

Note that the order of extensions is not important - any interactions between
multiple extensions MUST be defined in the documents defining the
extensions.

Non-normative examples of acceptable extension headers:
- Sec-WebSocket-Extension: deflate-stream
- Sec-WebSocket-Extension: mux; max-channels=4; flow-control, deflate-stream
- Sec-WebSocket-Extension: x-private-extension

A server accepts one or more extensions by including a
Sec-WebSocket-Extension header containing one or more
extensions which were requested by the client.  For each such
extension, the parameters returned by the server (if any) are as
defined in the document specifying that extension (for example,
compressing before multiplexing or after).

--
John A. Tamplin
Software Engineer (GWT), Google

---

From: Greg Wilkins <[email-masked]>
Date: Mon, 24 Jan 2011 16:30:05 +1100

John,

I generally agree with all that you wrote except:

> multiple extensions MUST be defined in the documents defining the

I think the order of the extensions should be important,  at least to
the extent that extension lists should not be reordered.
I also think that any usage of the extension data space in each frame
should be done in the same order as the extensions are specified in
the list.

regards

---

From: John Tamplin <[email-masked]>
Date: Mon, 24 Jan 2011 00:42:51 -0500

> should be done in the same order as the extensions are specified in

I think that complicates implementations for no real value.  Also, I worry
about what splitting/merging multiple headers would do to the order.

In most cases, I think it will be clear which way the extensions should
compose together - for example, compression and multiplexing -- clearly
compression on the physical channel should be after multiplexing, and
compression (or lack thereof) should be negotiated separately on the logical
channels.

That said, I certainly wouldn't push hard for this if others thought
respecting the order in the header was better.

---

From: Greg Wilkins <[email-masked]>
Date: Mon, 24 Jan 2011 16:59:05 +1100

> about what splitting/merging multiple headers would do to the order.

RFC2616 4.2 makes it clear that multiple headers of the same name are
well ordered and more over that:

  "The order in which header fields with the same field-name are
    received is therefore significant to the interpretation of the
    combined field value, and thus a proxy MUST NOT change
    the order of these field values when a message is forwarded."

> compression (or lack thereof) should be negotiated separately on the logical

I suspect that a lot of extensions will only have a single obvious
order in which they can be applied.

But I can also imagine unrelated extensions that use the extension
data space, where ordering will be necessary to decode the extension
data.  Consider an extension that signs each frame (or adds a
checksum), and another that tags each frame with some tracing
information about the client (timestamps etc.).  Both extensions will
put data into the extension data fields. As we currently do have not
defined any structure within the extension data, it will be up to each
extension to consume the extension data that is relevant to them, thus
the ordering of these unrelated extensions will be important.

The alternative is to define now the structure of extension data, so
that each extension can find it's own data without knowledge of all
other extensions.

Even if you think this situation unlikely, HTTP headers of the same
name are already well ordered, so it should cost us nothing to keep
this even if it is never used.

> respecting the order in the header was better.

others??