spdy-http2 / node-spdy

SPDY server on Node.js
2.81k stars 196 forks source link

1.32.x Failing with node >= 4.1.2 #234

Closed AdamMagaluk closed 8 years ago

AdamMagaluk commented 8 years ago

Recently when updating from node 4.1.1 going to 4.1.2 I've noticed our code that uses node-spdy@1.32.x breaks. I've tracked down the changes in node@4.1.2 to this commit https://github.com/nodejs/node/commit/99943e189d specificly removal of the lines 136-141 in lib/_http_outgoing.js.

For some reason node-spdy is sending a blank buffer which is causing the crash. In <= node@4.1.1 it would get filtered out by lines 136-141. In latest node zero length data only gets filtered out if a) there's connection with http_message b) the output is length 0. In this case it follows the path to be buffered which does not check the length of the data.

Any thoughts on how to get around this?

Below running the file with node@4.1.1

λ: nvm use v4.1.1
Now using node v4.1.

λ: node spdy-test.js
connection
on req: /some-url

Running with node@4.1.2


λ: nvm use v4.1.2
Now using node v4.1.2

λ: node spdy-test.js
connection
net.js:617
    throw new TypeError('invalid data');
    ^

TypeError: invalid data
    at Socket.write (net.js:617:11)
    at Connection.write (/Users/ApigeeCorporation/Software/zetta/tests/spdy-4-test/node_modules/spdy/lib/spdy/connection.js:515:36)
    at Scheduler.tickListener [as _tickListener] (/Users/ApigeeCorporation/Software/zetta/tests/spdy-4-test/node_modules/spdy/lib/spdy/scheduler.js:67:23)
    at processImmediate [as _immediateCallback] (timers.js:374:17)
var net = require('net');
var http = require('http');
var spdy = require('spdy');

var server = spdy.createServer({
  windowSize: 1024 * 1024,
  plain: true,
  ssl: false
});

server.on('connection', function() {
  console.log('connection')
});

server.on('request', function(req, res) {
  console.log('on req:', req.url);
});

server.listen(3000, function() {
  var agent = spdy.createAgent({
    host: 'localhost',
    port: 3000,
    spdy: {
      plain: true,
      ssl: false
    }
  }).on('error', function(err) {
    console.error('agent error:', err);
  });

  var body = new Buffer([1,2,3,4]);

  var opts = {
    method: 'POST',
    headers: {
      'Host': 'localhost',
      'Content-Length': body.length
    },
    path: '/some-url',
    agent: agent
  };

  var req = http.request(opts, function(res) {
  }).on('error', function(err) {
    console.error('req error:', err);
  });
  req.end(body);

});
AdamMagaluk commented 8 years ago

Also note this issue does not happen when you use req.pipe() instead of req.end(data). I was able to get around the issue in the code i'm by replacing all req.end() with a req.pipe().

indutny commented 8 years ago

Fixed, thanks for reporting!