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”.
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 SPDY, NPN, ALPN, 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:
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
SPDY whitepaper: http://www.chromium.org/spdy/spdy-whitepaper
SPDY (official ???) page: http://www.chromium.org/spdy
IETF Transport Layer Security (TLS) Application Layer Protocol Negotiation Extension: http://tools.ietf.org/html/draft-friedl-tls-applayerprotoneg-02
IETF HTTP/1.1 RFC: http://www.ietf.org/rfc/rfc2616.txt