twitter-archive / CocoaSPDY

SPDY for iOS and OS X
Apache License 2.0
2.39k stars 233 forks source link

Configuring a server to accept SPDY requests #54

Open nileshjagnik opened 10 years ago

nileshjagnik commented 10 years ago

We have built a server at Amahi for our Amahi iOS app. The server supports NPN over SSL which has been implemented using the Amahi SPDY library. All other services have been enabled to communicate with our server using SPDY via NPN. Except the iOS app which still uses httpv1.1. We now want to use CocoaSPDY in our iOS app. We understand that CocoaSPDY does not support NPN. But due to constraints in the system, we cannot dedicate another port just for spdy requests from the iOS app.

The readme suggests that we "use a server that's smart enough to examine the incoming request and determine whether the connection will be SPDY or HTTP based on what it looks like".

I am looking for a way to build this "smart server" that can work without changing the current framework so as not to disrupt the server's interaction with other apps.

cpg commented 10 years ago

Just to clarify, we want to change our server to do this examination of the incoming request.

We are not clear what we need to do to make sure our clients using CocoaSPDY will need.

We would like it if you can expand on those "smarts" neded to examine the request so we change our server to be able to do this.

goaway commented 10 years ago

Once SSL is negotiated, the next few bytes over the TCP connection are either going to be an HTTP request method or a SPDY frame header. By examining these bytes before setting up the rest of your pipeline, you can determine whether the connection should be set up to handle SPDY or HTTP.

chrismeyersfsu commented 10 years ago

@goaway I think I'm close do doing what you mention with the help of haproxy. Haproxy has the ability to examine the raw bytes going over the socket by just updating the rules/config file (nginx would require modification of the core/module code).

HAProxy Dedicated Port Configuration

This method successfully implements the dedicated port @goaway mentions in the project README.

frontend iospdy
  mode tcp
  bind :4443 ssl crt /home/ubuntu/ssl_certs/your_cert.pem

  default_backend spdy
backend spdy
  server nginx_spdy 127.0.0.1:8091

HAProxy Smart Detection

This method, currently, unsuccessfully attempts to implement the idea @goaway presents in the project README and Twitter implements.

  1. The frontend secure handles ssl and then redires to the backend insecure. I wasn't sure if ssl needed to be handled first before I used req.payload to read from the stream. I wanted to ensure that the bytes count read by req.payload was strictly from the spdy/http stream and not the ssl logic.
  2. Differentiating between spdy and http logic. The line acl isspdy req.payload(0,1) -m bin 80 does not consider data frames.

I believe the problem is the differentiator code below doesn't include any logic to check for a data-frame. See the link above to see an implementation of a differentiator that does take into account the data frame.

I'd appreciate any comments on furthering this differentiator logic.

frontend secure
  mode tcp
  bind :443 ssl crt /home/ubuntu/ssl_certs/your_cert.pem npn http/1.1,http1.0,spdy/3,spdy/2

  use_backend spdy if { ssl_fc_npn -i spdy/3 }
  use_backend spdy if { ssl_fc_npn -i spdy/2 }

  default_backend insecure

backend insecure
  server localhost 127.0.0.1:444
  no log
  acl isspdy req.payload(0,1) -m bin 80
  #tcp-request inspect-delay 1s
  use-server nginx_spdy if isspdy
  server nginx_spdy 127.0.0.1:8091
  server default 127.0.0.1:8090

The configurations above are trimmed down versions of my configuration in an effort to include only the relevant settings. Please post your results.

Useful Commands

http://louwrentius.com/how-to-compile-haproxy-from-source-and-setup-a-basic-configuration.html
make TARGET=linux2628 USE_STATIC_PCRE=1 USE_OPENSSL=1 clean all
sudo haproxy -d -V -f /etc/haproxy/haproxy.cfg