Subject: [hybi] HTTP Upgrade - A Modest Proposal

From: David Endicott <[email-masked]>
Date: Thu, 31 Mar 2011 22:54:18 -0400

While I am not interested in disrupting or derailing the progress being made
on finalizing the Websocket specification, the recent discussions about the
initial HTTP Upgrade handshake leads me to offer up the following proposal
that I believe may resolve the situation.

I propose we drop the HTTP Upgrade element from the WebSocket specification
entirely.  I believe that the co-mingling of HTTP Upgrade with WebSocket is
a confusion of protocols and the two should be more firmly separated.

My justification is:

1. HTTP Upgrade request (and it's response) are properly part of a HTTP
exchange, not a WebSocket one.  The use of HTTP Upgrade as a mechanism to
support WebSockets via a HTTP server is a good and valid use of that HTTP
capability, but it is not unique or specific to WebSocket.   Further,
WebSocket protocol servers may not be part of a HTTP serving environment and
having it answer HTTP (however limited) could confuse client agents.

2. When WebSocket is provided as part of a HTTP server stack, having to
instantiate the WebSocket serving process (thread/handler/etc.) just to
resolve the handshake and determine if a WebSocket connection will actually
proceed is awkward, potentially expensive and possibly insecure.    The
responsibility to determine if the HTTP server will support a HTTP Upgrade
to any given protocol for a given URL is properly the responsibility of the
HTTP server, not WebSocket.   The HTTP server must be able, via the Upgrade
request to consider only (a) the URL and (b) the Upgrade protocol and decide
if it will support it.   If it will, then all further negotiation is the
responsibility of the protocol being upgraded to.

3. If a HTTP server decides that it will allow an HTTP Upgrade to WebSocket
on the requested URL, the HTTP server can restrict the WebSocket serving
process to the docroot of that URL, thereby maintaining consistency of the
HTTP server's URL structure and preventing the WebSocket server process from
affecting any other part of the filesystem as well as establishing a
relative filesystem context for the WebSocket serving process.   The
WebSocket server process should not be allowed to determine the validity,
accessibility, remapping, etc. of the requested URL.  That is the HTTP
server's responsibility.

4. When WebSocket is provided as a stand-alone process, using a HTTP Upgrade
as the handshake presents at least two problems.  (a) changing from
line-oriented I/O (in the HTTP handshake) to a byte-oriented I/O (for
WebSocket frames) is awkward and potentially error prone, and (b) any HTTP
client-agent can potentially make a request to a WebSocket server and get
back a HTTP response, this exposes the availability and capabilities of the
WebSocket server to a client-agent that is not actually a WebSocket client.
  Neither of these concerns is really all that severe, but it is something
to be aware of.

Specifically I propose that the HTTP Upgrade based handshake be removed from
the WebSocket specification and replaced with a Control frame handshake or
negotiation.    This would mean that all WebSocket communication is done in
websocket frames.   This simplifies the implementation and keeps each part
in its own protocol context.   It strengthens the error checking between
client-agents and the WebSocket server.  For example, if a HTTP client-agent
incorrectly makes a request of a stand-alone WebSocket server, the client's
HTTP request will fail as a WebSocket frame and the server can drop the
connection.  The WebSocket server can further be assured that any
establishing connection that can provide valid frames is a client-agent that
is likely a conforming implementation.

Personally I would prefer a negotiation control frame to be used as the
initial exchange.  It defines that capability setup is determined at
connection establishment but also allows the possibility of later
re-negotiation should the situation change.    Failing that, a simple
websocket based handshake would be fine.

A note could be included on the use of the HTTP Upgrade by HTTP servers as a
mechanism to bootstrap a WebSocket connection, but this is no different than
it's use to boot-strap any other protocol.   Separating the two would allow
the implementer to decide if and how they wish to deal the ramifications of
using that mechanism.

Again, let me reiterate that I have no interest in derailing this working
group, I have strong motivation to get a real
bidirectional asynchronous protocol into browser agents as soon as possible,
no matter how mangled the implementation.   I will take good over perfect,
and soon over good.

tl;dr: HTTP is HTTP, WebSocket is WebSocket, do not mix.  Leverage.

---

From: "Greg Longtin" <[email-masked]>
Date: Thu, 31 Mar 2011 23:07:19 -0500

David,

A few thoughts on your post (clipped) --

> 1. Further, WebSocket protocol servers may not be part of a HTTP serving
environment and having it answer HTTP (however limited) could confuse client
agents.

I'm not sure I understand the 'confuse client agents' concept.  If a client
agent includes the header 'Upgrade: websocket' in an HTTP request, it should
be expecting the response as defined in the spec.

resolve the handshake

I'm not sure why 'when A' implies 'B.'  Somewhere, the stack needs know what
will be considered valid 'Request-URI' and possibly 'Sec-WebSocket-Protocol'
information.  That is a concern of whomever administers the stack.

> 4 (a) changing from line-oriented I/O (in the HTTP handshake) to a
byte-oriented I/O (for WebSocket frames) is awkward and potentially error
prone

Considering WS servers will be designed for byte-oriented I/O, the
line-oriented I/O coding requirements are minimal, and not necessarily error
prone.

> 4 (b) any HTTP client-agent can potentially make a request to a WebSocket
server and get back a HTTP response, this exposes the availability and
capabilities of the WebSocket server

Without the correct Request-URI and possibly 'Sec-WebSocket-Protocol'
header, what can the client find out?  If the HTTP client request is
invalid, the spec states (somewhat vaguely) in Section 7.2.2. the following
'Certain algorithms require or recommend that the server _abort the
WebSocket connection_ during the opening handshake.'  Hence, 'get back a
HTTP response' may not occur with the client agent's request.

I think everyone is a little sensitive and spent from all the reading. 

Thanks,

Greg Longtin

---

From: Willy Tarreau <[email-masked]>
Date: Fri, 1 Apr 2011 07:21:50 +0200

> line-oriented I/O coding requirements are minimal, and not necessarily error

I would add that any HTTP server already deals with that. They accept
POST requests which are byte-oriented, they can send any file (eg: HTML,
GIF, etc...) which are byte-oriented too and browsers can correctly
retrieve these files. So in fact it's something which is already
implemented and works very well in every client and server.

> HTTP response' may not occur with the client agent's request.

There were discussions in the past about exposing some capabilities as
control frames, but that did not bring any major advantage, and that
required an additional round-trip before communication could start,
which is really not acceptable in some environments (eg: smartphones).

Willy