]> granicus.if.org Git - apache/blob - docs/manual/howto/http2.xml
More s/code/module/
[apache] / docs / manual / howto / http2.xml
1 <?xml version='1.0' encoding='UTF-8' ?>
2 <!DOCTYPE manualpage SYSTEM "../style/manualpage.dtd">
3 <?xml-stylesheet type="text/xsl" href="../style/manual.en.xsl"?>
4 <!-- $LastChangedRevision$ -->
5
6 <!--
7  Licensed to the Apache Software Foundation (ASF) under one or more
8  contributor license agreements.  See the NOTICE file distributed with
9  this work for additional information regarding copyright ownership.
10  The ASF licenses this file to You under the Apache License, Version 2.0
11  (the "License"); you may not use this file except in compliance with
12  the License.  You may obtain a copy of the License at
13
14      http://www.apache.org/licenses/LICENSE-2.0
15
16  Unless required by applicable law or agreed to in writing, software
17  distributed under the License is distributed on an "AS IS" BASIS,
18  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  See the License for the specific language governing permissions and
20  limitations under the License.
21 -->
22
23 <manualpage metafile="http2.xml.meta">
24 <parentdocument href="./">How-To / Tutorials</parentdocument>
25
26   <title>HTTP/2 guide</title>
27
28   <summary>
29     <p>This is the howto guide for the HTTP/2 implementation in Apache httpd. This
30     feature is <em>experimental</em> and you may expect interfaces and directives to
31     change between releases.
32     </p>
33   </summary>
34   <seealso><module>mod_http2</module></seealso>
35
36   <section id="protocol">
37     <title>The HTTP/2 protocol</title>
38     <p>HTTP/2 is the evolution of the world's most successful application layer protocol, HTTP.
39     It focuses on making more efficient use of network resources. It does not change the fundamentals
40     of HTTP, the semantics. There are still request and responses and headers and all that. So, if
41     you already know HTTP/1, you know 95% about HTTP/2 as well.</p>
42     <p>There has been a lot written about HTTP/2 and how it works. The most normative is, of course,
43     its <a href="https://tools.ietf.org/html/rfc7540">RFC 7540</a> 
44     (<a href="http://httpwg.org/specs/rfc7540.html">also available in more readable formatting, YMMV</a>).
45     So, there you'll find the nuts and bolts.</p>
46     <p>But, as RFC do, it's not really a good thing to read first. It's better to first understand
47     <em>what</em> a thing wants to do and then read the RFC about <em>how</em> it is done. A much
48     better document to start with is <a href="https://daniel.haxx.se/http2/">http2  explained</a>
49     by Daniel Stenberg, the author of <a href="https://curl.haxx.se">curl</a>. It is available in
50     an ever growing list of languages, too!</p>
51     <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>
52     <ul>
53         <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>
54         <li><strong>h2</strong> is HTTP/2 over TLS (protocol negotiation via ALPN).</li>
55         <li><strong>h2c</strong> is HTTP/2 over TCP.</li>
56         <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 <a href="http://httpwg.org/specs/rfc7540.html#FramingLayer"> section</a>.</li>
57         <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 <a href="http://httpwg.org/specs/rfc7540.html#StreamsLayer"> section</a>.</li>
58         <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>
59     </ul>
60   </section>
61
62   <section id="implementation">
63     <title>HTTP/2 in Apache httpd</title>
64     <p>The HTTP/2 protocol is implemented by its own httpd module, aptly named
65     <module>mod_http2</module>. It implements the complete set
66     of features described by RFC 7540 and supports HTTP/2 over cleartext (http:), as
67     well as secure (https:) connections. The cleartext variant is named '<code>h2c</code>', 
68     the secure one '<code>h2</code>'. For <code>h2c</code> it allows the <em>direct</em>
69     mode and the <code>Upgrade:</code> via an initial HTTP/1 request.</p>
70     <p>One feature of HTTP/2 that offers new capabilities for web developers is
71     <a href="#push">Server Push</a>. See that section on how your web application
72     can make use of it.</p>
73   </section>
74   
75   <section id="building">
76     <title>Build httpd with HTTP/2 support</title>
77     <p><module>mod_http2</module> uses the library of <a href="https://nghttp2.org">nghttp2</a>
78     as its implementation base. In order to build <module>mod_http2</module> you need at least version 1.2.1 of
79     <code>libnghttp2</code> installed on your system.</p>
80     <p>When you <code>./configure</code> you Apache httpd source tree, you need to give it 
81     '<code>--enable-http2</code>' as additional argument to trigger the build of the module.
82     Should your <code>libnghttp2</code> reside in an unusual place (whatever that is on your
83     operating system), you may announce its location with '<code>--with-nghttp2=&lt;path&gt;</code>'
84     to <code>configure</code>.</p>
85     <p>While that should do the trick for most, they are people who might prefer a statically
86     linked <code>nghttp2</code> in this module. For those, the option <code>--enable-nghttp2-staticlib-deps</code>
87     exists. It works quite similar to how one statically links openssl to <module>mod_ssl</module>.</p>
88     <p>Speaking of SSL, you need to be aware that most browsers will speak HTTP/2 only on <code>https:</code>
89     URLs, so you need a server with SSL support. But not only that, you will need a SSL library
90     that supports the <code>ALPN</code> extension. If OpenSSL is the library you use, you need
91     at least version 1.0.2.</p>
92   </section>
93
94   <section id="basic-config">
95     <title>Basic Configuration</title>
96
97     <p>When you have a <code>httpd</code> built with <module>mod_http2</module> you need some
98     basic configuration for it becoming active. The first thing, as with every Apache module,
99     is that you need to load it:</p>
100     <highlight language="config">
101 LoadModule http2_module modules/mod_http2.so
102     </highlight>
103     
104     <p>The second directive you need to add to your server configuration is</p>
105     <highlight language="config">
106 Protocols h2 http/1.1
107 </highlight>
108     <p>This allows h2, the secure variant, to be the preferred protocol on your server
109     connections. When you want to enable all HTTP/2 variants, you simply write:</p>
110     <highlight language="config">
111 Protocols h2 h2c http/1.1
112 </highlight>
113     <p>Depending on where you put this directive, it affects all connections or just
114     the ones to a certain virtual host. You can nest it, as in:</p>
115     <highlight language="config">
116 Protocols http/1.1
117 &lt;VirtualHost ...&gt;
118     ServerName test.example.org
119     Protocols h2 http/1.1
120 &lt;/VirtualHost&gt;
121 </highlight>
122
123     <p>This allows only HTTP/1 on connections, except SSL connections to <code>test.example.org</code>
124     which offer HTTP/2.</p>
125     <note><title>Choose a strong SSLCipherSuite</title>
126     <p>The <directive module="mod_ssl">SSLCipherSuite</directive> needs to be configured with
127     a strong TLS cipher suite. The current version of <directive>mod_http2</directive> does not enforce any cipher but most
128     clients do so. Pointing a browser to a <code>h2</code> enabled server with a inappropriate
129     cipher suite will force it to simply refuse and fall back to HTTP 1.1. This is a common mistake
130     that is done while configuring httpd for HTTP/2 the first time, so please keep it in mind to avoid
131     long debugging sessions! If you want to be sure about the cipher suite to choose please avoid
132     the ones listed in the <a href="http://httpwg.org/specs/rfc7540.html#BadCipherSuites">HTTP/2 TLS blacklist</a>.</p>
133     </note>
134     <p>The order of protocols mentioned is also relevant. By default, the first one is the 
135     most preferred protocol. When a client offers multiple choices, the one most to the 
136     left is selected. In</p>
137     <highlight language="config">
138 Protocols http/1.1 h2
139 </highlight>
140     <p>the most preferred protocol is HTTP/1 and it will always be selected unless a 
141     client <em>only</em> supports h2. Since we want to talk HTTP/2 to clients that
142     support it, the better order is</p>
143     <highlight language="config">
144 Protocols h2 h2c http/1.1
145 </highlight>
146
147     <p>There is one more thing to ordering: the client has its own preferences, too. If
148     you want, you can configure your server to select the protocol most preferred by
149     the client:</p>
150     <highlight language="config">
151 ProtocolsHonorOrder Off
152     </highlight>
153     <p>makes the order <em>you</em> wrote the Protocols irrelevant and only the client's
154     ordering will decide.</p>
155     <p>A last thing: the protocols you configure are not checked for correctness
156     or spelling. You can mention protocols that do not exist, so there is no need
157     to guard <directive module="core">Protocols</directive> with any
158     <directive type="section" module="core">IfModule</directive> checks.</p>
159     <p>For more advanced tips on configuration, see the <a href="../mod/mod_http2.html#dimensioning">
160     modules section about dimensioning</a> and <a href="../mod/mod_http2.html#misdirected">
161     how to manage multiple hosts with the same certificate</a>.</p>
162   </section>
163
164   <section id="mpm-config">
165     <title>MPM Configuration</title>
166     
167     <p>HTTP/2 is supported in all multi-processing modules that come with httpd. However, if
168     you use the <module>prefork</module> mpm, there will be severe restrictions.</p>
169     <p>In <module>prefork</module>, <module>mod_http2</module> will only process one request at at time
170     per connection. But clients, such as browsers, will send many requests at the same time.
171     If one of these takes long to process (or is a long polling one), the other requests will
172     stall.</p>
173     <p><module>mod_http2</module> will not work around this limit by default. The reason is that
174     <module>prefork</module> is today only chosen, if you run processing engines that are not
175     prepared for multi-threading, e.g. will crash with more than one request.</p>
176     <p>If your setup can handle it, configuring <module>event</module> mpm is nowadays
177     the best one (if supported on your platform).</p>
178     <p>If you are really stuck with <module>prefork</module> and want multiple requests,
179     you can tweak the <directive module="mod_http2">H2MinWorkers</directive> to make
180     that possible. If it breaks, however, you own both parts.</p>
181   </section>
182   
183   <section id="clients">
184     <title>Clients</title>
185     <p>Almost all modern browsers support HTTP/2, but only over SSL connections: Firefox (v43),
186     Chrome (v45), Safari (since v9), iOS Safari (v9), Opera (v35), Chrome for Android (v49)
187     and Internet Explorer (v11 on Windows10) (<a href="http://caniuse.com/#search=http2">source</a>).</p>
188     <p>Other clients, as well as servers, are listed 
189     <a href="https://github.com/http2/http2-spec/wiki/Implementations">on the Implementations wiki</a>,
190     among them implementations for c, c++, common lisp, dart, erlang, haskell, java, nodejs,  php, 
191     python, perl, ruby, rust, scala and swift.</p>
192     <p>Several of the non-browser client implementations support HTTP/2 over cleartext, h2c. The
193     most versatile being <a href="https://curl.haxx.se">curl</a>.</p>
194   </section>
195
196   <section id="tools">
197     <title>Useful tools to debug HTTP/2</title>
198     <p>The first tool to mention is of course <a href="https://curl.haxx.se">curl</a>. Please make sure that
199     your version supports HTTP/2 checking its <code>Features</code>:</p>
200     <highlight language="config">
201     $ curl -V
202     curl 7.45.0 (x86_64-apple-darwin15.0.0) libcurl/7.45.0 OpenSSL/1.0.2d zlib/1.2.8 nghttp2/1.3.4
203     Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 [...] 
204     Features: IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP <strong>HTTP2</strong>
205     </highlight>
206     <note><title>Mac OS homebrew notes</title>
207     brew install curl --with-openssl --with-nghttp2 
208     </note>
209     <p>And for really deep inspection <a href="https://wiki.wireshark.org/HTTP2">wireshark</a>.</p>
210     <p>The <a href="https://nghttp2.org">nghttp2</a> package also includes clients, such as:</p>
211     <ul>
212         <li><a href="https://nghttp2.org/documentation/nghttp.1.html">nghttp</a> - useful to visualize the HTTP/2 frames and get a better idea of the protocol.</li>
213         <li><a href="https://nghttp2.org/documentation/h2load-howto.html">h2load</a> - useful to stress-test your server.</li>
214     </ul>
215     <p>Chrome offers detailed HTTP/2 logs on its connections via the 
216     <a href="chrome://net-internals/#http2">special net-internals page</a>. There is also an
217     interesting extension for <a href="https://chrome.google.com/webstore/detail/http2-and-spdy-indicator/mpbpobfflnpcgagjijhmgnchggcjblin?hl=en">Chrome</a>
218     and <a href="https://addons.mozilla.org/en-us/firefox/addon/spdy-indicator/">Firefox</a>
219     to visualize when your browser is using HTTP/2.</p>
220   </section>
221
222   <section id="push">
223     <title>Server Push</title>
224     <p>The HTTP/2 protocol allows the server to PUSH responses to a client it never
225     asked for. The tone of the conversation is: &quot;here is a request that you
226     never sent and the response to it will arrive soon...&quot;</p>
227     <p>But there are restrictions: the client can disable this feature and the
228     server may only ever PUSH on a request that came from the client.</p>
229     <p>The intention is to allow the server to send resources to the client that
230     it will most likely need: a css or javascript resource that belongs to a html
231     page the client requested. A set of images that is referenced by a css, etc.</p>
232     <p>The advantage for the client is that it saves the time to send the request which
233     may range from a few milliseconds to half a second, depending on where on the 
234     globe both are located. The disadvantage is that the client may get sent
235     things it already has in its cache. Sure, HTTP/2 allows for the early cancellation
236     of such requests, but still there are resources wasted.</p>
237     <p>To summarize: there is no one good strategy on how to make best use of this 
238     feature of HTTP/2 and everyone is still experimenting. So, how do you experiment
239     with it in Apache httpd?</p>
240     <p><module>mod_http2</module> inspect response header for <code>Link</code> headers
241     in a certain format:</p>
242     <highlight language="config">
243 Link &lt;/xxx.css&gt;;rel=preload, &lt;/xxx.js&gt;; rel=preload
244     </highlight>
245     <p>If the connection supports PUSH, these two resources will be sent to the
246     client. As a web developer, you may set these headers either directly in
247     your application response or you configure the server via</p>
248     <highlight language="config">
249 &lt;Location /xxx.html&gt;
250     Header add Link "&lt;/xxx.css&gt;;rel=preload"
251     Header add Link "&lt;/xxx.js&gt;;rel=preload"
252 &lt;/Location&gt;
253     </highlight>
254     <p>If you want to use <code>preload</code> links without triggering a PUSH, you
255     can use the <code>nopush</code> parameter, as in</p>
256     <highlight language="config">
257 Link &lt;/xxx.css&gt;;rel=preload;nopush
258     </highlight>
259     <p>or you may disable PUSHes for your server entirely with the directive</p>
260     <highlight language="config">
261 H2Push Off
262     </highlight>
263     <p>And there is more:</p>
264     <p>The module will keep a diary of what has been PUSHed for each connection
265     (hashes of URLs, basically) and will not PUSH the same resource twice. When
266     the connection closes, this information is discarded.</p>
267     <p>There are people thinking about how a client can tell a server what it
268     already has, so PUSHes for those things can be avoided, but this is all
269     highly experimental right now.</p>
270     <p>Another experimental draft that has been implemented in <module>mod_http2</module>
271     is the <a href="https://tools.ietf.org/html/draft-ruellan-http-accept-push-policy-00">
272     Accept-Push-Policy Header Field</a> where a client can, for each request, define
273     what kind of PUSHes it accepts.</p>
274     <p>
275     PUSH might not always trigger the request/response/performance that one expects or 
276     hopes for. There are various studies on this topic to be found on the web that explain
277     benefits and weaknesses and how different features of client and network influence
278     the outcome. For example: just because the server PUSHes a resource does not mean
279     a browser will actually use the data.</p>
280     <p>The major thing that influences the response being PUSHed is the request that was
281     simulated. The request URL for a PUSH is given by the application, but where do the
282     request headers come from? For example, will the PUSH request a <code>accept-language</code>
283     header and if yes with what value?</p>
284     <p>Apache will look at the original request (the one that triggered the PUSH) and copy the 
285     following headers over to PUSH requests: <code>user-agent</code>, <code>accept</code>, 
286     <code>accept-encoding</code>, <code>accept-language</code>, <code>cache-control</code>.</p>
287     <p>All other headers are ignored. Cookies will also not be copied over. PUSHing resources
288     that require a cookie to be present will not work. This can be a matter of debate. But 
289     unless this is more clearly discussed with browser, let's err on the side of caution and
290     not expose cookie where they might oridinarily not be visible.</p>
291   </section>
292
293   <section id="earlyhints">
294     <title>Early Hints</title>
295     <p>An alternative to PUSHing resources is to send <code>Link</code> headers to the
296     client before the response is even ready. This uses the HTTP feature called "Early Hints" and
297     is described in <a href="https://tools.ietf.org/html/rfc8297">RFC 8297</a>.</p>
298     <p>In order to use this, you need to explicitly enable it on the server via</p>
299     <highlight language="config">
300 H2EarlyHints on
301     </highlight>
302     <p>(It is not enabled by default since some older browser tripped on such responses.)</p>
303     <p>If this feature is on, you can the directive <directive module="mod_http2">H2PushResource</directive> to 
304     trigger early hints and resource PUSHes:</p>
305     <highlight language="config">
306 &lt;Location /xxx.html&gt;
307     H2PushResource /xxx.css
308     H2PushResource /xxx.js
309 &lt;/Location&gt;
310     </highlight>
311     <p>This will send out a <code>"103 Early Hints"</code> response to a client as soon
312     as the server <em>starts</em> processing the request. This may be much early than
313     the time the first response headers have been determined, depending on your web
314     application.</p>
315     <p>If <directive module="mod_http2">H2Push</directive> is enabled, this will also start the PUSH right after the
316     103 response. If <directive module="mod_http2">H2Push</directive> is disabled however, the 103 response will be send
317     nevertheless to the client.</p>
318   </section>
319   
320 </manualpage>