<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Philipp Serafin wrote:
<blockquote
cite="mid:f042876c0807221023g58e5f36atb936924e334ffaac@mail.gmail.com"
type="cite"><br>
<blockquote type="cite">
<pre wrap="">Asynchronous: Requests and responses can be pipelined, meaning requests and
responses can be transmitted simultaneously and are queued.
</pre>
</blockquote>
<pre wrap=""><!---->
I think the problem is that this definition of "asynchronous" is very
narrow. Yes, you don't need to wait for a request to finish before you
issue a new one. But you'd still be bound to HTTP's request/response
scheme in general.
</pre>
</blockquote>
<br>
WebSockets uses HTTP so it is hardly
immune to the request/response behaviour of its underlying protocol
(including the stream nature of TCP).<br>
<br>
Besides this statement appears to be based on the assumption that the
server MUST wait for additional client requests to send each "message".
However the specification allows the server to send "chunked" or
"multipart" data in a variety of ways so full asynchronous
communication is acheivable by making the response chunks part of one
long HTTP multipart response and allowing the javascript API to access
the incoming data while the response is incomplete. It can be
simplified for the end-user by allowing the raw server response to be
read by bytes, lines or "parts". If you need more channels (ie, to pass
messages while sending a large file) then you simply open more
WebSockets and let the server handle multiplexing via cookies or
message ids.<br>
<br>
<blockquote
cite="mid:f042876c0807221023g58e5f36atb936924e334ffaac@mail.gmail.com"
type="cite">
<pre wrap="">However, web authors might want to employ other schemes as well, for
example server-sided asynchronous notifications ("pushing"),
</pre>
</blockquote>
<br>
Client opens a connection. handshakes, then leaves connection open
listening for "pushed" parts in the response stream. <br>
<br>
<blockquote
cite="mid:f042876c0807221023g58e5f36atb936924e334ffaac@mail.gmail.com"
type="cite">
<pre wrap="">client-sided notifications that don't need to be replied</pre>
</blockquote>
<br>
HTTP has a status code specifically for this purpose.<br>
<br>
<blockquote
cite="mid:f042876c0807221023g58e5f36atb936924e334ffaac@mail.gmail.com"
type="cite">
<pre wrap=""> or requests that can be answered out-of-order.</pre>
</blockquote>
<br>
The order of data is controlled by the order it is sent by the
application. There is no requirement for the requests and
responses/parts to be synchronised. Especially if the server responses
consist of a single multi-part "response".<br>
<br>
<br>
<br>
I'm not advocating against WebSockets, just its current definition. In
particular it tries to solve things that HTTP/1.1 already handles. I
believe we should be thinking of WebSockets as a Javascript API, not a
new communications protocol for the simple reason that HTTP is already
a very suitable and widely deployed protocol. What authors (especially
AJAX authors) are missing is a reliable way to use HTTP's existing
asynchronous connection support.<br>
<br>
Here are my issues with WebSockets as currently defined:<br>
<br>
1.) Request must have a <scheme> component whose value is either
"ws" or "wss"<br>
<br>
The "scheme" should be HTTP(S). WebSockets should be the API. <br>
<br>
2.) The message event is fired when when data is received for a
connection. <br>
<br>
What "data"? A byte, a line, a chunk, the whole response? The spec
isn't clear. I'd also recommend adding a
connection.read( max_bytes ) method as used by Python and most
languages to let the author receive bytes at a frequency appropriate to
the application (eg, a game might want to frequently poll for small
updates). <br>
<br>
3.) If the resulting absolute URL has a <port> component, then
let port be that component's value; otherwise, if secure is false, let
port be 81, otherwise let port be 815. <br>
<br>
No, no, no! Don't let paranoia override common sense. Not all websocket
applications will have the luxury to run on these ports (multiple web
servers, shared host, tunnelled connections, 2 websocket apps on one
host, etc...).<br>
<br>
4.) The whole handshake is too complex.<br>
<br>
There are many firewalls, proxies and servers that legimately insert,
change, split, or remove HTTP headers or modify their order. This is
also likely if the service being provided sits on top of a
framework/server (such as Coldfusion/IIS). Also what happens if
HTTP/1.2 is sent? These will break the WebSocket handshake as currently
defined. <br>
<br>
rfc 2616 section 3 says: The version of an HTTP message is indicated by
an HTTP-Version field in the first line of the message.<br>
HTTP-Version = "HTTP" "/" 1*DIGIT "." 1*DIGIT<br>
<br>
How many non-http servers send this? Probably none. I recommend the
handshake simply read about 256 bytes of the server response and check
that it contains a valid HTTP version field and one or more valid HTTP
headers and optional end-of-headers marker. If ALL headers semantically
validate (ie, with the regex [A-Za-z-]: \s(.*?)\r\n) then it is
reasonably safe to assume it is a real HTTP or WebSockets service. If
the headers validate
then the client repeats the process until the message body is reached.
At this
point we check our collected headers for at least one "Accept" header
containing "WebSocket" (assuming that being a "WebSocket" rather than a
basic pipelined HTTP connection is even useful).<br>
<br>
5.) URI parsing specification<br>
<br>
The current proposal spells out the URI/path parsing scheme. However
this should be treated EXACTLY like HTTP so the need to define it in
the spec is redundant. It is enough to say that the resource may be
requested using a GET or POST request. Same with cookie handling,
authorization and other HTTP headers. These should be handled by the
webserver and/or application exactly as normal, there is no need to
rewrite the rules simply because the information flow is asynchronous.<br>
<br>
6.) Data framing specification<br>
<br>
Redundant because HTTP already provides multiple methods of data
segment encapsulation including "Content-Length", "Transfer-Encoding"
and "Content-Type". Each of these have sub-types suitable for a range
of possible WebSocket applications. Naturally it is not necessary for
the client or server to support them all since there are HTTP headers
explicitly designed for this kind of negotiation. The WebSocket should
however define at least one fallback method that can be relied on (I
recommend "Content-Length", "Transfer-Encoding: chunked" and
"Content-Type: multipart/form-data" as MUST requirements).<br>
<br>
7.) WebSockets needs a low-level interface as well<br>
<br>
By "dumbing down" the data transfer into fired events and wrapping the
data segments internally the websocket hides the true communication
behind an abstract object. This is a good thing for simplicity but
extremely limiting for authors wanting to fine-tune an application or
adapt to future protocols. I strongly recommend that rawwrite() and
rawread() methods be made available to an OPEN (ie,
authenticated/handshaked) websocket to allow direct handling of the
stream. It would be understood that authors using these methods must
understand the nature of both HTTP and websockets. In the same way a
settimeout() method should be provided to control blocking/non-blocking
behaviour. I can't stress enough how important these interfaces are, as
they may one day be required to implement WebSockets 2.0 on "legacy" or
broken HTML5 browsers.<br>
<br>
8.) Origin: / WebSocket-Origin:<br>
<br>
Specifying clients allowed to originate a connection is a disaster
waiting to happen for the simple reason that sending your origin is a
privacy violation in the same vain as the referrer field. Any
open-source browser or privacy plugin will simply disable or spoof this
since it would allow advertising networks to track people by ad-serving
via websockets. Such tracking undermines the security of anonymising
proxies (as the "origin" may be a private site or contain a client id).
Using origin as a required field essentially makes the use of
"referrer" mandatory. If a websocket wants to restrict access then it
will have to use credentials or IP ranges like everything else.<br>
<br>
9.) WebSocket-Location<br>
<br>
The scenario this is supposed to solve (that an application makes a
mistake about what host it's on and somehow sends the wrong data) is
contrived. What's more likely to happen is that a server application
has trouble actually knowing its (virtual) hostname (due to a proxy,
mod_rewrite, URL masking or other legitimate redirect) and therefore NO
clients can connect. It isn't uncommon for the host value passed to a
CGI script and the hostname returned by the environment (ie, via uname
or OS library) to conflict. Then there is the matter of an SSL
connection (no host header available). I'm having trouble determining
why this should even matter. I suspect most simple
applications/wrappers will just echo back the host header sent by the
client so if a mistake is made it's likely to go unnoticed anyway.<br>
<br>
10.) To close the Web Socket connection, either the user agent or the
server closes the TCP/IP connection. There is no closing handshake.<br>
<br>
HTTP provides a reliable way of closing a connection so that all
parties (client, server and proxies) know why the connection ended.
There is no reason for websockets to not follow this protocol and close
the connection properly.<br>
<br>
<br>
In conclusion, the current specification of WebSockets re-invents
several wheels and does so in ways that are overly complex, error-prone
and yet seriously limited in functionality. The whole concept needs to
be approached from the position of making HTTP's features (which are
already implemented in most UAs) available to Javascript (while
preventing the exploit of non-HTTP services). I do not believe this is
difficult if my recommendations above are followed. I do not wish to be
overly critical without contributing a solution, so if there are no
serious objections to the points I've made I will put time into
reframing my objections as a compete specification proposal.<br>
<br>
<br>
Shannon<br>
<br>
<br>
</body>
</html>