I have an express 4 app that I am attempting to implement http2/SPDY.
www (where server is created):
var spdy = require('spdy');
var options = {
/* certs */
}
var server = spdy.createServer(options,app).listen(8081);
index.js:
var asset = fs.readFileSync("public/js/asset.js");
router.get('/test', function(req,res) {
if (req.isSpdy) {
var headers = {'content-type': 'application/javascript'};
res.push('/js/asset.js', headers, function(err,stream) {
if (err) {
console.log(err);
return;
}
stream.end(asset);
});
}
res.render('test', {});
});
Now this all works out perfectly in normal use scenario. Using the SPDY indicator plugin I can see that my site is being served via HTTP/2. I am also able to see PUSH_PROMISES working for the specified asset files. Its performance improvement is pretty awesome really.
However, the problem arises when the request is aborted by the client. This is easy to replicate by rapidly pressing refresh/stop in a browser. In this scenario I receive the following error which crashes my node app:
events.js:141
throw er; // Unhandled 'error' event
^
Error: socket hang up
at TLSSocket.onclose (/Users/colevarner/fullpower/node/motionxlive/node_modules/spdy/node_modules/spdy-transport/lib/spdy-transport/connection.js:186:15)
at TLSSocket.g (events.js:260:16)
at emitOne (events.js:82:20)
at TLSSocket.emit (events.js:169:7)
at Immediate._onImmediate (net.js:469:12)
at processImmediate [as _immediateCallback] (timers.js:374:17)
If I comment out the res.push()
calls, the code works as expected with no errors.
I gave the npm spdy-push
wrapper module (which states it handles connection closes) a try, but it did not work at all. When set up like the documentation shows, it caused the following error:
/Users/colevarner/fullpower/node/motionxlive/node_modules/spdy/node_modules/spdy-transport/lib/spdy-transport/stream.js:662
return callback(err, push);
^
TypeError: callback is not a function
at /Users/colevarner/fullpower/node/motionxlive/node_modules/spdy/node_modules/spdy-transport/lib/spdy-transport/stream.js:662:14
at /Users/colevarner/fullpower/node/motionxlive/node_modules/spdy/node_modules/spdy-transport/lib/spdy-transport/connection.js:833:5
at Object.callback (/Users/colevarner/fullpower/node/motionxlive/node_modules/spdy/node_modules/spdy-transport/lib/spdy-transport/stream.js:463:5)
at Framer.tickSync (/Users/colevarner/fullpower/node/motionxlive/node_modules/spdy/node_modules/spdy-transport/lib/spdy-transport/protocol/base/scheduler.js:130:12)
at Framer.tick (/Users/colevarner/fullpower/node/motionxlive/node_modules/spdy/node_modules/spdy-transport/lib/spdy-transport/protocol/base/scheduler.js:108:13)
at /Users/colevarner/fullpower/node/motionxlive/node_modules/spdy/node_modules/spdy-transport/lib/spdy-transport/protocol/base/scheduler.js:102:10
at doNTCallback0 (node.js:407:9)
at process._tickCallback (node.js:336:13)
Does anyone have any ideas on what I could be doing wrong, how I am supposed to handle aborted requests, or another module that provides http2/spdy PUSH_PROMISE support for Express?
After speaking with the developer of npm-spdy
it appears this is currently broken.