How does browser know which version of HTTP it should use when sending a request?

When a browser sends a request to a server for the first time, how does it decide which version of HTTP it should apply? The HTTP RFC specification says:

An HTTP client SHOULD send a request version equal to the highest version for which the client is at least conditionally compliant

But from my experiment in Chrome inspector, Chrome uses HTTP 2 when sending request to some websites, but it uses HTTP 1.1 as well in other cases.

I wonder how Chrome knows what version of HTTP request it should use? I know the server should respond with the highest version of HTTP it supports, so does Chrome send the very first request to each website with http2 by default, then save the HTTP version the website supports and uses that version ever after?

Any explanation would be apprecaited.

1

1 Answer

HTTP/1.x

Both HTTP/1.1 and HTTP/1.0 use compatible request formats. After the first request, the server's response will indicate the version it supports, plus headers such as "Connection: keep-alive" indicating which features may be used.

HTTP/2

Browsers have decided to only support HTTP/2 over a TLS connection. This allows them to use a new TLS feature called ALPN (application-layer protocol negotiation).

When Chrome establishes the TLS connection, it sends a list of supported protocols (http/1.1 and h2) as part of the TLS handshake, and the server responds with the one it wishes to use – e.g. "h2" indicating that it's now expecting HTTP/2.

In case the server doesn't return an ALPN extension at all, the browser assumes that it only supports HTTP/1.x. (This is the reason why enabling HTTP/2 support on servers used to require upgrading OpenSSL.)


The HTTP/2 protocol itself does support being used over a plaintext connection by using the HTTP Upgrade mechanism. In most cases, the first request has to be HTTP/1.1, with an Upgrade: header again listing protocols that the client wants to switch to.

The response will also be HTTP/1.1, either "101 Switching Protocols" indicating that the server now expects HTTP/2 on the same connections, or something else indicating that HTTP/2 isn't supported.

Browsers do not use HTTP Upgrade in this way, they simply don't support HTTP/2 without TLS. (However, the Apache HTTPD webserver can be configured to accept 'h2c' connections for testing.)

HTTP/3

HTTP/3 uses a different transport protocol (QUIC vs TCP), so an inline upgrade is not possible. The browser doesn't know whether the server might support QUIC, so it still makes an initial TCP connection and negotiates HTTP/1.1 vs HTTP/2 using TLS ALPN as above.

The upgrade to HTTP/3 is actually server-initiated – in its HTTP resposes the server sends the Alt-Svc header (or a special ALTSVC frame in HTTP/2) indicating that it supports HTTP/3 on the specified UDP/QUIC port. The browser might follow that suggestion and try to establish a QUIC connection, and if successful closes the TCP one.

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like