Subject: [hybi] websocket baseline counterproposal

From: Scott Ferguson <[email-masked]>
Date: Mon, 10 May 2010 18:01:18 -0700

I've written up a websocket baseline counterproposal draft that 
satisfies the requirements of draft-loreto-hybi-requirements, including 
the binary requirements and HTTP-compatibility at

http://hessian.caucho.com/websockets/draft-ferg-hybi-websockets-latest.html

If there is sufficient interest, I can submit it as a formal draft.

The proposal has the following features:

  1. allows binary frames following the Thompson/Wilkins model, but 
encodes variable length bytes, so the frame length can be 32-bit (or 
64-bit), while minimizing overhead for small messages. (frame header 
parsing is still trivial.)

  2. supports control frames allowing for graceful close, keepalives, 
(and enabling a multiplexing extension if desired.)

  3. supports the keepalive capabilities discussed in this list. The 
specific proposal is the "ping" request/response. (Although I like the 
asymmetrical heartbeat, it would be more complicated because of the 
dynamic negotation, and I felt it was best to keep things simple.)

  4. the handshake is HTTP compatible, basically a simplification to the 
actual HTTP usage in practice.

  5. allows client pipelining to reduce RTT (although there hasn't been 
enough discussion in this list, so I'd imagine it would change.)

  6. example multiplexing extension (not technically part of the 
proposal, but I wanted to show how it might fit in, and it's come up 
frequently as an idea we should at least explore.)

  7. written in a more conventional spec format to make it easier to 
discuss and evaluate the protocol.

  8. continues to support the JavaScript API without modification

  9. drops the *-Key1 and *-Key2 from -76 because they're silly and 
don't add value. If we want a nonce and signature, we can add a nonce 
and signature.  I've marked where those would go.

Share and Enjoy!

-- Scott

---

From: Greg Wilkins <[email-masked]>
Date: Tue, 11 May 2010 10:23:48 +0200

Scott,

I welcome this alternate proposal.  Great Work!

I think it is very valuable to always consider alternatives, even
if just as a thought exercise, to ensure that ones mind is not
getting tunnel vision towards one particular solution.

Some feedback on your proposal.

I do think the form/style of the document is good and much more
conventional, but it would benefit from some examples in the
introduction.  (Note also that the current  hixie draft
document is also very much improved in readability terms - although
badly redundant in not presenting framing as symmetric).

I don't like the option to send an init frame immediately after
the request handshake (for the same reasons I've gone into before).
It would be OK if it was marked at content in the request.  However,
I think it would be better still if it was the server that sent
the first init frame after the 101 and the client can then respond
with it's own plus application frames.

I think that it is generally agreed that we should at least
have a nonce and a response based on it, so it would be
good to see that expanded in your spec.

It would also be good to have a version in the handshake.

The framing is good (mostly because there is only one
framing mechanism) - although still a little over complex
with the variable length length encoding.  If we are to
have variable length lengths, then I actually prefer the
hixie encoding and that frees up 4 bits in the code for
future use (see some ideas below).

I'd like to see one of the bits in the code dedicated to
transport encoding.  If the bit is set a transport encoding
would apply to the data, if not-set the data is not encoded.
If no websocket-transport-encoding headers have been exchanged,
then the transport encoding will be gzip.

It's not clear to me how binary and/or text data are
differentiated.      Perhaps the spec could just assume
all data frames are text/plain;charset=utf-8
unless a  websocket-content-type header has been sent to
say otherwise (with inbound and outbound allowed to have
different content types).

Close should differentiate between graceful close
and error close (where an error close is different to
the network just breaking).

I like the negotiate header op code.   Although I'm not
sure that "negotiate" is the right name (and will scare
some people off it!).   Many headers are declarative
(eg websocket-content-type) and only some are part
of negotiations.

The multiplexing extension is good, but lacks flow control.
This could be added with a simple Channel-Window-Size
op code, that tells the other end the number of bytes
that can be sent on a channel before another window-size
message is received.

You also need to be clear what the original channel
is (channel zero) and that negotiate-headers only apply
to the current channel (I assume).

Note that while this may seam a lot different to the
current draft - I really don't see that they are that
far apart.    In summary I think the main differences
are:

  + a single framing mechanism that works for
    both text and binary.

  + Fragmentation

  + A control frame mechanism with an op code, which
    allows simple addition of features such as
    noops, keep alives, graceful closes, headers,
    multi-plexing etc etc.

Of these features - I can't believe that
the we are already converging on the first
two (once binary is added to websockets I can't
see that sentinel framing will remain and we appear
to have some consensus that fragmentation is needed).

So it is the last of these features that I
think is most important.   The current hixie
draft has added special frames (0xff00) for
graceful close.   But that is not a general
control frame mechanism and is not going to
be able to be extended for other features (required
or as extensions).

I would like to see this specification submitted
as an alternative.   Specially as we will hopefully
be refining and finalizing the requirements over the
next few weeks - it would be good to see alternate
solutions.      So even if we end up just harvesting
ideas from it - it will be a valuable contribution.

cheer

Scott Ferguson wrote:
>  9. drops the *-Key1 and *-Key2 from -76 because they're silly and don't
> add value. If we want a nonce and signature, we can add a nonce and
> signature.  I've marked where those would go.
> 
> Share and Enjoy!
> 
> -- Scott
> 
> _______________________________________________
> hybi mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/hybi

---

From: Jamie Lokier <[email-masked]>
Date: Tue, 11 May 2010 10:22:38 +0100

> dynamic negotation, and I felt it was best to keep things simple.)

Note that for some applications (which I've discussed), a "ping"
method with timeouts fixed in the specification simply does not work.

So I'd want a way to disable it from the Javascript API, and the
application would perform its own keepalive method.

-- Jamie

---

From: Scott Ferguson <[email-masked]>
Date: Tue, 11 May 2010 09:23:23 -0700

> getting tunnel vision towards one particular solution.
thanks!
> badly redundant in not presenting framing as symmetric).
Good point. I did write the intro very quickly (and last after getting 
the rest working.)
> with it's own plus application frames.
Yes.

That's the RTT issue. Since it's currently under discussion and I 
haven't seen a good, complete solution yet (although Jamie has good 
starting ideas), I figured it was better to use a simple pipeline model 
for the draft, rather than try to make something up.
> good to see that expanded in your spec.
Ok. I can make that change. I'm still not certain how valuable that is: 
it looks more like pretending to do security stuff rather than solving 
an actual security problem.
> It would also be good to have a version in the handshake.
True. I assume you're thinking something like:

  "Upgrade: WebSocket/1.0"
