Friday, June 17, 2011

SPDY Express: A Spike 2

‹prev | My Chain | next›

Up tonight, I continue my efforts to get node-spdy working under express.js. On some level, this seems like an easy exercise—express.js uses connect middleware and the test spdy server runs under pure connect just fine.

In practice, at least to my express-inexperienced eye, things aren't so simple. I ended yesterday's efforts with an express.js + SPDY session that ended in a 500 error. That error turns out to be:
TypeError: Object [object Object] has no method 'render'
at Router.<anonymous> (/home/cstrom/repos/node-spdy/test/express/app.js:39:7)
at done (/home/cstrom/repos/node-spdy/node_modules/express/lib/router/index.js:250:22)
at middleware (/home/cstrom/repos/node-spdy/node_modules/express/lib/router/index.js:244:9)
at param (/home/cstrom/repos/node-spdy/node_modules/express/lib/router/index.js:227:11)
at pass (/home/cstrom/repos/node-spdy/node_modules/express/lib/router/index.js:232:6)
at Router._dispatch (/home/cstrom/repos/node-spdy/node_modules/express/lib/router/index.js:255:4)
at Object.handle (/home/cstrom/repos/node-spdy/node_modules/express/lib/router/index.js:45:10)
at next (/home/cstrom/repos/node-spdy/node_modules/connect/lib/http.js:204:15)
at Object.methodOverride [as handle] (/home/cstrom/repos/node-spdy/node_modules/connect/lib/middleware/methodOverride.js:35:5)
at next (/home/cstrom/repos/node-spdy/node_modules/connect/lib/http.js:204:15)
After a bit of noodling, I find that if I add some express.js / ServerResponse methods to the SPDY response object, I can make this error go away. So I add all of the methods in the view.js library in express, which includes the missing render method:
var //...
, http = require('http')
, res = http.ServerResponse.prototype
, spdy = require('../../../lib/spdy')
, spdy_res = spdy.Response.prototype;

//...

spdy_res.partial = res.partial;
spdy_res.render = res.render;
spdy_res._render = res.render;
Now when I try to access the sample express + SPDY site, I get:
Error: Can't set headers after they are sent.
at [object Object].setHeader (/home/cstrom/repos/node-spdy/lib/spdy/response.js:137:11)
at [object Object].next (/home/cstrom/repos/node-spdy/node_modules/connect/lib/http.js:168:13)
at [object Object].<anonymous> (/home/cstrom/repos/node-spdy/node_modules/express/lib/view.js:324:16)
at [object Object].<anonymous> (/home/cstrom/repos/node-spdy/node_modules/express/lib/view.js:313:17)
at [object Object].<anonymous> (/home/cstrom/repos/node-spdy/node_modules/express/lib/view.js:313:17)
at [object Object].<anonymous> (/home/cstrom/repos/node-spdy/node_modules/express/lib/view.js:313:17)
at [object Object].<anonymous> (/home/cstrom/repos/node-spdy/node_modules/express/lib/view.js:313:17)
at [object Object].<anonymous> (/home/cstrom/repos/node-spdy/node_modules/express/lib/view.js:313:17)
at [object Object].<anonymous> (/home/cstrom/repos/node-spdy/node_modules/express/lib/view.js:313:17)
at [object Object].<anonymous> (/home/cstrom/repos/node-spdy/node_modules/express/lib/view.js:313:17)
That message is repeated over and over and over. Running through the stacktrace, I find that the source of this error is setting the header on line 168 of http.js. Specifically, setting the header for a 500 internal server error response:
        res.statusCode = 500;
res.setHeader('Content-Type', 'text/plain');
res.end(msg);
Hahaha. So something is generating an error message, spdy-express tries to send out a 500 error message, which generates another 500 error message, which generates another error message ad infinitum. Good stuff.

I spend a good portion of the rest of the night in node-debug / console.log funland. Eventually, I trace the source of the error to this snippet in https.js:
      // Call the layer handler
// Trim off the part of the url that matches the route
removed = layer.route;
req.url = req.url.substr(removed.length);

// Ensure leading slash
if ('/' != req.url[0]) req.url = '/' + req.url;
Look as though I need to investigate express.js routing. Tomorrow. That is going to need to be enough progress for tonight. Exhausted.


Day #53

No comments:

Post a Comment