For the last two days, I have be spiking in an attempt to get SPDY and express.js playing nicely. Day 3 picks up where I left off yesterday, with an exception being generated from within the
http.js
module of connect:Server.prototype.handle = function(req, res, out) {After some rooting around in
// ...
// 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;
// ...
node debug
, I come across a seemingly unhelpful exception:RangeError undefined.It is an odd little error because it seemingly comes from nowhere (there is no associated stacktrace). Eventually, I step through enough code to come across:
debug> break in #<Object>.render(view=index, opts=#<Object>, fn=undefined, parent=undefined, sub=undefined), /home/cstrom/repos/node-spdy/node_modules/express/lib/view.js:308I actually go through many more iterations than shown above before I realize that it is repeating. I think the endless repeating must eventually result in the
if ('function' == typeof opts) {
^
debug>
break in #<Object>.render(view=index, opts=#<Object>, fn=undefined, parent=undefined, sub=undefined), /home/cstrom/repos/node-spdy/node_modules/express/lib/view.js:313
return this._render(view, opts, fn, parent, sub);
^
debug>
break in #<Object>.render(view=index, opts=#<Object>, fn=undefined, parent=undefined, sub=undefined), /home/cstrom/repos/node-spdy/node_modules/express/lib/view.js:308
if ('function' == typeof opts) {
^
debug>
break in #<Object>.render(view=index, opts=#<Object>, fn=undefined, parent=undefined, sub=undefined), /home/cstrom/repos/node-spdy/node_modules/express/lib/view.js:313
return this._render(view, opts, fn, parent, sub);
^
debug>
break in #<Object>.render(view=index, opts=#<Object>, fn=undefined, parent=undefined, sub=undefined), /home/cstrom/repos/node-spdy/node_modules/express/lib/view.js:308
if ('function' == typeof opts) {
^
RangeError
. Regardless, I need to figure out why it is repeating. More to the point, why is a call to the _render()
method stepping right back into render()
on line 308?It turns out that there is a perfectly reasonable answer to that question. In my sleep deprived delirium yesterday, I defined
_render
and render
in the SPDY response object to be the same thing:spdy_res.partial = res.partial;Both are pointing to the
spdy_res.render = res.render;
spdy_res._render = res.render;
render()
method from Response
in express.js. The solution is easy enough, point spdy_res._render
to res._render
:spdy_res.partial = res.partial;That gets me a little farther. But, when I load the express sample app now, I get:
spdy_res.render = res.render;
spdy_res._render = res._render;
TypeError: Object [object Object] has no method 'send'That is a similar class of error to what I was seeing last night. Specifically, express decorates connect and node.js objects with new methods (like
at [object Object]._render (/home/cstrom/repos/node-spdy/node_modules/express/lib/view.js:439:10)
at [object Object].render (/home/cstrom/repos/node-spdy/node_modules/express/lib/view.js:313:17)
at [object Object]._render (/home/cstrom/repos/node-spdy/node_modules/express/lib/view.js:429:10)
at [object Object].render (/home/cstrom/repos/node-spdy/node_modules/express/lib/view.js:313:17)
at Router.(/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)
render()
and send()
). I already figured out how to add render()
(it did take a few tries to get _render()
working). Unfortunately, that same technique won't quite work with send()
.For
render()
I was able to decorate directly in my newly added express/lib/spdy.js
. Unfortunately, the send()
method is added to Response.prototype
after lib/spdy.js
is loaded. So I have to add code directly to lib/express.js
:var http = require('http')After doing the same for
, res = http.ServerResponse.prototype
, spdy = require('../../../lib/spdy')
, spdy_res = spdy.Response.prototype;
spdy_res.send = res.send;
contentType()
and header()
, I am actually able to load up the app!Even more impressive, when I check out the SPDY tab in Chrome's
about:net-internals
, I find:t=1308442868018 [st=24936] SPDY_SESSION_SYN_STREAMHoly wow! That's a real SPDY session. And it is powered by express.js! And no errors!
--> flags = 1
--> accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
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: max-age=0
host: localhost:3000
method: GET
scheme: https
url: /
user-agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.794.0 Safari/535.1
version: HTTP/1.1
--> id = 7
t=1308442868031 [st=24949] 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
Yay! It actually works!
Er... I mean of course it works. I'm brilliant! And tomorrow I'll see if I can figure out how it works. And maybe even implement it well.
Day #53
No comments:
Post a Comment