<title>The HTTP/2 protocol</title>
<p>HTTP/2 is the evolution of the world's most successful application layer protocol, HTTP.
It focuses on making more efficient use of network resources. It does not change the fundamentals
- of HTTP, the semantics. There are still request and responses and headers and all that. So, if
+ of HTTP, the semantics. There are still requests and responses and headers and all that. So, if
you already know HTTP/1, you know 95% about HTTP/2 as well.</p>
<p>There has been a lot written about HTTP/2 and how it works. The most normative is, of course,
its <rfc>9113</rfc> (which obsoletes the original <rfc>7540</rfc>).
There you'll find the nuts and bolts.</p>
<p>But, as RFCs do, it's not really a good thing to read first. It's better to first understand
<em>what</em> a thing wants to do and then read the RFC about <em>how</em> it is done. A much
- better document to start with is <a href="https://daniel.haxx.se/http2/">http2 explained</a>
+ better document to start with is <a href="https://daniel.haxx.se/http2/">http2 explained</a>
by Daniel Stenberg, the author of <a href="https://curl.haxx.se">curl</a>. It is available in
an ever growing list of languages, too!</p>
- <p>Too Long, Didn't read: there are some new terms and gotchas that need to be kept in mind while reading this document:</p>
+ <p>TL;DR: there are some new terms and gotchas that need to be kept in
+ mind while reading this document:</p>
<ul>
- <li>HTTP/2 is a <strong>binary protocol</strong>, as opposed to HTTP 1.1 that is plain text. The latter is meant to be human readable (for example sniffing network traffic) meanwhile the former is not. More info in the official FAQ <a href="https://http2.github.io/faq/#why-is-http2-binary">question</a>.</li>
+ <li>HTTP/2 is a <strong>binary protocol</strong>, as opposed to HTTP 1.1
+ that is plain text. The latter is meant to be human readable (for example
+ sniffing network traffic) while the former is not. More info in the official
+ FAQ <a href="https://http2.github.io/faq/#why-is-http2-binary">question</a>.</li>
<li><strong>h2</strong> is HTTP/2 over TLS (protocol negotiation via ALPN).</li>
<li><strong>h2c</strong> is HTTP/2 over TCP.</li>
- <li>A <strong>frame</strong> is the smallest unit of communication within an HTTP/2 connection, consisting of a header and a variable-length sequence of octets structured according to the frame type. More info in the official documentation <rfc>9113</rfc>.</li>
- <li>A <strong>stream</strong> is a bidirectional flow of frames within the HTTP/2 connection. The correspondent concept in HTTP 1.1 is a request/response message exchange. More info in the official documentation <rfc>9113</rfc>.</li>
- <li>HTTP/2 is able to run <strong>multiple streams</strong> of data over the same TCP connection, avoiding the classic HTTP 1.1 head-of-line blocking of slow requests and avoiding the need to re-instantiate TCP connections for each request/response (KeepAlive patched the problem in HTTP 1.1 but did not fully solve it).</li>
+ <li>A <strong>frame</strong> is the smallest unit of communication within
+ an HTTP/2 connection, consisting of a header and a variable-length sequence
+ of octets structured according to the frame type. More info in the official
+ documentation <rfc>9113</rfc>.</li>
+ <li>A <strong>stream</strong> is a bidirectional flow of frames within the
+ HTTP/2 connection. The corresponding concept in HTTP 1.1 is a request/response
+ message exchange. More info in the official documentation
+ <rfc>9113</rfc>.</li>
+ <li>HTTP/2 is able to run <strong>multiple streams</strong> of data over
+ the same TCP connection, avoiding the classic HTTP 1.1 head-of-line blocking
+ of slow requests and avoiding the need to re-instantiate TCP connections
+ for each request/response (KeepAlive patched the problem in HTTP 1.1 but
+ did not fully solve it).</li>
</ul>
</section>
well as secure (https:) connections. The cleartext variant is named '<code>h2c</code>',
the secure one '<code>h2</code>'. For <code>h2c</code> it allows the <em>direct</em>
mode and the <code>Upgrade:</code> via an initial HTTP/1 request.</p>
- <p>One feature of HTTP/2 that offers new capabilities for web developers is
- <a href="#push">Server Push</a>. See that section on how your web application
- can make use of it.</p>
+ <p>One feature of HTTP/2 that formerly offered new capabilities for web developers is
+ <a href="#push">Server Push</a>, though it is now deprecated. See the
+ <a href="#earlyhints">Early Hints</a> section for the recommended alternative.</p>
</section>
<section id="building">
to <code>configure</code>.</p>
<p>While that should do the trick for most, there are people who might prefer a statically
linked <code>nghttp2</code> in this module. For those, the option <code>--enable-nghttp2-staticlib-deps</code>
- exists. It works quite similar to how one statically links openssl to <module>mod_ssl</module>.</p>
+ exists. It works quite similarly to how one statically links openssl to <module>mod_ssl</module>.</p>
<p>Speaking of SSL, you need to be aware that most browsers will speak HTTP/2 only on <code>https:</code>
- URLs, so you need a server with SSL support. But not only that, you will need a SSL library
+ URLs, so you need a server with SSL support. But not only that, you will need an SSL library
that supports the <code>ALPN</code> extension. If OpenSSL is the library you use, you need
at least version 1.0.2.</p>
</section>
<title>Basic Configuration</title>
<p>When you have a <code>httpd</code> built with <module>mod_http2</module> you need some
- basic configuration for it becoming active. The first thing, as with every Apache module,
+ basic configuration for it becoming active. The first thing, as with every httpd module,
is that you need to load it:</p>
<highlight language="config">
LoadModule http2_module modules/mod_http2.so
<note><title>Choose a strong SSLCipherSuite</title>
<p>The <directive module="mod_ssl">SSLCipherSuite</directive> needs to be configured with
a strong TLS cipher suite. The current version of <module>mod_http2</module> does not enforce any cipher but most
- clients do so. Pointing a browser to a <code>h2</code> enabled server with a inappropriate
+ clients do so. Pointing a browser to a <code>h2</code> enabled server with an inappropriate
cipher suite will force it to simply refuse and fall back to HTTP 1.1. This is a common mistake
- that is done while configuring httpd for HTTP/2 the first time, so please keep it in mind to avoid
+ made while configuring httpd for HTTP/2 the first time, so please keep it in mind to avoid
long debugging sessions! If you want to be sure about the cipher suite to choose please avoid
the ones listed in the HTTP/2 TLS reject list (<rfc section="9.2.2">9113</rfc>).</p>
</note>
<section id="clients">
<title>Clients</title>
- <p>Almost all modern browsers support HTTP/2, but only over SSL connections: Firefox (v43),
- Chrome (v45), Safari (since v9), iOS Safari (v9), Opera (v35), Chrome for Android (v49)
- and Internet Explorer (v11 on Windows10) (<a href="http://caniuse.com/#search=http2">source</a>).</p>
+ <p>All modern browsers support HTTP/2 over TLS connections
+ (<a href="https://caniuse.com/http2">source</a>). Support has been universal across
+ major browsers since approximately 2015.</p>
<p>Other clients, as well as servers, are listed
<a href="https://github.com/http2/http2-spec/wiki/Implementations">on the Implementations wiki</a>,
among them implementations for c, c++, common lisp, dart, erlang, haskell, java, nodejs, php,
</ul>
<p>Chrome offers detailed HTTP/2 logs on its connections via the
<a href="chrome://net-internals/#http2">special net-internals page</a>. There is also an
- interesting extension for <a href="https://chrome.google.com/webstore/detail/http2-and-spdy-indicator/mpbpobfflnpcgagjijhmgnchggcjblin?hl=en">Chrome</a>
- and <a href="https://addons.mozilla.org/en-us/firefox/addon/spdy-indicator/">Firefox</a>
- to visualize when your browser is using HTTP/2.</p>
+ interesting extension for <a href="https://chromewebstore.google.com/detail/http-indicator/hgcomhbcacfkpffiphlmnlhpppcjgmbl">Chrome</a>
+ and <a href="https://addons.mozilla.org/en-US/firefox/addon/http2-indicator/">Firefox</a>
+ to indicate when your browser is using HTTP/2.</p>
</section>
<section id="push">
<p>To summarize: there is no one good strategy on how to make best use of this
feature of HTTP/2 and everyone is still experimenting. So, how do you experiment
with it in Apache httpd?</p>
- <p><module>mod_http2</module> inspect response header for <code>Link</code> headers
+ <p><module>mod_http2</module> inspects response headers for <code>Link</code> headers
in a certain format:</p>
<highlight language="config">
Link </xxx.css>;rel=preload, </xxx.js>; rel=preload
(hashes of URLs, basically) and will not PUSH the same resource twice. When
the connection closes, this information is discarded.</p>
<p>There are people thinking about how a client can tell a server what it
- already has, so PUSHes for those things can be avoided, but this is all
- highly experimental right now.</p>
- <p>Another experimental draft that has been implemented in <module>mod_http2</module>
+ already has, so PUSHes for those things can be avoided, but no standard
+ emerged before push was deprecated.</p>
+ <p>An experimental draft that was implemented in <module>mod_http2</module>
is the <a href="https://datatracker.ietf.org/doc/html/draft-ruellan-http-accept-push-policy-00">
Accept-Push-Policy Header Field</a> where a client can, for each request, define
- what kind of PUSHes it accepts.</p>
+ what kind of PUSHes it accepts. This draft expired and was never adopted.</p>
<p>
PUSH might not always trigger the request/response/performance that one expects or
hopes for. There are various studies on this topic to be found on the web that explain
<code>accept-encoding</code>, <code>accept-language</code>, <code>cache-control</code>.</p>
<p>All other headers are ignored. Cookies will also not be copied over. PUSHing resources
that require a cookie to be present will not work. This can be a matter of debate. But
- unless this is more clearly discussed with browser, let's err on the side of caution and
- not expose cookie where they might ordinarily not be visible.</p>
+ unless this is more clearly discussed with browsers, let's err on the side of caution and
+ not expose cookies where they might ordinarily not be visible.</p>
</section>
<section id="earlyhints">
</Location>
</highlight>
<p>This will send out a <code>"103 Early Hints"</code> response to a client as soon
- as the server <em>starts</em> processing the request. This may be much early than
+ as the server <em>starts</em> processing the request. This may be much earlier than
the time the first response headers have been determined, depending on your web
application.</p>
<p>If <directive module="mod_http2">H2Push</directive> is enabled, this will also start the PUSH right after the
- 103 response. If <directive module="mod_http2">H2Push</directive> is disabled however, the 103 response will be send
+ 103 response. If <directive module="mod_http2">H2Push</directive> is disabled however, the 103 response will be sent
nevertheless to the client.</p>
</section>