17

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

2 Answers 2

24

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.

1
  • Absolutely fantastic answer. Dec 6, 2022 at 1:34
3

I would like to expand on the u1686_grawity's answer.

How can browsers make the first request using HTTP/3?

In 2020 a new internet standard draft has been published, that defines a way for browsers to decide what HTTP version to use even for the first request.

This way is using the new HTTPS and SVCB DNS record types.

Example

An entry like:

example.com 3600 IN HTTPS 1 . alpn=”h3,h2”

...advertises the support for the HTTP/3 and HTTP/2 protocols for the example.com origin.

Additionally SVCB DNS records can make the browser need to do just one DNS query to learn both the protocol as well as the target IP(s). You can read more about it in Cloudflare's blog post.

Browsers support

The browsers supporting these entries are:

  • Chrome, since v102 (released in May 2022),
  • Firefox, since v92 (released in July 2021),
  • Safari, since v14 (released in September 2020), but as of Safari 17.2 (December 2023) the HTTP/3 support as a whole is under an "experimental" flag in this browser and is enabled only for ~50% of users at a time.

More information

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .