How to upgrade an HTTP/3 connection into WebSocket? - websocket

Is HTTP/3 compatible with WebSocket?
Is there any solution for this?

While there exist RFC 8441 that specifies how to bootstrap WebSocket over HTTP/2, there is not yet such RFC (in final form) for HTTP/3.
However, given that HTTP/2 and HTTP/3 are quite similar (at the HTTP/x framing layer), this is in the work at this draft RFC: https://www.ietf.org/archive/id/draft-hamilton-httpbis-h3-websockets-00.html.
I expect browsers and libraries to implement this draft RFC in the following months, like it happened for RFC 8441.
Currently, a browser will either open a separate WebSocket connection, or use an existing HTTP/2 connection as specified by RFC 8441.

Related

What is the WebSockets alternative in the HTTP/2 world?

The new HTTP/2 protocol comes with some promising features. Some of them:
Multiplexing - a single TCP connection can be used to make multiple HTTP/2 requests and receive multiple responses (to a single origin)
HTTP/2 Server Push - sending server responses to the client without receiving requests, i.e. initiated by the server
Bidirectional connection - HTTP/2 spec - Streams and Multiplexing:
A "stream" is an independent, bidirectional sequence of frames
exchanged between the client and server within an HTTP/2 connection.
The motivation behind HTTP/2 is explained here HTTP/2 FAQ:
HTTP/1.1 has served the Web well for more than fifteen years, but its
age is starting to show.
and
The goal of the Working Group is that typical uses of HTTP/1.x can use HTTP/2 and see some benefit.
So HTTP/2 is nice and comes to replace HTTP/1.x. Unfortunately, HTTP/2 does not support WebSockets. In this question Does HTTP/2 make websockets obsolete? it is made clear that the HTTP/2 Server Push is not an alternative, neither are Server-Sent Events.
Now to the question: What do we use if we want WebSockts functionality over HTTP/2?
Current forms of HTTP/2 Protocol Negotiation:
HTTP/2 connections start in one of three ways:
In an encrypted connection (TLS/SSL) using ALPN (Application Layer Protocol Negotiation). Most browsers require TLS/SSL for HTTP/2 and use this method for HTTP/2 connection establishment.
In clear text, using the HTTP/1.1 Upgrade header (same as Websockets). Most browsers require TLS/SSL for HTTP/2, so this is limited in it's support.
In clear text, using a special string at the beginning of an HTTP/1.1 connection (which could allow HTTP/2 servers in clear text to disable HTTP/1.1 support). Limited client support.
Negotiating the Websocket Protocol, present tense:
Negotiating Websocket connections, at the moment, requires HTTP/1.1 support and makes use of the HTTP/1.1 Upgrade header.
This is often performed by the same application server that listens to the HTTP/1.1 and HTTP/2 connections. Web applications that support concurrency (whether evented or thread based) are usually protocol agnostic (as long as HTTP semantics are preserved) and work well enough on both protocols.
This allows HTTP data to be used during connection establishment (and perhaps effect the Websocket connection state/authentication procedure).
Once the Websocket connection is established, it's totally independent from the HTTP semantics / layer.
Negotiating the Websocket Protocol in an HTTP/2 world:
In an HTTP/2 (only) world, which might be a while into the future, there could be a number of possible approaches to Websocket protocol negotiation: an ALPN based approach and an HTTP/2 "tunnel" (or "stream") approach.
The ALPN approach preserves protocol independence at the expense of the pre-upgrade (HTTP) stage, while the "stream" approach provides the HTTP pre-"upgrade" (or Connect) stage at the expense of high coupling and complexity.
The ALPN Approach:
One possible future approach will simply add the Websocket protocol to the ALPN negotiation table.
At the moment, ALPN is used to select (or default to) the "http/1.1" protocol and the Upgrade request is handled by the HTTP/1.1 server. Which means that Websocket still provides us with the HTTP header data during protocol negotiation (while using it's own TCP/IP connection)
In the future, ALPN might simply add "wss" as an available choice.
Using this approach, the Websocket (which is currently established using the HTTP/1.1 Upgrade header, both in encrypted and clear text forms) could easily be negotiated using the ALPN extension to the TLS/SSL layer.
This will keep the Websocket protocol independent from the HTTP/2 protocol and allow it's use even when HTTP isn't supported.
However, this will come with the downside that cookies and other HTTP headers might be no longer available as part of the protocol negotiation. Another difference (both good and bad) is that this approach will require a separate TCP/IP connection.
The HTTP/2 "tunnel" / "stream" approach
Another possible future approach, which is reflected in this proposed draft, will dispose of the HTTP/1.1 variation of the Websocket protocol in favor of an HTTP/2 "stream" approach.
HTTP/2 "streams" are the way HTTP/2 implements multiplexing and allows multiple requests to be handled concurrently. Each request receives a stream number ID and any data pertaining to this request (headers, responses etc') is identified using the same numerical stream ID.
Under this approach, "Websocket" data will be contain within the HTTP/2 wrapper and the stream ID will be used to identify the "Websocket" stream.
Although this might provide some benefits (HTTP headers and cookies could be provided as part of the Websocket negotiation), it's not without its downfalls.
Higher complexity and tighter protocol coupling are just two examples, both of which are very serious downfalls.
Conclusion:
At the time of this writing, HTTP/1.1 Upgrade semantics are required for Websocket connections, both when using clear text (ws) and encrypted (wss) connections.
The future is, as of yet, undecided and it will probably take a long time before the current Upgrade process (using HTTP/1.1) is phased out
Well your timing is rather apt!
A new version of the internet standards draft was literally just published:
Bootstrapping WebSockets with HTTP/2
Additional information here:
https://github.com/mcmanus/draft-h2ws/blob/master/README.md
And you can follow the discussion in it here:
https://lists.w3.org/Archives/Public/ietf-http-wg/2017OctDec/0032.html
Until this is approved, and then implemented by browsers and servers, I would say that Daniel Haxx’s post that you included in your question represents a very good summary of the current status.
One of your links actually has one answer: you can just use SSE.
Semantically, you can achieve the same things with either websockets or (SSE + POST ). The view that the two technologies address different use cases is, roughly speaking, bikeshedding around "this syntax works better for this".
There are ongoing efforts to port something similar to websockets to HTTP/2, but unless those technologies make possible new uses cases or efficiencies, I see no point.

Why WebSockets use ("ws" and "wss") instead of ("http" and "https")?

What was a reason for registering special URI schemes: "ws" and "wss"?
I briefly read specs, and didn't find any reason about this change.
https://www.rfc-editor.org/rfc/rfc6455#section-11.1
WebSocket client sends special headers (Connection: Upgrade, Upgrade: websocket) which lets relatively easy decide whether this is normal HTTP requests (GET,POST ...etc) or this is WebSocket connection request.
Why WebSockets can't work using "http" and "https" schemes?
I wasn't on the board or anything, but here's any 2¢...:
The protocol's handshake currently uses HTTP(S) for connection establishment, but this is as far as the HTTP involvement goes.
It's highly possible that future versions might extend the handshake possibilities, using technologies such as ALPN.
By using the URI scheme ws://... and wss://..., the handshake is decoupled from the URI, allowing future changes to occur with less disturbance.
They use it for sake of architectural clarity, looks like there is no technical limitation why you could not handle your websocket connections using purely http.
Please notice javascript client libraries for handling websocket connections like Paho, are handling websockets purely over http protocol, and even fail if you are explicitly providing host prefixed with ws protocol instead - A piece of simple example from showcase code:
// Create a client instance
client = new Paho.MQTT.Client(
location.hostname, Number(location.port), "clientId"
);

How does a browser know if a site supports HTTP/2?

If I type out https://http2.golang.org/ the chrome browser will automatically send the HTTP/2 request. How is this done?
Take stackoverflow for example, when the browser sends a request to stackoverflow.com, it has to do the following steps:
DNS lookup. find the ip address of stackoverflow.
TCP/IP handshake
TLS handshake.
HTTP request/response (Application Protocol).
....
TLS handshake
Regarding step3 TLS handshake, there is an nice explanation by #Oleg.
In order to inspect the detail of TCP/IP packet, You may need use some tools to capture packets. e.g. Wireshark.
Client sends ClientHello to server, which carries several things
supported cipher suite. which cipher suites do you like?
supported TLS version.
a random number.
the supported Application Protocols. e.g. HTTP/2, HTTP 1.1/ Spdy/..
...
Server responds SeverHello, which carries
chosen cipher suite.
chosen TLS version.
a random generated number
And, chosen application protocols in TLS application-layer protocol negotiation (ALPN), e.g. HTTP/2
Conclusion
HTTP2 request/response happens in step4. Before that, browser has already know whether sever support HTTP/2 through TLS handshake.
The chrome browser will only send a HTTP/1.1 Request to the website. As the website is HTTP/2 Enabled, it will send a message to the browser that it supports HTTP/2. The server upgrades the communication protocol between it and the server to HTTP/2 if it finds the browser capable of recognizing HTTP/2.
So, it is generally the server which converts a request to the HTTP/2 Connection. The browser just complies with the upgrade policy of the server.
The chrome browser displays that you have a HTTP/2 connection with the server or website, only after the server upgrades the communication protocol.
The string "h2" identifies the protocol where HTTP/2 uses Transport Layer >Security (TLS) [TLS12].
This identifier is used in the TLS application-layer protocol negotiation (ALPN) >extension [TLS-ALPN] field and in any place where HTTP/2 over TLS is identified.
If server support http2.0 browser will find that server is support http2.0 in TLS application-layer protocol negotiation.
refer link!

netty websocket protocols support

I tried to look this over in the Netty documentation but was unable to find it : which all websocket protocols does Netty websocket implementation support ?
I am trying to check for browser compatibility and hence also wanted to see the protocols as mentioned above. Going through the websocket server example in Netty 3.5.3 , I see in the WebSocketServerIndexPage class that window.MozWebSocket is also used , hence am I right that hybi-07 and hybi-10 is also supported without any specific code to be written? (Pardon me I am not much aware of the differences in the various protocols but it seems to be mentioned everywhere).
Netty supports protocol versions HyBi 00 (which is the same as Hixie 76), HyBi 8-10 and HyBi 13-17 (17 is the same as IETF 6455).
Each browser supports a single version of the protocol. HyBi 00-76 covers current released versions of iOS. IETF 6455 covers recent versions of Chrome and Firefox (and Opera if once they enable it by default), and IE 10. For browsers without native WebSocket support but with Flash you can use web-socket-js as a fallback and that supports IETF 6455 (albeit without binary data types).
In other words, Netty supports basically all browsers that have WebSocket support.
According to the netty api docs, it supports 3 versions of the Hybi drafts - 00, 07 and 10 as well as RFC 6455.
This will give you support for most browsers as summarised by http://en.wikipedia.org/wiki/WebSocket.

How to establish a TCP Socket connection from a web browser (client side)?

I've read about WebSockets but they don't seem to be pure "sockets", because there is an application layer protocol over them. "ws:"
Is there any way of doing a pure socket connection from a web browser, to enliven webpages?
Here are my random stabs in the dark
Applets sockets provided by Java (need java installed)
Flash sockets provided by Flash (need flash installed)
But about HTML5, Why are they called WebSockets if they aren't Sockets?
Is the websocket protocol so simple to implement that it is "almost"-sockets?
I've read about WebSockets but they don't seem to be pure "sockets", because there is an application layer protocol over them.
[Is the] websocket protocol so simple to implement that [it is] "almost"-sockets?
Allowing regular socket connections directly from the browser is never going to happen because it opens up a huge risk. WebSockets is about as close to raw sockets from the browser as you are going to get. The initial WebSockets handshake is similar to an HTTP handshake (allowing web servers to proxy/bridge it) and adds CORS type security. In addition, WebSockets is a message based transport (rather than streaming as raw TCP) and this is done using a two byte header on each message frame.
Even flash is not able to quite make raw TCP connections. Flash sockets also add CORS security, but instead of an in-band handshake, flash socket connections make a connection to port 843 on the target server to request a security policy file.
Is there any way of doing a pure socket connection from a web browser, to enliven webpages?
Yes, you can use my websockify bridge/proxy which allows a WebSockets enabled browser to connect directly to a TCP socket via websockify.
But about HTML5, Why are they called WebSockets if they aren't Sockets?
WebSockets are a transport built on TCP sockets. After the handshake there is very minimal overhead (typically just a two byte header).
I can't improve on Kanaka's answers to your secondary questions, and I know this question is a year old. But for the main question, Is there any way of doing a pure socket connection from a web browser, to enliven webpages? There is a project called the Java / JavaScript Socket Bridge that might be what you (or anyone coming across this page from a Google search) are looking for. The advantage of this method over what others have mentioned is that it does not require either a client-side or a server-side service to be run. So, for instance, if you wanted to implement an IRC client purely in JavaScript but your web host does not allow you sufficient rights to proxy the connection, this Java applet would be the way to go. The only concern is making sure the client has Java installed and allowed.
You can just send data between a client and a server with WebSockets. Simply speaking, the only difference that WebSockets introduces is that the client:
adds some header bytes, like the type of data and the length
adds masks and encodes the data using them
The server also has to add header bytes, but does not need to encode the data.
If you implement the protocol correctly (server side, that is, since the browser already has an implementation), you can use it with ease to send text and binary data. (Although browser support is narrow, especially for the latter.)
The benefit of WebSocket is that it is HTTP based. You can use it also in environments there http proxies are used. Thus Websocket has a higher infrastructure compatibility as plain tcp.
Additionally http/WebSocket is providing you some features which you otherwise have to specify on your own:
Redirect
NAT keepalive
Multiplexing via URI
Framing
If you are asking for some data to be pushed from server it is widely termed as COMET or Reverse Ajax.
Web sockets is still not very popular as there are inherent firewall issues and minimal support yet from popular browsers.
You can take a look at http://www.ape-project.org/ as this is one of the most popular implementations (but native to unix/linux only for now. For windows they suggest using a virtual box or vmware based implementation)

Resources