Permalink
Browse files

Fix HTTP agent disconnection problem

  • Loading branch information...
1 parent 9d4c5a1 commit 36e75b7351c483cdc8ae281e9c43278836ea94f8 @ry ry committed Mar 14, 2011
Showing with 91 additions and 2 deletions.
  1. +4 −2 lib/http.js
  2. BIN test/fixtures/person.jpg
  3. +87 −0 test/simple/test-http-get-pipeline-problem.js
View
6 lib/http.js
@@ -1289,8 +1289,10 @@ Agent.prototype._establishNewConnection = function() {
// All that should be required for keep-alive is to not reconnect,
// but outgoingFlush instead.
if (!req.shouldKeepAlive) {
- debug('AGENT socket.end()');
- if (socket.writable) socket.end();
+ if (socket.writable) {
+ debug('AGENT socket.destroySoon()');
+ socket.destroySoon();
+ }
assert(!socket.writable);
} else {
debug('AGENT socket keep-alive');
View
BIN test/fixtures/person.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
87 test/simple/test-http-get-pipeline-problem.js
@@ -0,0 +1,87 @@
+// We are demonstrating a problem with http.get when queueing up many
+// transfers. The server simply introduces some delay and sends a file.
+// Note this is demonstarted with connection: close.
+var common = require('../common');
+var assert = require('assert');
+var http = require('http');
+var fs = require('fs');
+
+var image = fs.readFileSync(common.fixturesDir + '/person.jpg');
+
+console.log("image.length = " + image.length);
+
+var total = 100;
+var requests = 0, responses = 0;
+
+var server = http.Server(function(req, res) {
+ if (++requests == total) {
+ server.close();
+ }
+
+ setTimeout(function() {
+ res.writeHead(200, {
+ 'content-type': 'image/jpeg',
+ 'connection': 'close',
+ 'content-length': image.length
+ });
+ res.end(image);
+ }, 1);
+});
+
+
+server.listen(common.PORT, function() {
+ for (var i = 0; i < total; i++) {
+ (function() {
+ var x = i;
+
+ var opts = {
+ port: common.PORT,
+ headers: { connection: 'close' }
+ };
+
+ http.get(opts, function(res) {
+ console.error("recv " + x);
+ var s = fs.createWriteStream(common.tmpDir + '/' + x + ".jpg");
+ res.pipe(s);
+
+ // TODO there should be a callback to pipe() that will allow
+ // us to get a callback when the pipe is finished.
+ res.on('end', function() {
+ console.error("done " + x);
+ if (++responses == total) {
+ s.on('close', checkFiles);
+ }
+ });
+ }).on('error', function(e) {
+ console.error('error! ', e.message)
+ throw e;
+ });
+ })();
+ }
+});
+
+
+var checkedFiles = false;
+function checkFiles() {
+ // Should see 1.jpg, 2.jpg, ..., 100.jpg in tmpDir
+ var files = fs.readdirSync(common.tmpDir);
+ assert.equal(total, files.length);
+
+ for (var i = 0; i < total; i++) {
+ var fn = i + '.jpg';
+ assert.ok(files.indexOf(fn) >= 0, "couldn't find '" + fn + "'");
+ var stat = fs.statSync(common.tmpDir + '/' + fn);
+ assert.equal(image.length, stat.size,
+ "size doesn't match on '" + fn +
+ "'. Got " + stat.size + " bytes");
+ }
+
+ checkedFiles = true;
+}
+
+
+process.on('exit', function() {
+ assert.equal(total, requests);
+ assert.equal(total, responses);
+ assert.ok(checkedFiles);
+});

0 comments on commit 36e75b7

Please sign in to comment.