Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Client response pause/resume does not work with non-keepalive connection #5787

Closed
egirshov opened this issue Jul 3, 2013 · 5 comments
Closed

Comments

@egirshov
Copy link

egirshov commented Jul 3, 2013

Doing pause/resume on response for a request with connection: close header results in 'aborted' event, 'end' is emitted afterwards as well.

Copying sample code from node-formidable/formidable#240 (tried out with 0.8, 0.10 and 0.11).

var http = require('http');
var server = http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.write('aaa');
  res.end('bbb');
});
server.listen(4000);
http.get({port: 4000, agent: false}).on('response', function (res) {
  res.on('data', function () {
    res.pause();
    setTimeout(function () { res.resume(); }, 100);
  });
  res.on('aborted', function () {
    console.log('aborted');
  });
  res.on('end', function () {
    console.log('end');
    server.close();
  });
});
@rustyconover
Copy link

I believe I know the cause of this problem.

Since the server isn't using a keep alive connection, it is closing the socket once the reply is complete. Calling shutdown() then close() on the socket.

The client, by pausing the data stream keeps some tcp data buffered. Before it is able to read all of the data off of the socket it receives a TCP reset packet causing signaling the socket has been closed by the server, which in turn causes the aborted event to be emitted.

This is all explained in much more depth here:

http://blog.netherlabs.nl/articles/2009/01/18/the-ultimate-so_linger-page-or-why-is-my-tcp-not-reliable
or
http://httpd.apache.org/docs/2.0/misc/fin_wait_2.html

Node does not implement a lingering close, or use the SO_LINGER option from the sources I've read in 0.12. It normally wouldn't need to because, most web connections are keep-alive now and with luck this problem wouldn't be rearing its complicated head but it is in this case.

@bnoordhuis Are you interested in a lingering close implementation in http.js for non keep-alive connections? Or a patch to add SO_LINGER support?

@tjfontaine
Copy link

I'm not sure that's the case, as it seems to be working with latest master after the streams3 changes that @isaacs made

@egirshov
Copy link
Author

Right, that works correctly in master now, how about 0.8 and 0.10 branches?

@bnoordhuis
Copy link
Member

@bnoordhuis Are you interested in a lingering close implementation in http.js for non keep-alive connections? Or a patch to add SO_LINGER support?

I don't want to derail this issue so if you want to continue the conversation please open a new one or post to the mailing list but the short answer is 'no' and that's because the slightly longer answer is 'because it introduces as many problems as it solves.'

@egirshov
Copy link
Author

@tjfontaine Could you please reopen this for 0.10 fix or comment if it's not going to be ported there?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants