Re: [hybi] WS framing alternative

Greg Wilkins <gregw@webtide.com> Mon, 02 November 2009 01:19 UTC

Return-Path: <gregw@webtide.com>
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 4A2D43A6882 for <hybi@core3.amsl.com>; Sun, 1 Nov 2009 17:19:41 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2.416
X-Spam-Level:
X-Spam-Status: No, score=-2.416 tagged_above=-999 required=5 tests=[AWL=0.183, BAYES_00=-2.599]
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 tv7moJ2aIulX for <hybi@core3.amsl.com>; Sun, 1 Nov 2009 17:19:39 -0800 (PST)
Received: from mail-gx0-f212.google.com (mail-gx0-f212.google.com [209.85.217.212]) by core3.amsl.com (Postfix) with ESMTP id 625653A6856 for <hybi@ietf.org>; Sun, 1 Nov 2009 17:19:39 -0800 (PST)
Received: by gxk4 with SMTP id 4so3816276gxk.8 for <hybi@ietf.org>; Sun, 01 Nov 2009 17:19:55 -0800 (PST)
Received: by 10.150.76.11 with SMTP id y11mr7351435yba.181.1257124794972; Sun, 01 Nov 2009 17:19:54 -0800 (PST)
Received: from ?10.10.1.9? (60-242-119-126.tpgi.com.au [60.242.119.126]) by mx.google.com with ESMTPS id 15sm1655210gxk.8.2009.11.01.17.19.51 (version=TLSv1/SSLv3 cipher=RC4-MD5); Sun, 01 Nov 2009 17:19:53 -0800 (PST)
Message-ID: <4AEE33AE.4080601@webtide.com>
Date: Mon, 02 Nov 2009 12:19:42 +1100
From: Greg Wilkins <gregw@webtide.com>
User-Agent: Thunderbird 2.0.0.23 (X11/20090817)
MIME-Version: 1.0
To: hybi@ietf.org
References: <mailman.3820.1256908248.4669.hybi@ietf.org> <91a5e3ea0910301458q465e5778kb46bcaedc65595a6@mail.gmail.com> <4AEB7AD1.7050509@webtide.com> <Pine.LNX.4.62.0910310401280.25616@hixie.dreamhostps.com>
In-Reply-To: <Pine.LNX.4.62.0910310401280.25616@hixie.dreamhostps.com>
X-Enigmail-Version: 0.95.7
Content-Type: text/plain; charset="ISO-8859-1"
Content-Transfer-Encoding: 7bit
Subject: Re: [hybi] WS framing alternative
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: Mon, 02 Nov 2009 01:19:41 -0000

Ian Hickson wrote:

> It's quite easy to make extensions to WebSocket that are backwards- and
> forwards-compatible. It just needs a revision of the protocol spec to
> define the new feature so that all UAs can be updated to support it.
>
> We should, however, keep such features to a minimum, so as to keep the
> protocol from ballooning into something only experts can implement.


So I think this is our FUNDAMENTAL point of disagreement.

You are arguing about making ws not user extensible
because you believe that it is easier to rev the spec
and update "all UAs".     It is an impossible task
to upgrade "all UAs" and even if it was, you are looking
at 3 to 5 year cycles to get any significant market
penetration.

How is a web ecosystem that is bristling with thousands of open
and/or proprietary extensions is going to be happy with a
protocol that can only be extended by new versions of the base
document - how is that layered?

You honestly believe that a process that can't even agree
on length-vs-sentinel framing is going to be able to centrally
coordinate all extensions to websocket in a timely manner?




> I believe the problem we have here is that we don't agree on what problem
> we are solving, though apparently Greg disagrees with me on that as well.

I disagree with you that I disagree with you on this :)

You and I are truly trying to solve different problems.


I believe our major differences are on requirements - mostly on
the requirement to allow transparent extension.

I think we also disagree on what extensions are necessary,
which your appear to believe should be centrally coordinated.
I believe that extensions need to be allowed to be created
and evolve in a Darwinian ecosystem outside of a committee system.


We also significantly disagree on a lot of technical detail
of how to do framing etc.   But that is significantly less important
and we really should try to refrain from debating that blow by
blow until the broad requirements are roughly agreed.




> On Sat, 31 Oct 2009, Greg Wilkins wrote:
>> What I'm currently trying to compromise on is:
>>
>>
>>    |\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
>>    | Application-level protocol | user application features
>>    +----------------------------+
>>    | Optional transport features| Multiplexing, compression, etc.
>>    +----------------------------+
>>    | Websocket protocol         | Two way comms, browser security model
>>    +----------------------------+
>>    | TCP                        | reliability, connection wrapper
>>    +----------------------------+
>>    | IP                         | packet abstraction, routing
>>    +----------------------------+
>>    | Ethernet                   | link-level routing
>>    |/\/\/\/\/\/\/\/\/\/\/\/\/\/\|
> 
> That's what I'm advocating. I guess our disagreement is that I think the 
> optional transport features should be in a separate spec layered on top of 
> WebSocket, just like BEEP and XMPP aren't in the raw TCP spec.

