Sunteți pe pagina 1din 12

HTTP/2 guide - Apache HTTP Server Version 2.4 about:reader?url=https://httpd.apache.org/docs...

httpd.apache.org

HTTP/2 guide - Apache HTTP


Server Version 2.4
13-17 minutes

Available Languages:  en  |  es  |  fr 

This is the howto guide for the HTTP/2 implementation in


Apache httpd. This feature is production-ready and you may
expect interfaces and directives to remain consistent
releases.

The HTTP/2 protocol

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 you
already know HTTP/1, you know 95% about HTTP/2 as well.

There has been a lot written about HTTP/2 and how it


works. The most normative is, of course, its RFC 7540 (also
available in more readable formatting, YMMV). So, there
you'll find the nuts and bolts.

But, as RFC do, it's not really a good thing to read first. It's

1 of 12 12/4/18, 9:44 AM
HTTP/2 guide - Apache HTTP Server Version 2.4 about:reader?url=https://httpd.apache.org/docs...

better to first understand what a thing wants to do and then


read the RFC about how it is done. A much better document
to start with is http2 explained by Daniel Stenberg, the
author of curl. It is available in an ever growing list of
languages, too!

Too Long, Didn't read: there are some new terms and
gotchas that need to be kept in mind while reading this
document:

HTTP/2 is a binary protocol, 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 question.

h2 is HTTP/2 over TLS (protocol negotiation via ALPN).

h2c is HTTP/2 over TCP.

A frame 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 section.

A stream 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 section.

HTTP/2 is able to run multiple streams 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).

2 of 12 12/4/18, 9:44 AM
HTTP/2 guide - Apache HTTP Server Version 2.4 about:reader?url=https://httpd.apache.org/docs...

HTTP/2 in Apache httpd

The HTTP/2 protocol is implemented by its own httpd


module, aptly named mod_http2. It implements the
complete set of features described by RFC 7540 and
supports HTTP/2 over cleartext (http:), as well as secure
(https:) connections. The cleartext variant is named 'h2c',
the secure one 'h2'. For h2c it allows the direct mode and
the Upgrade: via an initial HTTP/1 request.

One feature of HTTP/2 that offers new capabilities for web


developers is Server Push. See that section on how your
web application can make use of it.

Build httpd with HTTP/2 support

mod_http2 uses the library of nghttp2 as its


implementation base. In order to build mod_http2 you
need at least version 1.2.1 of libnghttp2 installed on your
system.

When you ./configure you Apache httpd source tree,


you need to give it '--enable-http2' as additional
argument to trigger the build of the module. Should your
libnghttp2 reside in an unusual place (whatever that is
on your operating system), you may announce its location
with '--with-nghttp2=<path>' to configure.

While that should do the trick for most, they are people who
might prefer a statically linked nghttp2 in this module. For

3 of 12 12/4/18, 9:44 AM
HTTP/2 guide - Apache HTTP Server Version 2.4 about:reader?url=https://httpd.apache.org/docs...

those, the option --enable-nghttp2-staticlib-deps


exists. It works quite similar to how one statically links
openssl to mod_ssl.

Speaking of SSL, you need to be aware that most browsers


will speak HTTP/2 only on https: URLs, so you need a
server with SSL support. But not only that, you will need a
SSL library that supports the ALPN extension. If OpenSSL is
the library you use, you need at least version 1.0.2.

Basic Configuration

When you have a httpd built with mod_http2 you need


some basic configuration for it becoming active. The first
thing, as with every Apache module, is that you need to load
it:

LoadModule http2_module modules/mod_http2.so

The second directive you need to add to your server


configuration is
Protocols h2 http/1.1

This allows h2, the secure variant, to be the preferred


protocol on your server connections. When you want to
enable all HTTP/2 variants, you simply write:

Protocols h2 h2c http/1.1

Depending on where you put this directive, it affects all


connections or just the ones to a certain virtual host. You
can nest it, as in:

4 of 12 12/4/18, 9:44 AM
HTTP/2 guide - Apache HTTP Server Version 2.4 about:reader?url=https://httpd.apache.org/docs...

Protocols http/1.1
<VirtualHost ...>
ServerName test.example.org
Protocols h2 http/1.1
</VirtualHost>

This allows only HTTP/1 on connections, except SSL


connections to test.example.org which offer HTTP/2.

Choose a strong SSLCipherSuite

The SSLCipherSuite needs to be configured with a


strong TLS cipher suite. The current version of mod_http2
does not enforce any cipher but most clients do so. Pointing
a browser to a h2 enabled server with a 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 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 blacklist.

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 left is
selected. In

Protocols http/1.1 h2

the most preferred protocol is HTTP/1 and it will always be


selected unless a client only supports h2. Since we want to
talk HTTP/2 to clients that support it, the better order is

5 of 12 12/4/18, 9:44 AM
HTTP/2 guide - Apache HTTP Server Version 2.4 about:reader?url=https://httpd.apache.org/docs...

Protocols h2 h2c http/1.1

There is one more thing to ordering: the client has its own
preferences, too. If you want, you can configure your server
to select the protocol most preferred by the client:

ProtocolsHonorOrder Off

makes the order you wrote the Protocols irrelevant and only
the client's ordering will decide.

A last thing: the protocols you configure are not checked for
correctness or spelling. You can mention protocols that do
not exist, so there is no need to guard Protocols with any
<IfModule> checks.

For more advanced tips on configuration, see the modules


section about dimensioning and how to manage multiple
hosts with the same certificate.

MPM Configuration

HTTP/2 is supported in all multi-processing modules that


come with httpd. However, if you use the prefork mpm,
there will be severe restrictions.

In prefork, mod_http2 will only process one request at at


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.

