- From: John Fallows <john.fallows@kaazing.com>
- Date: Sat, 28 Oct 2017 09:44:37 +0000
- To: Patrick McManus <pmcmanus@mozilla.com>
- Cc: hybi <hybi@ietf.org>, HTTP Working Group <ietf-http-wg@w3.org>
- Message-ID: <CACAJL3=L51FNxJk_=4dNuzr_u0dH3k24atZg9YYB_MYLAdb8VA@mail.gmail.com>
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 <pmcmanus@mozilla.com> wrote: > On Fri, Oct 27, 2017 at 12:42 PM, John Fallows <john.fallows@kaazing.com> > 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("https://example.com/chat", ["chat", "superchat"]) instead of: new WebSocket("wss://example.com/chat <https://example.com/chat>", ["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 8.1.2.3 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 8.1.2.3 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 pseudo-header. 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 >> https://server.example.com/chat. >> > > no.. the target url is wss://server.example.com/chat 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 > https://server.example.com 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 request. 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://example.com/chat2. 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 https://example.com/chat2 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://example.com/chat2, 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 completed. 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 <pmcmanus@mozilla.com> >> wrote: >> >>> thanks for the feedback.. start with a tightly scoped issue first: >>> >>> On Thu, Oct 26, 2017 at 3:47 PM, John Fallows <john.fallows@kaazing.com> >>> 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 >>> 8.1.2.3 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™ >> kaazing.com/kwic <http://www.kaazing.com/kwic> | Blog >> <http://blog.kaazing.com/> | Twitter <https://twitter.com/kaazing> >> > -- *John Fallows* CTO* | *📞+1.415.215.6597 *----------------------------------------------------------------------* KAAZING >|< when real-time matters™ kaazing.com/kwic <http://www.kaazing.com/kwic> | Blog <http://blog.kaazing.com/> | Twitter <https://twitter.com/kaazing>
Received on Saturday, 28 October 2017 09:45:12 UTC