Up tonight, I would like to explore NPN (Next Protocol Negotiation) in node-spdy. NPN is a new SSL extension that is required to perform proper SPDY. I have already looked at this in the SPDY gem, but believe that I may have to add this to node-spdy.
To test this out, I load up the sample node-spdy server in Firefox. Amazingly it just works. Looking at the packets in Wireshark, I find:
There is no NPN negotiation taking place in there. The next packet after the SSL Server Hello is a normal HTTP GET request for the homepage. Nice.
I already know that node-spdy works perfectly well with Chrome when explicitly specifying
spdy/2
as the NPN protocol. But how does Chrome deal with an NPN protocol of http/1.1
? More to the point, how does node-spdy handle it?I change the test server to set
http/1.1
:var options = {Again, it turns out to handle it just fine. The Wireshark capture shows that Chrome triggers a NPN session, which only specifies
// ...
NPNProtocols: ['http/1.1']
};
var server = spdy.createServer(options, function(req, res) {
// ...
});
http/1.1
:So, wow. There does not seem to be anything needed to get node-spdy working with NPN while still being backward compatible. But how is it managing that? I have not come across any code that I recall...
Digging into it some, I find that indeed node-spdy does nothing to perform NPN. In fact, it is node.js itself that does the negotiation. The options from the node-spdy test server:
var options = {These are passed to the node-spdy
//...
NPNProtocols: ['http/1.1']
};
var server = spdy.createServer(options, function(req, res) {
//...
});
createServer()
function, which, in turn, passes them along to the TLS create server:var Server = core.Server = function(options, requestListener) {Following this through to the TLS module in node.js, I find that these options are passed along to
//...
tls.Server.call(this, options, function(c) {
// ...
});
//...
};
setOptions
:function Server(/* [options], listener */) {And, finally, those options are converted into a
var options, listener;
//...
this.setOptions(options);
});
Buffer
to be used in NPN by the convertNPNProtocols()
function:// Convert protocols array into valid OpenSSL protocols listPretty darn impressive that this just works in node.js. Huge kudos to Fedor Indutny who not only wrote node-spdy but also wrote the node.js code that does NPN. As a Rubyist, I am dissappointed that the same feature languishes in the pull request purgatory of eventmachine.
// ("\x06spdy/2\x08http/1.1\x08http/1.0")
function convertNPNProtocols(NPNProtocols, out) {
//..
};
Day #49
No comments:
Post a Comment