Re: [hybi] #1: HTTP Compliance

Jamie Lokier <jamie@shareable.org> Wed, 19 May 2010 01:32 UTC

Return-Path: <jamie@shareable.org>
X-Original-To: hybi@core3.amsl.com
Delivered-To: hybi@core3.amsl.com
Received: from localhost (localhost [127.0.0.1]) by core3.amsl.com (Postfix) with ESMTP id 7A9F83A68E3 for <hybi@core3.amsl.com>; Tue, 18 May 2010 18:32:52 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -0.934
X-Spam-Level:
X-Spam-Status: No, score=-0.934 tagged_above=-999 required=5 tests=[AWL=-0.935, BAYES_50=0.001]
Received: from mail.ietf.org ([64.170.98.32]) by localhost (core3.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id M-JRqB1+e6mt for <hybi@core3.amsl.com>; Tue, 18 May 2010 18:32:51 -0700 (PDT)
Received: from mail2.shareable.org (mail2.shareable.org [80.68.89.115]) by core3.amsl.com (Postfix) with ESMTP id D1B753A6852 for <hybi@ietf.org>; Tue, 18 May 2010 18:32:50 -0700 (PDT)
Received: from jamie by mail2.shareable.org with local (Exim 4.63) (envelope-from <jamie@shareable.org>) id 1OEY9G-0002UD-W7; Wed, 19 May 2010 02:32:39 +0100
Date: Wed, 19 May 2010 02:32:38 +0100
From: Jamie Lokier <jamie@shareable.org>
To: Ian Hickson <ian@hixie.ch>
Message-ID: <20100519013238.GB2318@shareable.org>
References: <4BF11920.2080307@webtide.com> <Pine.LNX.4.64.1005171039050.25609@ps20323.dreamhostps.com> <4BF12FF1.2020101@webtide.com> <15307.1274106895.116423@Sputnik> <Pine.LNX.4.64.1005172259030.22838@ps20323.dreamhostps.com> <20100518003753.GP20356@shareable.org> <Pine.LNX.4.64.1005180229430.22838@ps20323.dreamhostps.com> <20100518121245.GR20356@shareable.org> <AANLkTiniCjBwm5T59as8jByM5xDhPMrea-GqZFpWPAVS@mail.gmail.com> <Pine.LNX.4.64.1005182105360.22838@ps20323.dreamhostps.com>
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Disposition: inline
In-Reply-To: <Pine.LNX.4.64.1005182105360.22838@ps20323.dreamhostps.com>
User-Agent: Mutt/1.5.13 (2006-08-11)
Cc: "hybi@ietf.org" <hybi@ietf.org>
Subject: Re: [hybi] #1: HTTP Compliance
X-BeenThere: hybi@ietf.org
X-Mailman-Version: 2.1.9
Precedence: list
List-Id: Server-Initiated HTTP <hybi.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/listinfo/hybi>, <mailto:hybi-request@ietf.org?subject=unsubscribe>
List-Archive: <http://www.ietf.org/mail-archive/web/hybi>
List-Post: <mailto:hybi@ietf.org>
List-Help: <mailto:hybi-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/hybi>, <mailto:hybi-request@ietf.org?subject=subscribe>
X-List-Received-Date: Wed, 19 May 2010 01:32:52 -0000

Ian Hickson wrote:
> On Tue, 18 May 2010, Jamie Lokier wrote:
> >
> > [The extra bytes in the handshake] block useful things:
> > 
> >    - Trying multiple WebSocket subprotocols in turn (on the same connection)
> 
> This is currently blocked by far more important things, like the way the 
> spec says to close the connection if the subprotocol isn't recognised.

Correct, that's also an unnecessary blocker.

> If we want to support multiple subprotocols at once, we can do so quite 
> easily by just making the subprotocol list be comma-separated. Would this 
> be a good idea?

I think it is a good idea, although there is a risk of low-quality
server but significant implementations matching a literal string,
breaking when other values are added to the comma-separate list, and
therefore making it impossible for clients to actually use the
capability.

But assuming the comma-separated list did catch on, a consequence of
that would be the "below the API" part of WebSocket would have a place
to add its own distinct entries to the comma-separated list, for
recognition by the other side as transport option requests (such as
compression, etc.), safe in the knowledge it wouldn't break negotiation.

(Separate headers would be much cleaner for that, though).

> >    - Trying a HTTP-based protocol if WebSocket is unavailable (ditto)
> 
> That wouldn't work anyway because the WebSocket object isn't the same 
> object as the XMLHttpRequest object and they therefore create entirely 
> different connections.

Just being different objects is not technical reason for different connections.
Separate XMLHttpRequest objects have no problem sharing connections.
There is no technical reason why a WebSocket object could not do the
same, just as easily.  Especially in browsers which routinely do this!

> In any case, why wouldn't you know that Web Socket is available? I
> don't understand why you would guess that it is and then find it
> isn't. You need a URL to connect to a Web Socket, why would you make
> up a URL without knowing whether it'll work?

Earlier in this thread, in a reply to you, we already gave an example.
It was the social networking client that talks to numerous de facto
standardised but different WebSocket protocols that the user shouldn't
have to know about.

Basically because autonegotiation is more user-friendly, both in terms
of users having to be given and enter fewer details, and in terms of
telling the user what went wrong if things didn't work out.

As you noted, people don't always pass around URLs - they often pass
around just a domain name, or a truncated URL that doesn't include the
"http:" prefix.

I would agree if it were _complicated_ to do, but we are talking about
really trivial stuff here.  Trying one thing, then trying another, is
already handled by the handshake, and it is utterly trivial to do from
a script.  It's so easy that it's hard to see why any random web
developer wouldn't use it whenever it seemed like a good idea.

It seems obvious to me that countless Javascripts will do exactly that.

The only question, then, is whether the spec forces that to be
unnecessarily inefficient for the sake of a weak security mechanism
which has alternatives.

> >    - HTTP authentication if the server responds with an authentication request
> 
> This can be supported entirely in Web Socket if we want to do that. 
> Currently, it's not clear that supporting this is even desireable, due to 
> the UI issues with doing so.

(On that topic, how do you propose to get through a proxy on port 443
that needs proxy authentication before it passes a CONNECT request?)

> >    - Pipelining WebSocket frames to avoid the negotation RTT delay
> 
> Pipelining WebSocket frames is a security problem for WebSocket API 
> clients, so that's not a problem.

I think that's false.

We have discussed no less than 6 solutions which support RTT-less
pipelining of WebSocket negotiation and initial data, while preventing
them from being misinterpreted by a HTTP server, and in some cases, by
any kind of server (any port) if it can't be tricked by the specified
WebSocket negotiation anyway.

I'm assuming you mean the security problem is a browser client script
opening a WebSocket and attempting to trick an HTTP server or other
kind of server, by sending "raw" requests that could be
misinterpreted, before the server is confirmed as a WebSocket server?

Did you mean something else?  I didn't find an explanation in draft76
of the security issues its mechanisms attempt to prevent; sorry if I
missed it.

> The random bytes do not stop pipelining of frames for dedicated
> clients where there is no security problem.

Dedicated clients that connect to _known_ servers can skip parts of
the WebSocket spec they don't care about anyway. ;-)

Any kind of client connecting to a server it doesn't know will accept
the connection has to follow the commonly agreed rules, which means it
can't pipeline anything until it knows the result of negotation.  But
that's a propery of the current method; it's not intrinsic to
pipelining, as we have already discussed methods without that limitation.

> > Anyway, I think what you're saying is that the WebSocket object and 
> > XMLHttpRequest objects will open separate TCP connections.
> 
> Yes.
> 
> > I'm arguing that the second object should be able to reuse the 
> > connection resulting from the first one's failure to negotiate on the 
> > same port - and that that's even more valuable when the client needs to 
> > attempt a sequence of WebSocket subprotocols in turn before it can begin 
> > real communication.
> 
> WebSocket and HTTP are different protocols. Reusing the connection makes 
> as much sense as reusing the connection of an FTP connection attempt to do 
> an HTTP connection attempt.

This is different.  Both WebSockets and HTTP requests are transient in
many cases.  If FTP was also transient, and it shared the same port
with HTTP, and many servers especially those designed for high
performance implemented both together, and many clients implemented
both, then of course it would make sense to _permit_ connection reuse
between them, without _requiring_ any implementation to do so.

There have been many scenarios presented where it shows a tangible
benefit, in mails to you and the list.

The sole effect of mandating that an idle HTTP connection cannot be
subsequently used for a WebSocket is pointless slowness.
It's not as if the WebSocket negotation will confuse an HTTP server any
differently than it will on a new connection.

The case for reusing a failed WebSocket negotation is not as strong as
that, due to the (imho, dubious) security mechanism of the random
bytes.  It is still a pessimisation, though.

There is a much stronger case for reusing a WebSocket connection after
a gracefully close that puts it into some kind of idle state.  That's
because users follow links every few seconds - and therefore WebSocket
scripts in ordinary pages will connect and disconnect from the same
server and port every few seconds in the current model.  Grossly inefficient.
But that's a digression; we can't do advanced stuff if we can't do the
simple stuff.

> On Tue, 18 May 2010, Greg Wilkins wrote:
> > If the handshake is HTTP compliant, then the connection for a websocket 
> > handshake could be taken from the existing pool of idle connections to a 
> > host.  That would save the time needed to establish the connection.
> 
> The resemblence to HTTP is nothing more than a hack to alolow us to share 
> ports in certain advanced scenarios. Most Web Socket servers will know 
> nothing about HTTP. Reusing connections is a level of complexity that is 
> completely unwarranted

Nobody is suggesting that clients _must_ reuse connections or that
servers _must_ support them.

> It's a proposal that lies on completely the wrong side of the 80/20 
> line and would introduce _massive_ complexity for authors,

Patently false.  Making it optional for both sides adds *zero*
complexity for authors who don't do it.  I am not seeing how you can
think it makes any difference to them.

Seriously, how do you imagine it affects them?

> who would have no idea why their WebSocket servers were suddenly
> receiving random HTTP requests and vice versa.

That's a function of connecting to the wrong type of server already,
and it's already dealt with by the spec'd negotation, which the wrong
type of server handles already by design.  Nothing new there.

Thanks,
-- Jamie