Re: [hybi] Fwd: New Version Notification for draft-mcmanus-httpbis-h2-websockets-01.txt

John Fallows <> Sat, 28 October 2017 09:44 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id 7C5E413AB34 for <>; Sat, 28 Oct 2017 02:44:52 -0700 (PDT)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -1.888
X-Spam-Status: No, score=-1.888 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, T_SPF_PERMERROR=0.01, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no
Authentication-Results: (amavisd-new); dkim=pass (2048-bit key)
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id 21NT9UEvFpVe for <>; Sat, 28 Oct 2017 02:44:50 -0700 (PDT)
Received: from ( [IPv6:2607:f8b0:400c:c08::22c]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by (Postfix) with ESMTPS id D97B313A214 for <>; Sat, 28 Oct 2017 02:44:49 -0700 (PDT)
Received: by with SMTP id v27so6461502uav.7 for <>; Sat, 28 Oct 2017 02:44:49 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; s=20150623; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=ekmRJhMDJt9XSWSy+XIz5CeVmE/Zx1SQpVhCHJJPiIk=; b=aEcNiUrZdKMSjM0cfvBpm5LLR+xth6Q/+rd9HHjkax/OjHvoox9Nnqy4JYCLcldEqJ WGCu3w+F33Tp58o4EVzn2EN5Eoq1p3R0E8wzMyNVg/EHuZixgZTr2X8dXcHB1mIhpCBl JrPnXdfT0rwHZFtfmKpaN8e052foE8LeU3dXfdWx95pVGp5vLgsbdt6tNwCPP6/oez5P hObgUm03EA8i75EoymGEnrU6Oe+NwK4yWk6Dapng/bUNmHaZ7McpA/o4T3daara+KiJb l36mfDS/cdKdNhIr4jS77/nic+kO4snK0O+IuAN+bkruD+G/GAGb8pXAiajQqNNzLshY 3FeA==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=ekmRJhMDJt9XSWSy+XIz5CeVmE/Zx1SQpVhCHJJPiIk=; b=gaJz2VfoMijwlo1iHnuk0k+toOj597ns9hsaiPWzBlp5KQMaYxoGUoicgTsYKLnsQ9 DcgcHcP237rHNDBplSOTOoXgotU2khwyLsWa+PumpoMz5FSvVR85PgbopYzM+eOc3fcJ Tk/we9WH2q+CwTQl783ZgOjZLmjpVsCtZmGZteG2dFqTYu1poctSYflF4gThLCZi4d+W FxMeuj9seCP03fU2m9Es9S0EpWPRcVigLygr+mjB8yZJavxMIAxAIjqvGU/0YlFYz8oG njo+LyQBV6U5gYmZ4HaFeW06gCW5Yq9IKju5vuX8mTp0dwQs6QKKkmKWFE/+S0T0LzzE kIIg==
X-Gm-Message-State: AMCzsaUDKp1AlKOZAJ7N8Xu7mcmZepnMasCua7/yQLYauG6VyE/uPW7E cD3L/2DTEfEBnNojNaWKL9tEmpRfc7POfIOt9+bPodKf
X-Google-Smtp-Source: ABhQp+RiQlCiy7OvJZG6qRyKdjS8Kgfu50abxsv/wDZqDXRwHEcd2rqjmwUi52hJy0gNTlGw08uyJCqT1ENG801H/MQ=
X-Received: by with SMTP id i3mr2872909uad.195.1509183888685; Sat, 28 Oct 2017 02:44:48 -0700 (PDT)
MIME-Version: 1.0
References: <> <> <> <> <> <>
In-Reply-To: <>
From: John Fallows <>
Date: Sat, 28 Oct 2017 09:44:37 +0000
Message-ID: <>
To: Patrick McManus <>
Cc: hybi <>, HTTP Working Group <>
Content-Type: multipart/alternative; boundary="94eb2c12370e961242055c984189"
Archived-At: <>
Subject: Re: [hybi] Fwd: New Version Notification for draft-mcmanus-httpbis-h2-websockets-01.txt
X-Mailman-Version: 2.1.22
Precedence: list
List-Id: Server-Initiated HTTP <>
List-Unsubscribe: <>, <>
List-Archive: <>
List-Post: <>
List-Help: <>
List-Subscribe: <>, <>
X-List-Received-Date: Sat, 28 Oct 2017 09:44:52 -0000

Hi Patrick,

Thanks for taking the time to address my feedback - comments inline below.

On Fri, Oct 27, 2017 at 10:14 AM Patrick McManus <>

> On Fri, Oct 27, 2017 at 12:42 PM, John Fallows <>
> wrote:
>> Hi Patrick,
>> There seems to be no requirement to change the scheme to wss for a
>> functional handshake using TUNNEL method plus :protocol header with
>> value websocket.
> I'm not changing the scheme. It was also wss in http/1.1 as well - its
> just that scheme does not typically appear on the wire in that protocol.

This one is subtle.

Imagine if the client JavaScript API had elected to use:
  new WebSocket("", ["chat", "superchat"])

instead of:
  new WebSocket("wss:// <>",
["chat", "superchat"])

then absolutely nothing about the wire protocol would have needed to change
for HTTP/1.1 WebSocket.

Interestingly, one of the original WebSocket handshake response headers
called WebSocket-Location, with ws[s] scheme URL, was removed as part of
the cleanup to use HTTP/1.1 proper.

As mentioned, the invention of the ws and wss schemes were born from not
using HTTP/1.1 proper from the beginning, including initially having
non-HTTP default ports such as 81 for ws instead of 80.

Server-Sent Events protocol deems it sufficient to offer a GET method
with accept
= text/event-stream header in the HTTP request, just as WebSocket protocol
deems it sufficient (in this proposed feedback) to offer a TUNNEL method
with :protocol = websocket pseudo-header in the HTTP request.

Although the origins of the WebSocket protocol design initially diverged
from HTTP, after the convergence on HTTP/1.1 proper, there was no remaining
justification for the "ws" and "wss" schemes from a network protocol
perspective, so they became a client-side concept enforced by the WebSocket
API and used by Proxy Auto-Configuration (PAC).

I'm suggesting we keep the "wss" scheme as a client-side concept, but also
avoid propagating it into the HTTP/2 network layer unnecessarily. Including
it just forces the server to pretend the :scheme = https anyway, e.g. the
server needs to know about :scheme = wss explicitly to treat it as https
while still processing HTTP layer semantics, such as cross-origin security.

>From an abstraction layering point of view, only WebSocket should depend on
HTTP, not the reverse.

My reference to 7540 explicitly talks about non http schemes (ftp
> is the most common). That doesn't make CONNECT/TUNNEL non http.. it just
> means http is being used to interact with a non-http service..

Good point - I went back and re-read RFC 7540, section regarding
the :scheme pseudo-header (copied below).

*:scheme is not restricted to http and https schemed URIs. A proxy or
gateway can translate requests for non-HTTP schemes, enabling the use of
HTTP to interact with non-HTTP services.*

I understood this to mean that an HTTP GET request with scheme ftp could be
translated by an HTTP/2 proxy or gateway to a certain usage of FTP wire
protocol, such as file retrieval, while an HTTP POST request with
scheme ftp might
be translated as file upload via FTP wire protocol.

That desired translation of HTTP <=> FTP is captured by the :scheme = ftp

Since we are not trying to translate between HTTP primitives and WebSocket
protocol primitives, the use of :scheme = wss doesn't seem quite right.

> In the example, the target URL used by the WebSocket on the wire would be
> no.. the target url is wss:// and this is a
> definition of how to use h2 to access that service. This document doesn't
> say anything about how to access an https:// schemed url. If the URL were
> it would be rejected by a websocket client
> which requires ws or wss. PAC evaluation also expects ws/wss schemes.

I think you missed my point - sorry, my fault.

I was trying to draw a clear distinction between a particular WebSocket
client implementation requirement (W3C territory) and the WebSocket
protocol requirement (IETF territory).

>From a network protocol perspective, all HTTP requests aimed at a
particular origin server, whether they use GET method or the proposed TUNNEL
method, would seem to logically have the same http or https scheme.

Singling out TUNNEL method with :protocol = websocket to present a
different :scheme = wss just seems to introduce more questions due to the
divergence from :scheme = https from the network protocol perspective.

Unlike a protocol, which represents a single layer in a protocol stack, a
scheme often unpacks to multiple protocol layers forming a protocol stack.
For example, the https scheme unpacks to http over tls over tcp.

In HTTP/2, transmitting :scheme = https describes the protocol stack up to
and including HTTP/2 itself. For example, this makes it easier for the
server to construct URLs that can be passed back to the client, where they
can be unpacked into a protocol stack consistent with the original HTTP/2

If the server is processing the TUNNEL method with :protocol = websocket HTTP/2
request, and :scheme = wss is included, it is not accurately representing
the protocol stack up to and including HTTP/2, because the WebSocket
protocol handshake has not yet completed.

Say, at the HTTP/2 layer of the protocol stack, the server wants to issue a
302 redirect to path /chat2 in absolute form. It might most naturally
construct the redirect location using a consistent :scheme, :authority and
in this case replacement :path. However, with :scheme = wss the constructed
location would not be correctly formed as it would be requesting an HTTP
redirect to wss://

Instead the HTTP/2 layer at the server would need to know to pretend :scheme
= wss was really :scheme = https so it could send the redirect to as intended. Then the client HTTP/2 layer would
need to somehow infer that the redirected request should send :scheme
= wss even
though the redirect URL had scheme https.

Alternatively, the HTTP/2 layer at the server would actually send the
redirect to wss://, and then expect the HTTP/2 layer at
the client to understand how to follow that redirect as if https and
presumably include :scheme = wss.

Putting :scheme = wss on the wire forces a tight coupling between the
HTTP/2 and WebSocket subsystems for non-obvious benefit, while the tight
coupling can be avoided by putting :scheme = https on the wire instead.

>> The cross-origin security checks (etc) are enforced by HTTP-specific
>> validation of the request headers prior to processing the TUNNEL method
>> semantics. If the validation fails, then the request never became a
>> WebSocket. Only after a successful HTTP response is provided can the pair
>> of HTTP/2 streams be considered a WebSocket.
> maybe you're confusing protocol with scheme?

No, they are quite distinct as described above.

The problem with sending :scheme = wss at the HTTP layer is that it
represents a promise of what will happen after the HTTP layer instead of
the current state up to and including the HTTP layer. That promise of
what's to come is already captured by the :protocol = websocket pseudo-header
so :scheme = wss doesn't appear to be adding much value.

Even after this was cleaned up to be a fully HTTP/1.1 compliant handshake,
>> as part of the work in IETF HyBi, the "ws" and "wss" schemes remained in
>> use on the client (only) but were deliberately not exposed on the wire.
> whether or not the scheme is on the wire is a property of http - not
> something hybi was ever in a position to standardize. (thus the 'cleanup'.)
> one weird note of 7230 5.3.2 requires that servers MUST accept absolute
> form requests even though clients are forbidden from sending them to
> non-proxies. The absolute form here would be wss://.. so this is an h1
> thing too it just wasn't obvious.

That interpretation doesn't seem consistent with RFC-6455, section 4.1
regarding absolute form (copied below).

*The "Request-URI" part of the request MUST match the /resource*
*        name/ defined in Section 3 (a relative URI) or be an absolute*
*        http/https URI that, when parsed, has a /resource name/, /host/,*
*        and /port/ that match the corresponding ws/wss URI.*

WebSocket servers should accept https://... as absolute form (not
wss://...), then process the Upgrade: websocket handshake without
attempting to change the meaning of the HTTP layer before the handshake has

Section 4.1 seems to make it clear that the intended scheme on the wire is
https for secure WebSocket connections.

If HTML5 or a client SDK in any other language decided to formalize sse as
the scheme to denote Server-Sent Events URLs, it would have no bearing on
the HTTP network traffic to setup an SSE event stream because it is a
client-side API contract that is not needed by the protocol layer.

IMHO, the wss scheme is an equivalent client-side API contract that is
equally not needed by the protocol layer.

> Having separate schemes for protocols that must start out life as HTTP
>> forces questions about port defaulting for those schemes. Since the "ws"
>> and "wss" schemes ended up being treated the same as "http" and "https" in
>> terms of port defaulting, there doesn't seem to be much value in
>> propagating the "wss" scheme to the server especially when the :protocol
>> header is present with value "websocket".
> you can of course imagine :protocol changing to be websocket2 with the
> scheme not changing.

Looking forward to hearing your perspective.

Kind Regards,
John Fallows
CTO, Kaazing

>> Hope this is helpful.
>> Kind Regards,
>> John Fallows
>> CTO, Kaazing
>> On Fri, Oct 27, 2017 at 5:33 AM Patrick McManus <>
>> wrote:
>>> thanks for the feedback.. start with a tightly scoped issue first:
>>> On Thu, Oct 26, 2017 at 3:47 PM, John Fallows <>
>>> wrote:
>>>> Note also that the scheme is "https" rather than "wss" because the HTTP
>>>> request is still "https" until *after* the TUNNEL has been established, and
>>>> the TUNNEL protocol being selected is based on :protocol header rather
>>>> than the :scheme header.
>>> I don't think so.. there is no https target URL in play here.  7540
>>> talks about non http schemes allowing the use of HTTP to interact
>>> with non-http services this way.
>>> --
>> *John Fallows*
>> CTO*  |  *đź“ž+1.415.215.6597 <(415)%20215-6597>
>> *----------------------------------------------------------------------*
>> KAAZING >|<  when real-time matters™
>> <>  |  Blog
>> <>  |  Twitter <>
> --
*John Fallows*
CTO*  |  *đź“ž+1.415.215.6597
KAAZING >|<  when real-time matters™ <>  |  Blog
<>  |  Twitter <>