mod_http2 will not work around this limit by default. The


reason is that prefork is today only chosen, if you run

6 of 12 12/4/18, 9:44 AM
HTTP/2 guide - Apache HTTP Server Version 2.4 about:reader?url=https://httpd.apache.org/docs...

processing engines that are not prepared for multi-


threading, e.g. will crash with more than one request.

If your setup can handle it, configuring event mpm is


nowadays the best one (if supported on your platform).

If you are really stuck with prefork and want multiple


requests, you can tweak the H2MinWorkers to make that
possible. If it breaks, however, you own both parts.

Clients

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) (source).

Other clients, as well as servers, are listed on the


Implementations wiki, among them implementations for c,
c++, common lisp, dart, erlang, haskell, java, nodejs, php,
python, perl, ruby, rust, scala and swift.

Several of the non-browser client implementations support


HTTP/2 over cleartext, h2c. The most versatile being curl.

Useful tools to debug HTTP/2

The first tool to mention is of course curl. Please make sure


that your version supports HTTP/2 checking its Features:

$ curl -V
curl 7.45.0 (x86_64-apple-darwin15.0.0)

7 of 12 12/4/18, 9:44 AM
HTTP/2 guide - Apache HTTP Server Version 2.4 about:reader?url=https://httpd.apache.org/docs...

libcurl/7.45.0 OpenSSL/1.0.2d zlib/1.2.8


nghttp2/1.3.4
Protocols: dict file ftp ftps gopher
http https imap imaps ldap ldaps pop3 [...]
Features: IPv6 Largefile NTLM NTLM_WB
SSL libz TLS-SRP HTTP2

Mac OS homebrew notes

brew install curl --with-openssl --with-nghttp2

And for really deep inspection wireshark.

The nghttp2 package also includes clients, such as:

nghttp - useful to visualize the HTTP/2 frames and get a


better idea of the protocol.

h2load - useful to stress-test your server.

Chrome offers detailed HTTP/2 logs on its connections via


the special net-internals page. There is also an interesting
extension for Chrome and Firefox to visualize when your
browser is using HTTP/2.

Server Push

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..."

But there are restrictions: the client can disable this feature

8 of 12 12/4/18, 9:44 AM
HTTP/2 guide - Apache HTTP Server Version 2.4 about:reader?url=https://httpd.apache.org/docs...

and the server may only ever PUSH on a request that came
from the client.

The intention is to allow the server to send resources to the


client that it will most likely need: a css or javascript
resource that belongs to a html page the client requested. A
set of images that is referenced by a css, etc.

The advantage for the client is that it saves the time to send
the request which may range from a few milliseconds to half
a second, depending on where on the globe both are
located. The disadvantage is that the client may get sent
things it already has in its cache. Sure, HTTP/2 allows for
the early cancellation of such requests, but still there are
resources wasted.

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?

mod_http2 inspect response header for Link headers in a


certain format:
Link </xxx.css>;rel=preload, </xxx.js>;
rel=preload

If the connection supports PUSH, these two resources will


be sent to the client. As a web developer, you may set these
headers either directly in your application response or you
configure the server via
<Location /xxx.html>
Header add Link "</xxx.css>;rel=preload"

9 of 12 12/4/18, 9:44 AM
HTTP/2 guide - Apache HTTP Server Version 2.4 about:reader?url=https://httpd.apache.org/docs...

Header add Link "</xxx.js>;rel=preload"


</Location>

If you want to use preload links without triggering a PUSH,


you can use the nopush parameter, as in

Link </xxx.css>;rel=preload;nopush

or you may disable PUSHes for your server entirely with the
directive
H2Push Off

And there is more:

The module will keep a diary of what has been PUSHed for
each connection (hashes of URLs, basically) and will not
PUSH the same resource twice. When the connection
closes, this information is discarded.

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.

Another experimental draft that has been implemented in


mod_http2 is the Accept-Push-Policy Header Field where
a client can, for each request, define what kind of PUSHes it
accepts.

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 benefits and weaknesses and how different features
of client and network influence the outcome. For example:
just because the server PUSHes a resource does not mean

10 of 12 12/4/18, 9:44 AM
HTTP/2 guide - Apache HTTP Server Version 2.4 about:reader?url=https://httpd.apache.org/docs...

a browser will actually use the data.

The major thing that influences the response being PUSHed


is the request that was simulated. The request URL for a
PUSH is given by the application, but where do the request
headers come from? For example, will the PUSH request a
accept-language header and if yes with what value?

Apache will look at the original request (the one that


triggered the PUSH) and copy the following headers over to
PUSH requests: user-agent, accept, accept-
encoding, accept-language, cache-control.

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 oridinarily not be visible.

Early Hints

An alternative to PUSHing resources is to send Link


headers to the client before the response is even ready. This
uses the HTTP feature called "Early Hints" and is described
in RFC 8297.

In order to use this, you need to explicitly enable it on the


server via

H2EarlyHints on

(It is not enabled by default since some older browser

11 of 12 12/4/18, 9:44 AM
HTTP/2 guide - Apache HTTP Server Version 2.4 about:reader?url=https://httpd.apache.org/docs...

tripped on such responses.)

If this feature is on, you can use the directive


H2PushResource to trigger early hints and resource
PUSHes:

<Location /xxx.html>
H2PushResource /xxx.css
H2PushResource /xxx.js
</Location>

This will send out a "103 Early Hints" response to a


client as soon as the server starts processing the request.
This may be much early than the time the first response
headers have been determined, depending on your web
application.

If H2Push is enabled, this will also start the PUSH right after
the 103 response. If H2Push is disabled however, the 103
response will be send nevertheless to the client.

12 of 12 12/4/18, 9:44 AM

S-ar putea să vă placă și