SPDY bug in Nginx 1.7.0
|Reported by:||X Ryl||Owned by:|
|uname -a:||Linux MyHOST 3.2.0-4-kirkwood #1 Debian 3.2.54-2 armv5tel GNU/Linux|
nginx version: nginx/1.7.0
built by gcc 4.7.2 (Debian 4.7.2-5)
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/lib/nginx/body --http-proxy-temp-path=/var/lib/nginx/proxy --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --user=www-data --group=www-data --with-http_ssl_module --with-http_spdy_module --with-http_sub_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_secure_link_module --with-http_stub_status_module --with-file-aio --without-http_uwsgi_module
I've seen a recurrent bug in nginx starting from 1.5 up to 1.7 when SPDY is enabled. At first, I though it was due to SPDY/2 protocol's known race condition, but it's still here in 1.7 with SPDY/3 protocol.
Attached is an hexdump from SPDY decrypted session that can be imported by Wireshark and analyzed by spdyshark's dissector (use "Import from hexdump" in the file menu, Ethernet type, dummy TCP header, whatever ports, then right click the first packet and select "Decode as SPDY")
Typically what happens:
1) The usual connection with static content works with SPDY
2) When querying Ajax's POST request, the connection drops because Nginx tells it's about to send 12 headers but only send 8 of them.
3) In the PHP's backend, I'm sending a lot of "Set-Cookie" header when starting/stopping the different session.
4) The last header that's parsed correctly in Wireshark is the first "Set-Cookie"
5) The specification for the protocol states:
"Duplicate header names are not allowed. To send two identically named headers, send a header with two values, where the values are separated by a single NUL (0) byte. Senders must not send multiple, in-sequence NUL characters. Receivers of multiple, in-sequence NUL characters must send a RST_STREAM with code PROTOCOL_ERROR on the stream."
6) See also https://code.google.com/p/chromium/issues/detail?id=252114
7) Not sure it's done correctly in nginx or not, but as a result, no connection works when SPDY is enabled in nginx, so it's a major bug for me.