History of mod_spdy
Work began January 2010. We implemented framing, and serial multiplexing. The project was placed on indefinite hold a few months later, pending better SPDY experimental results. Resumed the project November 2011. We now have a complete SPDY implementation.
server
client
SSL handshake
server
Hello!
client
SSL handshake
server
client
SSL handshake
server
I choose: spdy/2
client
Next Protocol Negotiation (NPN) Our patched version of mod_ssl provides two NPN-related hooks.
Next Protocol Negotiation (NPN) Our patched version of mod_ssl provides two NPN-related hooks. The first hook lets us add protocols to be advertised. The second hook informs us which protocol was chosen by the client.
Next Protocol Negotiation (NPN) Our patched version of mod_ssl provides two NPN-related hooks. The first hook lets us add protocols to be advertised. The second hook informs us which protocol was chosen by the client. Other modules could use these hooks too.
mod_spdy
mod_ssl
client
mod_foo
mod_spdy
mod_ssl
SSL handshake
client
Hello! mod_foo
mod_ssl
SSL handshake
client
Hello! mod_foo
mod_ssl
SSL handshake
client
mod_spdy
mod_ssl
SSL handshake
client
mod_foo
mod_spdy
mod_ssl
SSL handshake
client
mod_ssl
client
mod_foo
Hooray!
mod_ssl
client
mod_foo
Aww...
Framing and header compression We insert filters to translate from SPDY frames to equivalent HTTP data, and back. Do this at the connection (not request) level, to maintain header compression state. This approach lets the site owner use the same, HTTP-specific Apache modules to process requests as without mod_spdy.
MPM
server socket
MPM
client socket
server socket
client socket
MPM
connection object
client socket
server socket
connection object
client socket
client socket
thread/process 3
server socket
connection object
client socket
client socket
MPM
server socket
client socket
network filters
MPM
server socket
client socket
network filters
MPM
server socket
client socket
network filters
MPM
server socket
client socket
network filters
MPM
request object
server socket
client socket
network filters
MPM
request object
server socket
client socket
network filters
MPM
server socket
Stream multiplexing
Once a request handler takes over, it does not return control until the request is finished. Apache (and modules) assume one thread per connection; the core data structures are not thread-safe. So we can't be event-driven, and we can't be multithreaded. What to do?
client socket
network filters
MPM
server socket
client socket
network filters
MPM
server socket
client socket
network filters
MPM
SPDY stream
client socket
network filters
MPM
SPDY thread 1
SPDY stream
SPDY thread 2
SPDY stream server socket SPDY stream
SPDY thread 3
client socket
network filters
MPM
SPDY thread 1
SPDY stream
server socket
client socket
network filters
SPDY thread 1
SPDY stream
server socket
client socket
network filters
SPDY thread 1
SPDY stream fake socket
server socket
client socket
network filters
SPDY thread 1
SPDY stream fake socket
SSL filters
server socket
client socket
network filters
SPDY thread 1
SPDY stream fake socket
server socket
client socket
network filters
SPDY thread 1
SPDY stream fake socket
network filters
server socket
client socket
network filters
SPDY thread 1
SPDY stream fake socket
server socket
client socket
network filters
SPDY thread 1
SPDY stream fake socket
server socket
client socket
network filters
SPDY thread 1
SPDY stream fake socket
server socket
client socket
network filters
SPDY thread 1
SPDY stream fake socket
server socket
request object
client socket
network filters
SPDY thread 1
SPDY stream fake socket
server socket
request object
Server push
mod_spdy provides a server-push function to other modules. When called (e.g. from a stream request handler), the main SPDY connection thread creates a new server-push stream. We synthesize a request to imagine that the client sent us, and allow Apache to respond accordingly.
Server push
One wrinkle: by the spec, we must send the pushed SYN_STREAM before the associated stream's FLAG_FIN.
Server push
One wrinkle: by the spec, we must send the pushed SYN_STREAM before the associated stream's FLAG_FIN. But we don't have response headers yet, and don't want to impose a synchronization between stream threads.
Server push
One wrinkle: by the spec, we must send the pushed SYN_STREAM before the associated stream's FLAG_FIN.
But we don't have response headers yet, and don't want to impose a synchronization between stream threads.
Solution: send SYN_STREAM sans headers; follow up with HEADERS frame later.
Remaining tasks/challenges