<summary>
<p>This is the howto guide for the HTTP/2 implementation in Apache httpd. This
feature is <em>production-ready</em> and you may expect interfaces and directives to
- remain consistent releases.
+ remain consistent across releases.
</p>
</summary>
<seealso><module>mod_http2</module></seealso>
of HTTP, the semantics. There are still request 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>7540</rfc>
- (also available in more readable formatting, YMMV (<rfc>7540</rfc>)).
- So, there you'll find the nuts and bolts.</p>
- <p>But, as RFC do, it's not really a good thing to read first. It's better to first understand
+ 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>
by Daniel Stenberg, the author of <a href="https://curl.haxx.se">curl</a>. It is available in
<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><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>7540</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>7540</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 blocking slow request and avoiding 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 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>
</ul>
</section>
<title>HTTP/2 in Apache httpd</title>
<p>The HTTP/2 protocol is implemented by its own httpd module, aptly named
<module>mod_http2</module>. It implements the complete set
- of features described by RFC 7540 and supports HTTP/2 over cleartext (http:), as
+ of features described by RFC 9113 and supports HTTP/2 over cleartext (http:), as
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>
Should your <code>libnghttp2</code> reside in an unusual place (whatever that is on your
operating system), you may announce its location with '<code>--with-nghttp2=<path></code>'
to <code>configure</code>.</p>
- <p>While that should do the trick for most, they are people who might prefer a statically
+ <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>
<p>Speaking of SSL, you need to be aware that most browsers will speak HTTP/2 only on <code>https:</code>
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
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>7540</rfc>).</p>
+ the ones listed in the HTTP/2 TLS reject list (<rfc section="9.2.2">9113</rfc>).</p>
</note>
<p>The order of protocols mentioned is also relevant. By default, the first one is the
most preferred protocol. When a client offers multiple choices, the one most to the
<p>HTTP/2 is supported in all multi-processing modules that come with httpd. However, if
you use the <module>prefork</module> mpm, there will be severe restrictions.</p>
- <p>In <module>prefork</module>, <module>mod_http2</module> will only process one request at at time
+ <p>In <module>prefork</module>, <module>mod_http2</module> will only process one request at a time
per connection. But clients, such as browsers, will send many requests at the same time.
If one of these takes long to process (or is a long polling one), the other requests will
stall.</p>
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 [...]
Features: IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP <strong>HTTP2</strong>
</highlight>
- <note><title>Mac OS homebrew notes</title>
- brew install curl --with-openssl --with-nghttp2
+ <note><title>macOS Homebrew notes</title>
+ <p>Homebrew's <code>curl</code> includes HTTP/2 support by default. Install with
+ <code>brew install curl</code> and follow the displayed caveats to put it ahead
+ of the system curl in your PATH.</p>
</note>
<p>And for really deep inspection <a href="https://wiki.wireshark.org/HTTP2">wireshark</a>.</p>
<p>The <a href="https://nghttp2.org">nghttp2</a> package also includes clients, such as:</p>
<section id="push">
<title>Server Push</title>
+ <note type="warning"><title>Deprecation Notice</title>
+ <p>Server Push is deprecated in <rfc section="8.4">9113</rfc>. Major browsers
+ (Chrome 106+, Edge 106+) have removed support for it. While <module>mod_http2</module>
+ still implements push, new deployments should use <a href="#earlyhints">103 Early Hints</a>
+ instead as a more reliable way to inform clients about needed resources.</p>
+ </note>
<p>The HTTP/2 protocol allows the server to PUSH responses to a client it never
asked for. The tone of the conversation is: "here is a request that you
never sent and the response to it will arrive soon..."</p>