Subject: [hybi] WebSocket protocol as it stands

From: Ryan Worsley <[email-masked]>
Date: Sat, 30 Oct 2010 01:52:37 +0100

Hi,

I don't know much about these sorts of things, but figured it imperative
that I write an informative email in case someone else hadn't.

It would appear draft 76 of the WebSocket protocol does not conform to the
HTTP specification, details here:
http://blog.iworks.at/?/archives/69-WebSockets-Handshake-non-HTTP-conforming.html.

This shouldn't be too much of a problem, however I've already found it to be
precisely that.  I've attempted to implement an early WebSocket server using
ASP.NET MVC - trying to get ahead of the curve and all that - however I ran
into a snag.  Because there is a body with no content-length header set, the
asp.net webserver, in whatever flavour it comes, ignores the body and
doesn't pass it on to any higher level applications.  This means we can't
validate back to the client and no websocket can be built!

The question is I suppose, should Microsoft 'fix' their server or should
someone add a content-length header to the specification?

I await your thoughts with nothing less than baited breath (actually I
really want to implement this thing, so that's kind of true.)

Regards,

Ryan.

*The presence of a message-body in a request is signaled by the inclusion of
a Content-Length or Transfer-Encoding header field in the request's
message-headers. A message-body MUST NOT be included in a request if the
specification of the request method (section 5.1.1) does not allow sending
an entity-body in requests. A server SHOULD read and forward a message-body
on any request; if the request method does not include defined semantics for
an entity-body, then the message-body SHOULD be ignored when handling the
request.*

---

From: Willy Tarreau <[email-masked]>
Date: Sat, 30 Oct 2010 08:17:53 +0200

Hi,

> validate back to the client and no websocket can be built!

Yes, this is a known issue since draft 76. A workaround exists but a new
handshake is being worked on, so the workaround has not been documented to
avoid multiplicity of incompatible versions.

> someone add a content-length header to the specification?

neither :-)

The server-side WS code does not need the client's data ("key3") to emit
the headers. The fix simply consists in making sure the server emits the
headers as soon as it has read all request headers. This will unlock the
intermediary components (possibly including the web server) which will
know that after the 101 response, data must flow freely between both sides.
The "key3" part from the client will then be able to reach the server code,
which will be able to respond and the handshake correctly completes.

This workaround has already worked for several implementations. If you do
this and it works for you, please at least report it, because we're also
interested in being aware of compliant and non-compliant HTTP implementations.

Regards,
Willy

---

From: Ryan Worsley <[email-masked]>
Date: Sat, 30 Oct 2010 16:39:44 +0100

Hi Willy,

Thanks for your considered reply, I actually confirmed this behaviour by
using a Microsoft application called wfetch.  if I insert a content-length
header into the message the body gets through just fine.

I understand your approach to be to send the response headers immediately
and then attempting to read the message body as we're now in a different
mode.  Unfortunately this didn't work in IIS and I think I can explain why.

At the point at which my application runs, the incoming http message has
been processed and packaged into a data structure that is handed to it.  No
further processing can be done at this point on the inbound message.  I can
listen on the incoming stream for further data from the client, but the body
has already been sent and disregarded.

It might be possible in my case to hook in at a much lower level of the
request processing pipeline.  I'm not sure, so I've posted a request for
information on the IIS community forums.

Is there any chance that you'll include content-length in the next draft?
What is the ETA of your next draft?
Does this aforementioned behaviour make IIS compliant or non compliant?

Kind regards,

Ryan.

---

From: Willy Tarreau <[email-masked]>
Date: Sat, 30 Oct 2010 18:08:30 +0200

Hi Ryan,

> header into the message the body gets through just fine.

I'm not surprized.

> mode.

It's not a body, it's the beginning of the tunnelled data. The difference
is precisely that if it were a body, it would be covered by a content-length.
When I first reported this issue a few months ago, I was told that we don't
want to put a content-length because the goal was precisely to ensure that
only completely compliant intermediaries would let this pass through.

> Unfortunately this didn't work in IIS and I think I can explain why.
> 

But if you use this data as the incoming stream, are you able to read it ?
I certainly agree that you can't get it as a body since it's not advertised
as such.

> Is there any chance that you'll include content-length in the next draft?

Apparently no due to the explanation above. Also, it's possible that a
next draft will rely again on a completely different handshake.

> What is the ETA of your next draft?

I have no idea.

> Does this aforementioned behaviour make IIS compliant or non compliant?

If IIS does not pass you those 8 bytes as a body, then it's right not to
do so. However, once you respond the 101 and the headers, it should let
the data flow between both sides, resulting in the pending 8 bytes to
reach your application. If you can't get those bytes, it would be nice
to find out why.

Regards,
Willy