Browse Source

cleartextstream.destroy() should destroy socket.

This fixes a critical bug see in MJR's production. Very difficult to build a
test case. Sometimes HTTPS server gets sockets that are hanging in a
half-duplex state.
v0.7.4-release
Ryan Dahl 14 years ago
parent
commit
75a0cf970f
  1. 22
      lib/stream.js
  2. 5
      lib/tls.js
  3. 2
      test/simple/test-https-eof-for-eom.js
  4. 4
      test/simple/test-stream-pipe-cleanup.js

22
lib/stream.js

@ -53,7 +53,7 @@ Stream.prototype.pipe = function(dest, options) {
dest._pipeCount++;
source.on('end', onend);
source.on('close', onend);
source.on('close', onclose);
}
var didOnEnd = false;
@ -74,6 +74,24 @@ Stream.prototype.pipe = function(dest, options) {
dest.end();
}
function onclose() {
if (didOnEnd) return;
didOnEnd = true;
dest._pipeCount--;
// remove the listeners
cleanup();
if (dest._pipeCount > 0) {
// waiting for other incoming streams to end.
return;
}
dest.destroy();
}
// don't leave dangling pipes when there are errors.
function onerror(er) {
cleanup();
@ -117,7 +135,7 @@ Stream.prototype.pipe = function(dest, options) {
dest.removeListener('drain', ondrain);
source.removeListener('end', onend);
source.removeListener('close', onend);
source.removeListener('close', onclose);
dest.removeListener('pause', onpause);
dest.removeListener('resume', onresume);

5
lib/tls.js

@ -608,12 +608,7 @@ SecurePair.prototype._destroy = function() {
self.cleartext.writable = self.cleartext.readable = false;
process.nextTick(function() {
self.encrypted.emit('end');
if (self.encrypted.onend) self.encrypted.onend();
self.encrypted.emit('close');
self.cleartext.emit('end');
if (self.cleartext.onend) self.cleartext.onend();
self.cleartext.emit('close');
});
}

2
test/simple/test-https-eof-for-eom.js

@ -83,7 +83,7 @@ server.listen(common.PORT, function() {
bodyBuffer += s;
});
res.on('end', function() {
res.on('close', function() {
console.log('5) Client got "end" event.');
gotEnd = true;
});

4
test/simple/test-stream-pipe-cleanup.js

@ -36,6 +36,10 @@ Writable.prototype.end = function () {
this.endCalls++;
}
Writable.prototype.destroy = function () {
this.endCalls++;
}
function Readable () {
this.readable = true;
stream.Stream.call(this);

Loading…
Cancel
Save