Yesterday I finally got a version 3 flavored SPDY conversation to take place. I had enabled spdy/3 in Chrome's
about:flags the other day, but the struggled through conversion of node-spdy's version 2 implementation to account for incompatibilities between the two versions and then a dumb mistake in assembling the headers.Today, I clean up.
First, I remove every
console.log() statement. There were a lot.Then I make sure that everything is still working. Stranger things have happened than everything breaking after removing
console.log() statements. Thankfully that is not the case this time. I still have my spdy/3 session:And, better still, no errors in the SPDY tab of
about:net-internals:....
SPDY_SESSION_SYN_REPLY
--> flags = 0
--> :status: 200
:version: HTTP/1.1
--> id = 1
SPDY_SESSION_RECV_DATA
--> flags = 0
--> size = 339
--> stream_id = 1
SPDY_SESSION_RECV_DATA
--> flags = 0
--> size = 0
--> stream_id = 1
SPDY_SESSION_SYN_STREAM
--> flags = 1
--> :host: localhost:3000
:method: GET
:path: /stylesheets/style.css
:scheme: https
:version: HTTP/1.1
accept: text/css,*/*;q=0.1
accept-charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
accept-encoding: gzip,deflate,sdch
accept-language: en-US,en;q=0.8
cache-control: no-cache
cookie: [value was stripped]
pragma: no-cache
referer: https://localhost:3000/
user-agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.9 (KHTML, like Gecko) Chrome/20.0.1115.1 Safari/536.9
--> id = 3
...There is still much work to go, but this good enough to create a branch on the node-spdy repository. The whole reason that I started down the spdy/3 road was to experiment with flow control. But there is at least one thing that I have to do before I move onto that. I need to re-enable spdy/2. Nearly all clients still use spdy/2, but right now I only have the spdy/3 zlib dictionary (used for blindingly fast header compression) hard-coded in
lib/spdy/utils.js. I need to move that out of utils.js and into the protocol version definitions. I also need to dynamically select the appropriate dictionary at connection time.Thankfully, the node-spdy module makes the value of the Next Protocol Negotation (an extension of SSL) available on the socket. So, when the zlib compression contexts are established on the connection, I can supply the protocol version:
function Connection(socket, pool, options) {
process.EventEmitter.call(this);
var self = this;
this._closed = false;
this.pool = pool;
var pair = pool.get(socket.npnProtocol);
this.deflate = pair.deflate;
this.inflate = pair.inflate;
// ...The pool can then look up the dictionary using the appropriate SPDY version number:Pool.prototype.get = function get(version, callback) {
var version_number = version.split(/\//)[1],
dictionary = spdy.protocol[version_number].dictionary;
// ...The dictionary itself is assigned to the protocol in the protocol's index.js (e.g. lib/spdy/protocol/v3/index.js):lib/spdy/protocol/v3/index.jsvar v3;
// ...
module.exports = v3;
v3.dictionary = require('./dictionary').dictionary;And the dictionary can be defined in dictionary.js as:exports.dictionary = new Buffer([
0x00, 0x00, 0x00, 0x07, 0x6f, 0x70, 0x74, 0x69,
0x6f, 0x6e, 0x73, 0x00, 0x00, 0x00, 0x04, 0x68,
0x65, 0x61, 0x64, 0x00, 0x00, 0x00, 0x04, 0x70,
// ...
]);(that is lifted directly from the spec)With that, I have my SPDY version three connection working again. This time, however, the dictionary comes from the correct protocol version library. After doing the same for spdy/2, node-spdy is now capable of serving up both spdy/3 and spdy2 from the same server:
That is a good stopping point for now. Tomorrow, I will hopefully pick back up with flow control.
Day #368


No comments:
Post a Comment