I agree totally that optional transport features layered on top of
WS should be specified in a separate spec.

( I could argue for some features (eg multi-plexing) to be non
optional - but that's a different debate).

What I'd like to see in the base ws spec are the ground rules for
most extensions - ie a meta data mechanism, so that extension can be done
easily, with negotiation and without breaking non conforming
implementations.

If there was a standard meta data mechanism in WS, then I would rewrite
BWTP protosal to be layered on top of WS.  It currently uses text based
length encoded frames - but it could easily be transported over WS
framing. It could become the basis for mutliplexing and fragmentation
extensions - but only if standardized meta data is supported.



> If we want multiplexing that is transparent to scripts (as opposed to
> layered on top of WebSocket, which seems to make more sense to me), then
> we need a whole new protocol; WebSocket just isn't cut out to do built-in
> multiplexing. (It handles higher-level multiplexing fine.)

Why can't a multiplexing protocol be both transparent to scripts
AND layered on top of WebSocket protocol?.

If I need a who new protocol for multiplexing, do I need
a whole new protocol for compression?    Then what do I do
if I want compression AND multiplexing - another new protocol?



> The extension mechanism is intended for providing new features in the
> future, specifically sending binary files, and sending binary streams
> (e.g. video). It's not a generic extension mechanism for protocol users.

OK - the type frame byte might not be a generic extension
mechanism for protocol users.   But that does not mean there
is not a need for one.


This is why I'm advocating for a standard meta data
transport (but not standard meta data).  Something along
the lines  of the base protocol allocating:

  0x01 be a UTF-8 frame of mime headers
  0x81 be a binary frame of mime encoded content (headers CRLFCRLF body)

These would be know by all implementations.  Simple implementations
that don't want to know about extensions can ignore them (as they
have to do now anyway).   Implementations that have extensions will
know the content-type of meta data in these frames and can inspect looking
for extension that they support.

The actual semantics of these frames would not be defined in the
base websocket protocol and would be a matter for the extensions.



>>>> I'm asking for 1 bit to be allocated to indicate that a frame 
>>>> contains mime-encoded data.  That is mostly sufficient for layered 
>>>> protocols to be built on.
>> I would reuse the text and binary framing mechanism.
> 
> Why are frame types 0x00 and 0x80 not good enough then?

Because they are already allocated for data transport
and thus are unsuitable for meta-data.

If we put extensions in those frames, we will break
implementations that don't support them.

If we want to use multiple extensions (eg multiplexing,
compression and SSL offload), then working out
who an 0x00 message is for is really difficult because
we don't know what the content-type(s) might be so
we can't introspect it.




> Sure. We could add compression in a future version of WebSocket.
> [...]
> This would be a sensible thing to support in a future version if we decide
> that implementation experience shows compression to be highly desireable.

The problem with what you say are the "we could add", "future version"
and "if we decide" parts.

Netscape didn't have to wait for any "we" to formulate HTTP/1.1 so that
persistent connections could be supported.   They came up with HTTP/1.0
keep-alive as a defacto standard that worked because HTTP supports
arbitrary meta-data that can be ignored.

I don't want to have to wait for whoever "we" is, to deign to consider
my particular pain point.     It might not be globally applicable.
It might be very niche and apply only to a small community of users.

But they should not be forced to give up on interoperability
to implement their own extensions.


