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