

Websocket gets an update - the details. - axod
http://axod.blogspot.com/2010/06/websocket-gets-update-and-it-breaks.html

======
mcav
It's as I feared: What was previously a nearly-compatible-with-HTTP, dead-
simple protocol, looks to have become confusingly, unnecessarily complex. Like
XMPP.

It will catch on because _it's all we've got_ , but we're going to shove yet
another mediocre protocol onto the stack of protocols servers need to speak in
addition to HTTP.

The people working on this have spent time understanding the problem domain
better than I have. But I really hope they've thought this protocol through.
Because we'll be stuck with it for a _long time_.

~~~
wvenable
A lot of bad protocols exist because people didn't think it through enough and
a lot of bad protocols exist because people thought it through too much.

The protocol is a bit more readable here: [http://tools.ietf.org/html/draft-
hixie-thewebsocketprotocol-...](http://tools.ietf.org/html/draft-hixie-
thewebsocketprotocol-76)

The security protocol does seem a little strange: putting numbers into the
fields interspersed with random characters and spaces, taking the numbers and
dividing them by the number of space characters, and using _2_ fields to make
harder. There's a lot of dancing here to ensure that the protocol is
implemented correctly.

------
prodigal_erik
What was wrong with requiring a "101 Switching Protocols" response to an
"Upgrade" request? Forcing the server to run four full rounds of MD5 just to
demonstrate that it actually implements a protocol is absurd. And reordering
fields to prove the server is indifferent to ordering belongs in an
integration test for the server, not a real client.

When the Internet works, it's thanks to Postel's Law, which is the polar
opposite of designing a protocol to maximize the likelihood of failure.

~~~
wmf
Postel's Law works when everyone follows it, but it's unstable. At some point
somebody will be liberal in what he sends and conservative in what he accepts
and everyone else will end up working around his bugs forever. This can even
lead to a ratcheting effect over time as people use less and less of the
protocol to avoid previous bugs.

This leads us to Ruby's Corollary[1]: Be exact in what you send and liberal in
what you accept. Since programmers will neither read the spec nor run the test
suite, you should build real implementations that exercise every facet of the
spec (e.g. randomize anything that doesn't matter). The only way to
interoperate with such implementations is to do things more or less correctly.

[1] After Sam Ruby, who inserts test cases into his blog to encourage browsers
and feed readers to work better.

~~~
prodigal_erik
His end users deserve better. He's wilfully confronting them with interop
failures they aren't in a position to understand, much less do anything about.
Testing is a burden which should be borne by developers.

~~~
wmf
This kind of interop error should be seen and fixed in the earliest
development and should never reach users; that's the point of deliberately
triggering it.

------
dedward
Seems a little harsh, - it's written somewhat badly, but the comments about
endianness are important - sure, a randomly generated 64-bit integer encoded
as big-endian is, entropically speaking, no more useful than it's little-
endian brother. It's also useless all by itself. As part of a system though,
like a challenge/response system, it's important both ends of the system know
how to interpret the data they are dealing with - so this is important.

At that point, defining the fact that you are sending a big-endian 64-bit
integer It might seem trivial now that we write everything in Java, but
endianness caused _all kinds_ of portability problems in the early internet
days when we started making different systems talk to each other, and made
simple porting jobs difficult. It's how we ended up with network-byte-order
instead of just using long ints and stuff like that - it's very easy to
overlook.

In short, being specific about data formats matters.

And yeah, it would suck if they over-complicate things - let's not let that
happen - we need simple protocols, but not too simple. It's okay if you can
slightly abuse them if it means fast adoption (One can coax HTTP servers to
sign into IRC and spam channels - but it's not a big enough problem to warrant
redesigning the whole thing, right?)

~~~
axod
> " it's important both ends of the system know how to interpret the data they
> are dealing with - so this is important."

As I say, it's treated, by both sides, as 8 bytes of random data. Never as
integers. The endianness here is irrelevant. The spec is going into _way_ more
detail than it needs.

------
sjs
When it goes over the network it has to be big-endian so both sides agree on
the value. That's why we call it "network order".

If the value is random and you send the low byte first and then treat that as
the high byte it would work. I can't imagine that ever being useful, but it
works as long as both sides agree that that [FE, ED, FA, CE] is 0xFEEDFACE.

If your RNG gives you 0xFEEDFACE you better not send it out as [CE, FA, ED,
FE] or you're going to make a mess of things. Host byte order is completely
irrelevant.

~~~
axod
The endianness here is irrelevant. It's 8 bytes of random data.

My point was, that generating a random 64bit integer and storing it as little
endian, would infact work fine. Because the 8 bytes of random data is only
used in the context of "8 bytes of random data", and never as "an integer" by
both sides.

The spec is just ridiculously _overly_ specific. It's telling us how you can
generate 8 bytes of random data. Any programmer implementing it should have a
vague idea how to do that.

~~~
sjs
I completely understand your frustration with the over-specification. Why
would they send it over the wire if it was never meant to be used though?
Surely the other side is interpreting these bytes somehow and excepts them in
a certain order.

[ a bit later ... ]

I decided to check the spec and see for myself what's going on. The part
you're talking about, key3, is in fact used later. The bytes may be random but
both sides need to know which of the 8 bytes comes first and which comes last.

    
    
        Let /challenge/ be the concatenation of /number_1/, expressed as
        a big-endian 32 bit integer, /number_2/, expressed as a big-
        endian 32 bit integer, and the eight bytes of /key_3/ in the
        order they were sent on the wire.
    

If the other side doesn't agree on the order of the bytes in key3 then things
are not going to work. Your other complaints may be valid but sometimes this
sort of over-specification helps implementers.

------
mike-cardwell
I'm not sure if it matters that the protocol is complex. A few people will
write libraries which expose a simple interface, so the vast majority of
people developing with WebSockets wont have to worry about this stuff.

What _really_ matters, is that the protocol is secure, efficient and
extensible. If it needs to be more complex in order to meet those criteria,
then fine...

------
tophercyll
I actually spent some time reading that spec yesterday while hunting a bug. I
was trying to figure out if maybe we were violating the protocol in some way.

I'm not enough of an expert to weigh in, but the spec did make me chuckle.
Super verbose with a dash of paranoia.

This is pretty funny (although gregw has written many longer and more detailed
essays about websockets as well):

<https://bugs.eclipse.org/bugs/show_bug.cgi?id=294563>

In the end, we located the bug within our code connecting jetty's websocket
support to our message passing system. You can bet that was an adventure to
sort out. =)

------
petercooper
_Why couldn't the spec just include the 'meat'. It's a simple protocol which
can be summed up in a page or two. The current spec runs to 55 pages!_

Be glad you don't study law! It's practically written in a different language
to everyday, pragmatic English. Specs and math papers can descend to similar
levels of readability, though RFCs, on the whole, tend to (in comparison) be
quite readable IMHO.

------
sjs
After browsing through the spec a little I can't take axod's claims seriously.
He's way off the mark saying that endianness of values sent over the network
doesn't matter. The fact that they are random bytes is irrelevant, they have
meaning even if they are generated randomly.

If you don't understand the point of sending values over the wire in a known
order then I'm sorry but I don't trust your ability to properly evaluate the
rest of the spec either.

axod: I don't mean this as a personal attack but considering your strong
opinions on this I'd expect you to have thought about it more diligently.