> (It's not obviously desireable, or I'd have added it already. Reasons why
> we might avoid it are that compression is not always useful for short
> strings, which are probably going to be most common; and that it's
> possible for compression to be introduced at the TLS level, thus making
> the protocol's use of compression unnecessary.)

It might not be desirable to you... but your mileage may vary!

Maybe my messages are not all that short.
Maybe my messages are short but really easy to compress.
Maybe I have really fast CPUs and a really slow network?
Maybe I have different sized messages and want to compress
some but not others?

one-size-fits-all protocols are not going to work!

I really really really REALLY don't want to have to
work on an internet that everytime i want to do something
new, innovative or just plain pragmatic for private reasons,
that I have to confronted with endless "why do you want to
do that" questions from the whatwg: for example:




> Why would you ever connect to a server that supported a protocol, if you 
> weren't expecting to speak that protocol?
> The browsers aren't doing anything other than what the scripts want them
> to do. The servers have no reason to support anything the clients aren't
> going to use, which is what the scripts are going to do.


Because the protocol might not be a server protocol, it might
be an intermediary protocol that is setup by your own local
infrastructure provider, by your ISP or by the deployers of
the server side (who may differ from the developers of the
server side).

Load balancing, compression, aggregation, SSL offload,
authentication etc. are all things that can be injected
between a client and server without the application authors
being involved.



> What would you need to do a "sticky load balancer with SSL offload" other
> than what TCP gives you already?

SSL offload removed CPU/network load from application servers.

But the offloader still needs to communicate meta data about
the SSL session to the server.

During a connection, the server might need to request that the
offloader  upgrade the connection (get a new key or request
client certificates).

Some server code will know about the offloaders existence
and extension protocols, but it also needs to be able to
work iwth code that does not and just thinks it is getting
a normal none-SSL connection.

Sticky load balancing is very important for mid-sized
deployments where an organization has a handful of stateful
nodes supplying a service (larger deployments tend to be
forced to be truly stateless and smaller deployments have
only 1 node).

If a client has multiple connections or renews a connection,
it is highly desirable (sometimes necessary) that all the
connections terminate on the same node.    Strange gateways
(eg AOL) mean that 2 connections from the same client can
be seen to come from different IPs   (note that
multiplexing would significantly reduce the need for
sticky load balancing!).

Sticky load balancing needs to be able to set state on
the client - typically cookies.   To facilitate load
migration and cluster maintenance, an ongoing meta-data
conversation is necessary between balancer and client
to manipulate this state (eg send a meta data frame
saying that the server has migrated your state to
a different node and please update the cookie (or whatever)
accordingly).


> What is the use case for the browser
> implementing multiplexing rather than a SharedWorker from script?

Because different frames might be implemented by different
developers using different frameworks and libraries, with out
any knowledge of the each other.  Thus they can't cooperate
on a shared worker.

Because code from multiple origins might accessing the
same server and security will be hard to enforce in
script in a shared worker.

Because it is not in the applications interest to share
connections - thus they have very little interest in doing so.

It is in the server/network vendors interest that multiplexing
is used and it is there job to convince the browser vendors
to implement that below the level of the application.

I'd like to see this built into base websocket protocol,
but if a reasonable extension path is provided, then I think
a layered multiplexing specification would have some chance
of successfully attracting support from browser vendors.



> If we want multiplexing that is transparent to scripts (as opposed to
> layered on top of WebSocket, which seems to make more sense to me), then
> we need a whole new protocol; WebSocket just isn't cut out to do built-in
> multiplexing. (It handles higher-level multiplexing fine.)

Why can't a multiplexing protocol be both transparent to scripts
AND layered on top of WebSocket protocol?.

If I need a who new protocol for multiplexing, do I need
a whole new protocol for compression?    Then what do I do
if I want compression AND multiplexing - another new protocol?




> I really, truly do not understand how you expect this feature to be used. 
> You need to explain a concrete use case, with actual examples of actual 
> user applications and actual on-the-wire traffic explaining to me what you 
> expect to have happen, because I have completely failed to understand the 
> more abstract use cases you have given so far.

All I'm doing is pointing out use-cases that exist today for
HTTP.    I'm not the expert on exactly what they require or
what meta-data they exchange - but I do have experience with
working with many of them, so I at least know of their existence
and what is involved to interoperate.

I have listed many many use-cases that exist today that
exchange meta data between clients, servers and intermediaries
in a mostly transparent fashion.

If you don't understand these existing use-cases then perhaps
you should familiarize yourself with these common elements
of internet infrastructure before finalizing your protocol?



>> But you can't provide a transparent compression extension, because the 
>> browser has no way to signal to the server "I handle this extension".
> 
> Sure it can. The handshake is completely extensible.

Is it?
It allows extra headers for authentication information or cookies
to be sent - but under very strict ordering conditions and with
limitations on standard HTTP header format.    This is hardly saying
that arbitrary headers for arbitrary extensions might be sent.

I do note that set-cookie is supported in the handshake response
(despite your earlier comment that this would be supported under no
circumstances). This is a start.

But other headers are ignored.    I guess this would allow a browser
to ignore the ignore and do an extension, but it would not allow
an application layer to do an extension (as you are advocating).

Even if the handshake is extensible - problems persist.   Say
I want to write an extension to send Content-Type meta data in
a mime-header frame before every data frame.  I could self
allocate 0x7f for that frame.    But this might clash with
somebody elses self allocated frame type, or break an intermediary
that had ignored my extra headers. etc. etc.


> We absolutely would not want clients and servers doing compression without 
> a spec defining how it works. Said spec can allow sending headers to opt- 
> in to compression, as well as defining which frames to use. It would be 
> actively harmful for the WebSocket spec _without_ compression to say that 
> clients could add arbitrary headers

Now you are contradicting yourself.    How is the header
"completely extensible" if you think it harmful if
"clients could add arbitrary headers" ?


> interoperability would be a nightmare 
> where implementations have to reverse-engineer each other to work out what 
> they need to support.

who needs to reverse-engineer what?  Whose talking about secret
non-interoperable extensions?

The experience with HTTP is that people do know how to add optional
features that can be harmlessly ignored for backward compatibility.

Experience with attempts to centrally control innovations is that
they fail.


cheers