Re: [hybi] WebSocket -76 is incompatible with HTTP reverse proxies

Willy Tarreau <w@1wt.eu> Wed, 07 July 2010 04:41 UTC

Return-Path: <w@1wt.eu>
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 E30E33A6957 for <hybi@core3.amsl.com>; Tue, 6 Jul 2010 21:41:35 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2.138
X-Spam-Level:
X-Spam-Status: No, score=-2.138 tagged_above=-999 required=5 tests=[AWL=-1.583, BAYES_05=-1.11, HELO_IS_SMALL6=0.556]
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 4Es-AxHEDN0l for <hybi@core3.amsl.com>; Tue, 6 Jul 2010 21:41:34 -0700 (PDT)
Received: from 1wt.eu (1wt.eu [62.212.114.60]) by core3.amsl.com (Postfix) with ESMTP id 96F263A67CC for <hybi@ietf.org>; Tue, 6 Jul 2010 21:41:32 -0700 (PDT)
Date: Wed, 7 Jul 2010 06:41:29 +0200
From: Willy Tarreau <w@1wt.eu>
To: Micheil Smith <micheil@brandedcode.com>
Message-ID: <20100707044129.GH12126@1wt.eu>
References: <20100706210039.GA12167@1wt.eu> <B709B846-2A8C-4B84-8F4D-B06B81D91A7B@brandedcode.com>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
In-Reply-To: <B709B846-2A8C-4B84-8F4D-B06B81D91A7B@brandedcode.com>
User-Agent: Mutt/1.5.20 (2009-06-14)
Cc: hybi@ietf.org
Subject: Re: [hybi] WebSocket -76 is incompatible with HTTP reverse proxies
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, 07 Jul 2010 04:41:36 -0000

On Wed, Jul 07, 2010 at 12:44:32PM +1000, Micheil Smith wrote:
> Willy,
> 
> Thanks for raising this point. I'm an author of a node.js powered websocket 
> server, and this was actually a really awkward part of the websocket spec to 
> comply to when writing my server.
> 
> Without having a content-length header, the http parser in node doesn't know 
> how to handle the extra data it receives in that initial handshake. What we 
> ended up doing as a fix, was just to provide an upgradeHead as a slice of the
> buffer from where the headers ended to the end of the packet.
> 
> In short, I'd be all for having a content-length header sent to declare the body 
> as a body, or to declare it as just extra data that should be handled post upgrade.
> >From what I can tell from what Ian is telling me over irc, he'd be more inclined to 
> add in content-length: 0 as a header, then content-length: 8.
> 
> Hopefully this reply does make somewhat sense.

Content-length: 0 also makes sense but it means that the nonce will
be sent *after* the handshake, which means we'd have a second
round-trip. For some sites who deal with hundreds of thousands of
concurrent connections (and I know some), having two more packets
in a connectionn is an unneeded increase of network traffic. For
this reason, I think that the idea of the nonce in the request header
is good.

However, I think that having content-length: 0 in the *response* will
definitely help eliminating incompatible intermediates : those who
properly support 101 will forward the data regardless of the content
length because the tunnel is established. Those who don't completely
support 101 will stop at the content-length and not forward the
response. Alternatively, it might be nice to use a transfer-encoding:
chunked in the response with only an end of chunk ("0\r\n") before the
nonce. That would permit the client to check if it receives only the
"0\r\n" or if it receives the nonce too. An increased check could also
consist in setting "Connection: close" in the response in addition with
the transfer-encoding or content-length. That way, incompatible
intermediates won't remain open waiting for anything and will quickly
close the connection before the part they don't support.

Regards,
Willy