Announcing an Early Alpha Patch for HTTP/2

Today, we are pleased to share the first version of an early alpha-level patch that enables HTTP/2 support in NGINX.

Editor – HTTP/2 is fully supported in NGINX 1.9.5 and later, and NGINX Plus R7 and later. The patch described in this post is no longer necessary, but is provided for the convenience of customers using NGINX versions 1.9.0 through 1.9.4.

How NGINX Supports HTTP/2

HTTP/2 is new, which means there is quite a bit of fear and misunderstanding around it. One of the biggest fears is that supporting HTTP/2 requires rearchitecting the entire application. That fear, and many of the others around HTTP/2, are unfounded. With NGINX, HTTP/2 can be supported with very little change to application architecture.

NGINX acts as an “HTTP/2 gateway” to ease the transition to the new protocol. On the front end, NGINX talks HTTP/2 to client web browsers that support it, and on the back end it talks HTTP/1.x (or FastCGI, uwsgi, SCGI) just as before. In between, NGINX translates between HTTP/2 and HTTP/1.x (or FastCGI, etc). This means that servers and applications proxied by NGINX will be unaffected by the move to HTTP/2, and don’t really even need to know that their clients are using HTTP/2. The only configuration change you need to make to your existing HTTPS setup is adding http2 to existing listen directives (the ssl parameter is also required):

listen 443 ssl http2 default_server;

As of June 2015, over 50% of users run web browsers that support HTTP/2. The adoption of HTTP/2 by web browsers is strong and will continue to increase over time. To support both HTTP/1.x and HTTP/2 side by side, NGINX implements the Application Layer Protocol Negotiation (ALPN) extension to TLS. When a web browser connects to a server, it sends a list of the protocols it supports. If h2 is in the list, NGINX uses HTTP/2 for that connection. If the browser doesn’t implement ALPN or doesn’t include h2 in its list of supported protocols, NGINX falls back to HTTP/1.x.

As you might be aware, there are a number of HTTP/1.x optimizations that are now “anti-patterns” with HTTP/2. Optimizations such as image spriting, concatenation, inlining, and domain sharding that helped performance with HTTP/1.x are no longer needed with HTTP/2. You can adopt HTTP/2 even if you use these optimizations, but we recommend that you remove them eventually to maximize performance with HTTP/2.

Installing the HTTP/2 Patch

Editor – HTTP/2 is fully supported in NGINX 1.9.5 and later, and NGINX Plus R7 and later. These instructions are no longer necessary, but are provided for the convenience of customers running NGINX versions 1.9.0 through 1.9.4.

  1. Install OpenSSL 1.0.2 or later. This is required to support the ALPN extension to TLS that our HTTP/2 implementation uses.

  2. Download and unpack the source code for an NGINX version between 1.9.0 and 1.9.4, if necessary. The example is for NGINX 1.9.3.

    # wget http://nginx.org/download/nginx-1.9.3.tar.gz
    # tar zxvf nginx-1.9.3.tar.gz
    # cd nginx-1.9.3
  3. Download the patch.

    [Editor – The patch is now available at http://nginx.org/patches/attic/http2/.]

    # wget http://nginx.org/patches/http2/patch.http2.txt
  4. Do a dry run to make sure the patch will be applied cleanly.

    # patch -p1 --dry-run < patch.http2.txt

    If no errors are reported, apply the patch.

    # patch -p1 < patch.http2.txt
  5. Recompile NGINX, including the following options along with the others you normally include.

    • If you are building NGINX with OpenSSL from source and statically linking to it:

      # ./configure --with-http_ssl_module \
      --with-http_v2_module \
      --with-debug \
      --with-openssl=/path/to/openssl-1.0.2 \
      ...
    • If OpenSSL is installed as an optional library (as on Mac OS X, for example):

      # ./configure --with-http_ssl_module \
      --with-http_v2_module \
      --with-debug \
      --with-cc-opt="-I/opt/local/include" \
      --with-ld-opt="-L/opt/local/lib" \
      ...
  6. Build NGINX.

    # make

Configuring NGINX

To enable HTTP/2 support, simply add the ssl and http2 parameters to existing listen directives:

server {
listen 443 ssl http2 default_server;

ssl_certificate     server.crt;
ssl_certificate_key server.key;
...
}


Note: The ssl parameter is required. At the time of this writing HTTP/2 is not supported without SSL encryption by browsers.

A good way to verify that HTTP/2 translation is working is the HTTP/2 and SPDY indicator plug-in for Google Chrome. The same plug-in is also available for Firefox.

Caveats

As with any early release software, there are a few caveats:

  • It is important to note that the patch is at an early alpha level of quality and should not be used in production. We are still actively working on bringing our HTTP/2 implementation to production quality. We would very much appreciate your help in achieving NGINX Inc.’s standards for reliability and performance by testing this alpha in nonproduction environments and sending feedback to the nginx-devel mailing list.
  • HTTP/2’s ‘Server Push’ feature is not supported in this patch and will not be supported in the first production-ready release of the HTTP/2 implementation. This feature might appear in a future NGINX release.
  • Applying this patch removes the SPDY module from the NGINX codebase and replaces it with the HTTP/2 module. After applying this patch, you can no longer configure NGINX to use SPDY. This will also be the case for the production-ready release of the HTTP/2 implementation in both NGINX and NGINX Plus. SPDY is being deprecated by Google in early 2016, so there is no need to support both.

Special Thanks

NGINX, Inc. would like to thank Dropbox and Automattic, who are heavy users of our software and graciously cosponsored the development of our HTTP/2 implementation. Their contributions have helped accelerate our ability to bring this software to you, and we hope you are able to support them in turn.

Infrastructure as Code
Get the latest on Microservices Design & Deployment