Monday, June 20, 2011

SPDY Connect

‹prev | My Chain | next›

Last night I cataloged what was needed to get a SPDY enabled express.js by way of node-spdy. Tonight I am going to start on the biggest unknown: writing a module to SPDY-ize connect.

The changes that I had to make directly to lib/connect.js are highlighted:
var HTTPServer = require('./http').Server
, HTTPSServer = require('./https').Server
, SPDYServer = require('./spdy').Server
, fs = require('fs');

// ...

function createServer() {
if ('object' == typeof arguments[0]) {
// return new HTTPSServer(arguments[0], Array.prototype.slice.call(arguments, 1));
return new SPDYServer(arguments[0], Array.prototype.slice.call(arguments, 1));

} else {
return new HTTPServer(Array.prototype.slice.call(arguments));
}

//...

exports.HTTPServer = HTTPServer;
exports.HTTPSServer = HTTPSServer;
exports.SPDYServer = SPDYServer;
So, the connect library needs to be able to export, as SPDYServer, the SPDY server that I defined separately in lib/spdy.js. I also need to override the exported connect.createServer function to send back a SPDY Server instead of an HTTPS Server. Exporting connect.createServer is made more complicated by virtue of lib/connect.js exporting createServer() as the export module itself:
// expose createServer() as the module

exports = module.exports = createServer;
I am unfamiliar with overriding the module like that. I wonder what effect it would have on doing something along the lines of:
original_connect = connect.createServer;
connect.createServer = function() {
if (SPDY_ENABLED) {
// do SPDY stuff
}
else {
original_connect()
}
}
Only one way to find out.

First up, I create a NPM package:
➜  connect-spdy  npm init
Package name: (connect-spdy)
Description: SPDY-ized connect server.
Package version: (0.0.0)
Project homepage: (none) https://github.com/eee-c/connect-spdy
Project git repository: (none) https://github.com/eee-c/connect-spdy
Author name: Chris Strom
Author email: (none) chris@eeecomputes.com
Author url: (none) http://eeecomputes.com
Main module/entry point: (none) index
Test command: (none)
What versions of node does it run on? (~v0.5.0-pre) >= 0.5.0-pre
About to write to /home/cstrom/repos/connect-spdy/package.json

{
"author": "Chris Strom (http://eeecomputes.com)",
"name": "connect-spdy",
"description": "SPDY-ized connect server.",
"version": "0.0.0",
"homepage": "https://github.com/eee-c/connect-spdy",
"repository": {
"type": "git",
"url": "git://github.com/eee-c/connect-spdy.git"
},
"main": "index",
"engines": {
"node": ">= 0.5.0-pre"
},
"dependencies": {},
"devDependencies": {}
}

Is this ok? (yes) yes
Now... how to hook into the existing connect.createServer? Will it always be defined when my connect-spdy is loaded...?

Ooh! Maybe I can expose a createServer() in connect-spdy in such a way that it mimics the spike code:
exports = module.exports = createServer;

function createServer() {
if ('object' == typeof arguments[0]) {
return new SPDYServer(arguments[0], Array.prototype.slice.call(arguments, 1));
} else {
return connectCreateServer(Array.prototype.slice.call(arguments));
}
};
If arguments are passed in, then I assume that we are trying to establish a SPDY server otherwise, I allow the default connect createServer() to do its thing. For the SPDYServer class, I just re-use the same class from my spike which, itself, was just a copy of connect's https.js.

With that, I revert my local copy of connect to the original package installed from npm. In express.js, I then load connect-spdy instead of connect:
-var connect = require('connect')
+var connect = require('connect-spdy')
And that actually seems to work. When I fire up the test express app.js server, with vanilla connect + my newly created connect-spdy, I see SPDY sessions in Chrome's about:net-internals:
    t=1308619806288 [st=8994]     SPDY_SESSION_SYN_REPLY  
--> flags = 0
--> connection: keep-alive
content-length: 277
content-type: text/html
status: 200 OK
version: HTTP/1.1
x-powered-by: Express
--> id = 7
Nice! That seems like a reasonable approach and a fine stopping point for the night.

I do not think connect-spdy is quite ready for npm, but I at least put it out on github in case anyone interested. I will get started on express-spdy tomorrow.


Day #54

No comments:

Post a Comment