I am closing in on the deadline for the beta copy of SPDY Book, which got me to thinking of things that I absolutely need for a proper book. The first thing that popped into my mind was an easy Express.js server.
Currently in my node-spdy working repo, I have Connect.js installed:
➜ node-spdy git:(data-compression) npm lsThat is a requirement for express,js, but not sufficient. So I install express as well:
spdy@0.0.1 /home/cstrom/repos/node-spdy
├─┬ connect@1.4.1 extraneous
│ ├── mime@1.2.2
│ └── qs@0.1.0
└── zlibcontext@1.0.7
➜ node-spdy git:(data-compression) npm install expressOoh! It seems that Express.js now comes with a generator. So I install express globally (to be able to run the binary) and execute the generator:
mime@1.2.2 ./node_modules/express/node_modules/mime
qs@0.1.0 ./node_modules/express/node_modules/qs
express@2.3.11 ./node_modules/express
➜ node-spdy git:(data-compression) npm ls
spdy@0.0.1 /home/cstrom/repos/node-spdy
├─┬ connect@1.4.1 extraneous
│ ├── mime@1.2.2
│ └── qs@0.1.0
├─┬ express@2.3.11 extraneous
│ ├── mime@1.2.2
│ └── qs@0.1.0
└── zlibcontext@1.0.7
➜ node-spdy git:(express) npm install -g expressI have not installed jade, so I do so now:
/home/cstrom/local/node-v0.5.0-pre/bin/express -> /home/cstrom/local/node-v0.5.0-pre/lib/node_modules/express/bin/express
mime@1.2.2 /home/cstrom/local/node-v0.5.0-pre/lib/node_modules/express/node_modules/mime
connect@1.4.4 /home/cstrom/local/node-v0.5.0-pre/lib/node_modules/express/node_modules/connect
qs@0.1.0 /home/cstrom/local/node-v0.5.0-pre/lib/node_modules/express/node_modules/qs
express@2.3.11 /home/cstrom/local/node-v0.5.0-pre/lib/node_modules/express
➜ node-spdy git:(express) express test/express
create : test/express
create : test/express/app.js
create : test/express/public/stylesheets
create : test/express/public/stylesheets/style.css
create : test/express/public/images
create : test/express/public/javascripts
create : test/express/logs
create : test/express/pids
create : test/express/test
create : test/express/test/app.test.js
create : test/express/views
create : test/express/views/layout.jade
create : test/express/views/index.jade
- make sure you have installed jade: $ npm install jade
➜ node-spdy git:(express) ✗ npm install jadeWith that, I can fire up the skeleton app:
jade@0.12.2 ./node_modules/jade
➜ node-spdy git:(express) ✗ node test/express/app.jsChecking it out in the browser, I see that it works:
Express server listening on port 3000
The next step is to run this as an https server. Running an https server in express is identical to running an http server except that I need to pass in SSL related options to the
createServer()
call. So, I fire up Emacs and add those options to the express
created app.js
:var express = require('express')And, sure enough, I now have a https version of the skeleton app:
, fs = require('fs');
var app = module.exports = express.createServer({
key: fs.readFileSync(__dirname + '/../../keys/spdy-key.pem'),
cert: fs.readFileSync(__dirname + '/../../keys/spdy-cert.pem'),
ca: fs.readFileSync(__dirname + '/../../keys/spdy-csr.pem'),
npnProtocols: ['spdy/2']
});
Now, I do something terrible. I start editing the express code directly in node_modules. This is almost certainly going to come back to bite me, but I am embracing this as a pure spike to gain a first understanding of what is required.
In there, I copy the https.js modules in both express and connect to equivalent spdy.js files. After replacing all instances of https with SPDY, I fire up the browser, sniff the network to find that I do not have a SPDY session.
It looks as though my first attempt at a SPDY / Express server is not sending out SPDY as a possible protocol. In a legitimate SPDY session, one of the first things to occur is a SSL Server Hello that includes
spdy/2
as a possible protocol:In my SPDY / express server, I am not seeing any NPN protocols:
I drop down into the debugger to find that I am passing the required NPNProtocols options all the way to the TLS server instance. Furthermore, I trace the NPNProtocol all the way to
convertNPNProtocols
:debug> { '0': 6, '1': 115, '2': 112, '3': 100, '4': 121, '5': 47, '6': 50, length: 7, offset: 4048, parent: '#<SlowBuffer>' }That is a buffer containing the ascii representations for spdy/2 (115 == s, 112 = p, etc). Ugh. So why is that not getting sent out to the browser?
I quit and restart Chrome a couple of times and eventually get a legit SPDY NPN session:
I cannot quite figure out why the server kept sending out an empty NPN list previously. I could see Chrome caching the empty NPN cert, but the server was clearly actively sending an empty NPN session over the wire. For now I will have to chalk that up to PEBKAC. Still, I tuck this away in the back of my mind for future reference. It seems like something is going wrong (or significantly unexpected).
Getting back to a working express / SPDY session, I check things out in the SPDY tab of Chrome's
about:net-internals
to find:t=1308281848286 [st= 11] SPDY_SESSION_SYN_REPLYYay! A SPDY session served up by express!
--> flags = 0
--> connection: keep-alive
content-type: text/html
status: 500 OK
version: HTTP/1.1
x-powered-by: Express
--> id = 1
Oh wait. The response status is 500 / internal server error. So, just... yay.
I will call it a night at this point. Hopefully the internal server error will be relatively easy to track down. Assuming that is the case, I will get started on implementing a real SPDY express middleware module tomorrow.
Day #52
No comments:
Post a Comment