Introduction to HTTP 2.0
HTTP 2.0, Hypertext Transfer Protocol 2.0, is the next generation HTTP protocol. was developed by the hypertext Transfer Protocol Bis (httpbis) Working Group of the Internet Engineering Task Force (IETF). Is the first update since the release of http1.1 in 1999. HTTP 2.0 conducted its first cooperative testing in August 2013. On the Open Internet HTTP 2.0 will be used only for https://URLs, while the http://Web site will continue to use HTTP/1, with the aim of increasing the use of encryption technology on the open Internet to provide strong protection against active attacks. DANE RFC6698 allows a domain administrator to issue certificates without a third-party ca.
The IETF will allow all Internet access by default to introduce encryption, and Internet experts call the next-generation encryption Protocol "HTTP 2.0".
Protocol objectives:
- asynchronous connection multiplexing;
- Head compression;
- Request/Response pipeline;
Maintaining backward compatibility with HTTP 1.1 semantics is also a key goal of this release. Spdy is an HTTP-compliant protocol that is sponsored by Google and is supported by browsers such as Chrome, Opera, Firefox, and Amazon Silk. One of the bottlenecks of HTTP implementations is that concurrency depends on multiple connections. HTTP pipeline technology can alleviate this problem, but it can only do some multiplexing. In addition, it has been confirmed that because of intermediate interference, the browser can not adopt the pipeline technology. Spdy adds a frame layer over a single connection to multiplex multiple concurrent streams. The frame layer is optimized for the HTTP class request response stream, so applications running on HTTP can run on top of Spdy as long as the application developer has little modification or even no modification. Spdy has 4 improvements to the current HTTP protocol:
- Multiplexing request;
- Prioritize the requests;
- compressed HTTP headers;
- Server Push stream (that is, server push technology);
Spdy tries to preserve the existing semantics of HTTP, so cookies, etags, and so on are available. [3]
How to enable HTTP/2 in Apache
just released the Apache httpd 2.4.17 finally support the HTTP/2. This page gives some suggestions on how to build/deploy/configure. The idea is to upgrade it when you find bugs, or to give advice on how to work better.
Finally, this will merge back to the official Apache document, which will only leave a link to there. We haven't done it yet.
Compile Support HTTP/2
Before you compile the version, you have to make some configuration. There are thousands of options here. Related to HTTP/2 are:
Enable the ' HTTP2 ' module that implements the protocol within the Apache server.
Specifies the non-default location of the LIBNGHTTP2 module required by the HTTP2 module. If the NGHTTP2 is in the default location, the configuration process is automatically adopted.
--enable-nghttp2-staticlib-deps
Rarely used options, you may want to link the NGHTTP2 library statically to the server. On most platforms, it is only useful if you cannot find a shared NGHTTP2 library.
If you want to compile NGHTTP2 yourself, you can view the document nghttp2.org. The latest Fedora and other versions have been shipped with this library.
TLS Support
most people want to use HTTP/2 on the browser, and the browser only supports HTTP/2 when using the TLS connection (the URL at the beginning of https://). You need some of the configurations I described below. But the first thing you need is a TLS library that supports ALPN extensions.
ALPN is used to negotiate protocols between the Negotiate server and the client. If the TLS library on your server has not yet implemented ALPN, the client can only communicate through http/1.1. So what's the library that can link to and support Apache?
OpenSSL 1.0.2 and later.
??? (I don't know anything else)
If your OpenSSL library is a Linux version, the version number used here may be different from the official OpenSSL version. Check your Linux version if you are unsure.
Configuration
another good advice for the server is to set the appropriate log level for the HTTP2 module. Add the following configuration:
# in a place like this line
LoadModule http2_module modules/mod_http2.so
<ifmodule http2_module> loglevel
: Info
</IfModule>
When you start the server, you can see a similar line in the error log:
[Timestamp] [Http2:info] [PID xxxxx:tid numbers]
MOD_HTTP2 (v1.0.0, NGHTTP2 1.3.4), initializing ...
Agreement
Well, suppose you've compiled the server, the TLS library is up to date, you start your server, you open the browser ... How do you know it's working?
If you don't add other server configurations, it's probably not working.
You need to tell the server where to use the protocol. By default, your server does not start the HTTP/2 protocol. Because it's safer, you might be able to keep your existing deployments working.
You can enable the HTTP/2 protocol with the new protocols Directive:
# for HTTPS server
protocols H2 http/1.1
...
# for HTTP servers
protocols H2C http/1.1
You can add this configuration to the entire server or to the specified vhosts.
SSL parameters
for TLS (SSL), HTTP/2 has some special requirements. Read the "HTTPS://Connections" section below for more detailed information.
http://connection (H2C)
Although there is no browser support now, the HTTP/2 protocol works on URLs such as http://, and mod_h[ttp]2 supports it. Enable it all you have to do is enable it in the Protocols configuration:
# for HTTP servers
protocols H2C http/1.1
Here are some clients (and client libraries) that support H2C. I will introduce the following:
Curl
the command line client that Daniel Stenberg maintains for access to network resources curl of course support. If you have curl on your system, there is an easy way to check whether it supports HTTP/2:
sh> curl-v
Curl 7.43.0 (x86_64-apple-darwin15.0) libcurl/7.43.0 securetransport zlib/1.2.5
protocols:dict File FTP FTPS Gopher HTTP HTTPS IMAP imaps LDAP ldaps POP3 pop3s SMB rtsp SMTP SMBs telnet tftp
Smtps DNS IPv6 largefile gss-api Kerberos spnego NTLM ntlm_wb SSL libz unixsockets
It's not good. There is no ' HTTP2 ' in these functions. What you want is the following:
sh> curl-v
URL 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 Protocols:dict file ftp FTPs Gopher HTTP HTTPS IMAP imaps LDAP ldaps POP3 pop3s rtsp SMB SMBs SMTP Smtps telnet tftp
Features:ipv6 largefile NTLM ntlm_wb SSL libz tls-srp HTTP2 unixsockets
If your curl supports HTTP2 features, you can check your server with a few simple commands:
sh> curl-v--http2 http://<yourserver>/
...
> Connection:upgrade, http2-settings
> UPGRADE:H2C
> Http2-settings:aamaaabkaaqaap__
>
< http/1.1 switching Protocols
< UPGRADE:H2C
< connection:upgrade
* Received *
U Sing HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed) ...
<the resource>
Congratulations, if you see a ... Switching ... Line means it's working!
There are some situations that do not occur HTTP/2 upgrade switching upgrade. If your first request has a request data body, such as when you upload a file, it does not trigger an escalation switch. The H2C Limit section is explained in detail.
Nghttp
NGHTTP2 can compile its own clients and servers together. If you have the client in your system, you can simply verify your installation by obtaining a resource:
sh> nghttp-uv http://<yourserver>/
[0.001] Connected
[0.001] http Upgrade request
...
Connection:upgrade, http2-settings
upgrade:h2c
http2-settings:aamaaabkaaqaap__
...
[0.005] HTTP Upgrade response http/1.1-switching protocols upgrade:h2c connection:upgrade
[ 0.006] HTTP Upgrade success ...
This is similar to the Upgrade output we see in the curl example above.
There is another way to use H2C in command line arguments without the-u parameter. This parameter instructs the nghttp to perform the HTTP/1 upgrade switch process. But what if we don't use it?
sh> nghttp-v http://<yourserver>/
[0.002] Connected
[0.002] send SETTINGS frame
...
[0.002] Send HEADERS frame
; End_stream | End_headers | PRIORITY
(padlen=0, dep_stream_id=11, weight=16, exclusive=0)
; Open New stream
: Method:get
:p ath:/
: Scheme:http
...
The connection immediately uses the http/2! This is what the protocol calls direct directly mode, which occurs when a client sends some special 24 bytes to the server:
0x505249202a20485454502f322e300d0a0d0a534d0d0a0d0a
In ASCII notation is:
PRI * http/2.0\r\n\r\nsm\r\n\r\n
Servers that support H2C see this information in a new connection and immediately switch to HTTP/2. The http/1.1 server is considered a ludicrous request, responding and shutting down the connection.
Therefore, direct mode is only suitable for those clients that determine that the server supports HTTP/2. For example, when the current upgrade switch process succeeds.
The charm of direct mode is 0 overhead, and it supports all requests, even with the Request Data section (view H2C restrictions).
For 2.4.17 versions, H2direct is enabled by default on plaintext connections. But there are some modules that are incompatible with this. Therefore, the default is set to off in the next release, and if you want your server to support it, you need to set it as:
H2direct on
https://connection (H2)
When your mod_h[ttp]2 can support H2C connections, you can enable the H2 brothers together, now browsers only support it and https: use together.
The HTTP/2 standard adds some additional requirements to https: (TLS) connections. The ALNP extension has been mentioned above. Another requirement is that you cannot use cryptographic algorithms in a specific blacklist.
Although the current version of MOD_H[TTP]2 does not enhance these algorithms (which may later), most clients do so. If your browser uses an inappropriate algorithm to open the H2 server, you will see an ambiguous warning inadequate_security that the browser will reject the connection.
A viable Apache SSL configuration is similar:
Sslciphersuite ecdhe-rsa-aes128-gcm-sha256:ecdhe-ecdsa-aes128-gcm-sha256:ecdhe-rsa-aes256-gcm-sha384: ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:KEDH+AESGCM: Ecdhe-rsa-aes128-sha256:ecdhe-ecdsa-aes128-sha256:ecdhe-rsa-aes128-sha:ecdhe-ecdsa-aes128-sha: Ecdhe-rsa-aes256-sha384:ecdhe-ecdsa-aes256-sha384:ecdhe-rsa-aes256-sha:ecdhe-ecdsa-aes256-sha:d He-rsa-aes128-sha256:dhe-rsa-aes128-sha:dhe-dss-aes128-sha256:dhe-rsa-aes256-sha256:dhe-dss-aes256-sha:d he-rsa-aes256-sha:!anull:!enull:! export:! Des:! rc4:!3des:! md5:! PSK
sslprotocol all-sslv2-sslv3
...
(yes, it's really long.) )
There are also some SSL configuration parameters that should be adjusted, but not necessarily adjusted: Sslsessioncache, sslusestapling, etc., are also introduced elsewhere. For example, Ilya Grigorik wrote an awesome blog: a high-performance browser network.
Curl
return to the shell using curl (see the "Curl H2C" section above to understand the requirements), you can also use the curl to detect your server with simple commands:
sh> curl-v--http2 https://<yourserver>/
...
* ALPN, offering H2
* ALPN, offering http/1.1
...
* ALPN, Server accepted to use H2 ...
<the resource>
Congratulations, you can work! If not, the possible causes are:
Your curl don't support HTTP/2. See the "Detecting Curl" section above.
Your OpenSSL version is too low to support ALPN.
You cannot verify your certificate, or do not accept your algorithm configuration. Try adding command-line option-K to deactivate these checks in curl. If you can work, reconfigure your SSL and certificates.
nghttp
we've talked about nghttp in H2C. If you use it for https: Connect, you will see information similar to the following:
sh> nghttp https://<yourserver>/
[ERROR] HTTP/2 protocol is not selected. (NGHTTP2 expects H2)
There are two possibilities that you can check by adding-V. If it is:
sh> nghttp-v https://<yourserver>/
[0.034] Connected
[ERROR] HTTP/2 protocol is not selected. (NGHTTP2 expects H2)
This means that your server uses a TLS library that does not implement ALPN. Sometimes it's difficult to install properly. See more StackOverflow.
What you see may also be:
sh> nghttp-v https://<yourserver>/
[0.034] Connected the negotiated
protocol:http/1.1
[ERROR] HTTP/2 protocol is not selected. (NGHTTP2 expects H2)
This means that ALPN can work correctly, but it does not use the H2 protocol. You need to check the protocols configuration on your server as described above. If the first part of the vhost is not working properly, try setting it in the generic section.
Firefox
You can open the Developer tool in the Firefox browser and view the HTTP/2 connection in the Web tab there. When you open the HTTP/2 and refresh the HTML page, you will see something similar to the following:
In the response header, you can see "H2" listed in the strange X-firefox-spdy entry. This means that HTTP/2 is used in this https: connection.
Google Chrome
in Google Chrome, you don't see the HTTP/2 indicator in the developer tool. Instead, Chrome uses a special address chrome://net-internals/#http2 gives the information. (LCTT: Chrome already has a "HTTP/2 and SPDY indicator" can be very good in the address bar to identify HTTP/2 connection)
If you open a server page, you can view the Net-internals page in Chrome, and you can see something like this:
If your server is in the list above, it means it is working.
Microsoft Edge
the successor Edge of Internet Explorer in Windows 10 also supports HTTP/2. You can also see the HTTP/2 protocol on the Web tab of the developer tool.
Safari
in Apple Safari, open the Developer tool, where there is a web tab. Reload the page on your server and select the line in the developer tool that shows the load. If you enable the display of detailed views on the right, see the Status section. There showed the http/2.0 200, like this:
Re-negotiation
https: Connection renegotiation refers to a change in a specific TLS parameter in a running connection. In the Apache httpd, you can change the TLS parameter in your directory configuration. If you enter a request to obtain a specific location resource, the configured TLS parameter is compared to the current TLS parameter. If they are not the same, a renegotiation is triggered.
The most common scenario is algorithmic change and client certificates. You can ask customers to access specific locations with validation, or for specific resources, you can use more secure, more CPU-pressure algorithms.
But no matter how good your ideas are, HTTP/2 can never happen again. There will be more than 100 requests on the same connection, so when do you renegotiate?
For this configuration, there is no way to mod_h[ttp]2 the existing ones. If you have a site that uses TLS to renegotiate, do not enable h2! on the above
Of course, we'll fix this in later versions, and then you'll be able to enable it safely.
Limit
Non-HTTP protocol
modules that implement protocols other than HTTP may not be compatible with MOD_HTTP2. This will undoubtedly occur when other protocols require the server to send data first.
NNTP is an example of such a protocol. If you have Mod_nntp_like_ssl configured on the server, do not load MOD_HTTP2. Wait for the next version.
H2C limit
There are some limitations to the implementation of H2C, you should note:
Reject H2C in the virtual host
You cannot deny H2C direct connection to a specified virtual host. A connection is established without the request triggering a direct link, which makes it impossible to know in advance which virtual host the Apache needs to look for.
Upgrade switch when request data is available
for requests with data, the H2C upgrade switch does not work properly. Those are put and POST requests (for submission and upload). If you write a client, you may use a simple get or OPTIONS * to handle those requests to trigger an upgrade switch.
The reason is obvious from a technical point of view, but if you want to know: In the upgrade switch process, the connection is in a half crazy state. The request is in http/1.1 format, and the response uses the HTTP/2 frame. If the request has a data portion, the server needs to read the entire data before sending the response. Because the response may need to be answered from the client for flow control and other things. However, if the http/1.1 request is still being sent, the client will still not be able to connect HTTP/2.
In order for the behavior to be predictable, several servers on the implementation decide not to upgrade in any request with request data, even if the request data is small.
302-Time Upgrade switch
When a redirect occurs, the current H2C upgrade does not work. It looks like the rewrite before MOD_HTTP2 could happen. This is certainly not going to lead to a break, but you might be puzzled if you test such a site.
H2 limit
Here are some H2 implementation restrictions you should be aware of:
Connection Reuse
The HTTP/2 protocol allows you to reuse TLS connections under certain conditions: If you have a certificate with wildcards or multiple altsubject names, the browser may reuse existing connections. For example:
You have a a.example.org certificate, and it has another name b.example.org. You open the URL https://a.example.org/in the browser and load the https://b.example.org/with another tab page.
Before reopening a new connection, the browser sees that it has a connection to a.example.org and the certificate is also available for b.example.org. Therefore, it sends a second label page request above the first connection.
This connection reuse is deliberately designed to allow sites that use the HTTP/1 segmentation sharding to improve efficiency without requiring too much change to take advantage of HTTP/2.
Apache Mod_h[ttp]2 has not yet fully achieved this. If a.example.org and b.example.org are different virtual hosts, Apache will not allow such connections to be reused and will inform the browser status code 421 misdirected Request. The browser will realize that it needs to reopen a connection to the b.example.org. This can still work, but it will reduce some efficiency.