SPDY is a protocol designed by Google that aims to fix HTTP/1.1 protocol weaknesses and to adapt this 14 year old protocol to today’s internet devices and requirements. Back in 1999, when HTTP/1.1 was designed, there were no mobile devices, the web pages were composed by HTML with a few images, almost no javascript and no CSS. The ISP delivered internet over very slow connections.


HTTP/2.0 has to address today’s and tomorrow’s need when much more devices can browse the internet from very different types of connections (very slow with high packet loss or very fast ones) and more and more people want multimedia content and interactivity. Websites became “web applications”.

Note

SPDY is not HTTP 2.0! But HTTP 2.0 will use SPDY as a basement.

Note that as long as HTTP/2.0 has not been released officially, ALL articles written on SPDYNPNALPN, etc may be outdated at some point. Sadly, this is true for the present article, BUT I’ll try to keep it up to date.


As an example, NPN is a TLS extension that has been designed to allow a client and a server to negotiate the protocol which will be used at the above network layer (in our case this is the application layer).


Well, this NPN TLS extension is going to be outdated soon by an official RFC called “Transport Layer Security (TLS) Application Layer Protocol Negotiation Extension” (shortened to ALPN).

Also, we’re already at the third version of SPDY protocol (3.1 to be accurate). It changes quite often.

HAProxy & SPDY

As Willy explained on HAProxy‘s mailing list, HAProxy won’t implement SPDY.
But, as soon as HTTP/2.0 will be released officially, then the development will focus on it.
The main driver for this is the problem seen in the introduction: waste of time because the drafts are updated quite often.

Saying that, HAProxy can be used to:

  • load-balance SPDY web servers

  • detect SPDY protocol through NPN (or more recent ALPN) TLS extension

Diagram

The picture below shows how HAProxy can be used to detect and split HTTP and SPDY traffic over an HTTPS connection:

HAProxy can be used to detect and split HTTP and SPDY traffic

Basically, HAProxy uses the NPN (and later the ALPN) TLS extension to figure out whether the client can browse the website using SPDY. If yes, the connection is forwarded to the SPDY farm (here hosted on nginx), otherwise, the connection is forwarded to the HTTP server farm (here hosted on nginx too).

Configuration

HAProxy configuration example for NPN and SPDY

Below, is the HAProxy configuration to detect and split HTTP and SPDY traffic to two different farms:

defaults
 mode tcp
 log global
 option tcplog
 timeout connect           4s
 timeout server          300s
 timeout client          300s

frontend ft_spdy
 bind 64.210.140.163:443 name https ssl crt STAR_haproxylab_net.pem npn spdy/2

# tcp log format + SSL information (TLS version, cipher in use, SNI, NPN)
 log-format %ci:%cp [%t] %ft %b/%s %Tw/%Tc/%Tt %B %tsc %ac/%fc/%bc/%sc/%rc %sq/%bq {%sslv/%sslc/%[ssl_fc_sni]/%[ssl_fc_npn]}

# acls: npn
 acl npn_spdy           ssl_fc_npn -i spdy/2

# spdy redirection
 use_backend bk_spdy      if npn_spdy

 default_backend bk_http

backend bk_spdy
 option httpchk HEAD /healthcheck
 server nginx 127.0.0.1:8082 maxconn 100 check port 8081

backend bk_http
 option httpchk HEAD /healthcheck
 http-request set-header Spdy no
 server nginx 127.0.0.1:8081 maxconn 100 check

NGINX configuration example for SPDY

And the corresponding nginx configuration:

Note that I use a Lua script to check if the “Spdy: no” HTTP header is present.

  • if present: then the connection was made over HTTP in HAProxy

  • if not present, then the connection was made over SPDY

 server {
      listen 127.0.0.1:8081;
      listen 127.0.0.1:8082 spdy;
      root /var/www/htdocs/spdy/;

        location = /healthcheck {
          access_log off;
          return 200;
        }

        location / {
             default_type 'text/plain';
             content_by_lua '
               local c = ngx.req.get_headers()["Spdy"];
               if c then
                 ngx.say("Currently browsing over HTTP")
               else
                 ngx.say("Currently browsing over spdy")
               end
                return
             ';
        }

   }

Testing

This setup is in production.
Simply browse https://spdy.haproxylab.net/ to give it a try.

Related Links

Subscribe to our blog. Get the latest release updates, tutorials, and deep-dives from HAProxy experts.