> future use (see some ideas below).
Yep, but since there wasn't a consensus on the length encoding, I 
decided to try a new one to see if there was any additional support.  A 
fixed 30-bit length with the two control bits would be fine, too (or 29/3).

The idea behind the draft encoding was:

  1. since the meta-length is in the first byte, it's easy to quickly 
detect overflow at an obvious place in the implementation. With the 
hixie encoding, the overflow detection is less obvious.

  2. there are 2 free bits if we have need of it.

  3. advantage of variable length is for short messages like pings, 
which only need 3 bytes. But since a 30-bit length would only require 5 
bytes, the variable length is probably overkill.

  4. large messages that knew their length could use something like 
sendfile() without forcing buffering. (although 30-bit or 29-bit fixed 
may be fine even for those applications.)
> then the transport encoding will be gzip.
That's an interesting idea. I like it.
> different content types).
Well, that goes to the heart of the sub-protocol issue. Any application 
or sub-protocol will have additional requirements beyond the 
binary/utf-8 issue. For example, a JSON payload is encoded as 
JSON/UTF-8, and an XML payload is encoded as XML/UTF-8. Those 
sub-protocols are the real negotiated issues. The UTF-8 is a requirement 
on those protocols, not on the WebSocket headers itself.

Because text encodings must be UTF-8, I didn't see any value in adding 
handshake headers to negotiate the encoding: it's a non-negotiable issue.
> the network just breaking).
Ok. Do you think the error close should have a text message?
> (eg websocket-content-type) and only some are part
Yep. I didn't know what to call it, and currently there's no use of that 
opcode in the draft, so I left it. It could just be "HEADER".
> to the current channel (I assume).
Right. I didn't actually want to create a full multiplexing protocol 
within the draft, just to show that it could be done. If I have time, I 
can split one into a separate draft this weekend.
>     noops, keep alives, graceful closes, headers,
Yep. This wasn't meant to be radically different (except the style change).

Technically, the additional difference is that the HTTP portion is a 
strict sub-grammar of HTTP/1.1, while the -76 draft is something else 
entirely.

-- Scott

---

From: Scott Ferguson <[email-masked]>
Date: Tue, 11 May 2010 09:26:56 -0700

> application would perform its own keepalive method.
Right. I'd assume the default would be no keepalive timeout, and the 
spec itself would not require any keepalive period.

I wasn't exactly sure how the final keepalive discussion ended up, 
particularly given the mobile issues. It looked like a client-initiated 
ping was the leading idea, although I liked the asymmetrical heartbeat.

-- Scott

---

From: "Martin J. Dürst" <[email-masked]>
Date: Wed, 12 May 2010 17:06:35 +0900

> If there is sufficient interest, I can submit it as a formal draft.

I very much suggest you do so. In general, the IETF works by submitting 
drafts, then looking at them and discussing them, not the other way round.

Regards,    Martin.

-- 
#-# Martin J. Dürst, Professor, Aoyama Gakuin University
#-# http://www.sw.it.aoyama.ac.jp   mailto:[email-masked]