diff --git a/AUTHORS b/AUTHORS
index 7159091579f..cf29f0189e4 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -167,4 +167,7 @@ Dean McNamee
-
-
+ Download
- 2011.04.01 - node-v0.4.5.tar.gz - (Documentation) + 2011.04.13 + node-v0.4.6.tar.gz + (Documentation)
diff --git a/lib/net.js b/lib/net.js index 52aaefa4d64..26acbb35588 100644 --- a/lib/net.js +++ b/lib/net.js @@ -636,7 +636,11 @@ Socket.prototype._onReadable = function() { pool.length - pool.used); DTRACE_NET_SOCKET_READ(this, bytesRead); } catch (e) { - self.destroy(e); + if (e.code == 'ECONNRESET') { + self.destroy(); + } else { + self.destroy(e); + } return; } diff --git a/lib/stream.js b/lib/stream.js index d31a9fe239a..632c87d2e26 100644 --- a/lib/stream.js +++ b/lib/stream.js @@ -28,9 +28,13 @@ function Stream() { util.inherits(Stream, events.EventEmitter); exports.Stream = Stream; +var pipes = []; + Stream.prototype.pipe = function(dest, options) { var source = this; + pipes.push(dest); + function ondata(chunk) { if (dest.writable) { if (false === dest.write(chunk)) source.pause(); @@ -52,10 +56,18 @@ Stream.prototype.pipe = function(dest, options) { if (!options || options.end !== false) { function onend() { + var index = pipes.indexOf(dest); + pipes.splice(index, 1); + + if (pipes.indexOf(dest) > -1) { + return; + } + dest.end(); } source.on('end', onend); + source.on('close', onend); } /* @@ -73,34 +85,35 @@ Stream.prototype.pipe = function(dest, options) { source.emit('resume'); }; } - + var onpause = function() { source.pause(); } dest.on('pause', onpause); - + var onresume = function() { if (source.readable) source.resume(); }; - + dest.on('resume', onresume); - + var cleanup = function () { source.removeListener('data', ondata); dest.removeListener('drain', ondrain); source.removeListener('end', onend); - + source.removeListener('close', onend); + dest.removeListener('pause', onpause); dest.removeListener('resume', onresume); - + source.removeListener('end', cleanup); source.removeListener('close', cleanup); - + dest.removeListener('end', cleanup); dest.removeListener('close', cleanup); } - + source.on('end', cleanup); source.on('close', cleanup); diff --git a/lib/tls.js b/lib/tls.js index d4599aba383..a8f1898f49c 100644 --- a/lib/tls.js +++ b/lib/tls.js @@ -54,13 +54,14 @@ function CryptoStream(pair) { this._writeState = true; this._pending = []; this._pendingCallbacks = []; + this._pendingBytes = 0; } util.inherits(CryptoStream, stream.Stream); CryptoStream.prototype.write = function(data /* , encoding, cb */) { if (this == this.pair.cleartext) { - debug('cleartext.write called with (((' + data.toString() + ')))'); + debug('cleartext.write called with ' + data.length + ' bytes'); } else { debug('encrypted.write called with ' + data.length + ' bytes'); } @@ -90,10 +91,12 @@ CryptoStream.prototype.write = function(data /* , encoding, cb */) { this._pending.push(data); this._pendingCallbacks.push(cb); + this._pendingBytes += data.length; + this.pair._writeCalled = true; this.pair._cycle(); - return this._writeState; + return this._pendingBytes < 128 * 1024; }; @@ -263,7 +266,7 @@ CryptoStream.prototype._push = function() { // Bail out if we didn't read any data. if (bytesRead == 0) { - if (this._pendingBytes() == 0 && this._destroyAfterPush) { + if (this._internallyPendingBytes() == 0 && this._destroyAfterPush) { this._done(); } return; @@ -272,7 +275,7 @@ CryptoStream.prototype._push = function() { var chunk = pool.slice(0, bytesRead); if (this === this.pair.cleartext) { - debug('cleartext emit "data" called with (((' + chunk.toString() + ')))'); + debug('cleartext emit "data" with ' + bytesRead + ' bytes'); } else { debug('encrypted emit "data" with ' + bytesRead + ' bytes'); } @@ -307,6 +310,8 @@ CryptoStream.prototype._push = function() { CryptoStream.prototype._pull = function() { var havePending = this._pending.length > 0; + assert(havePending || this._pendingBytes == 0); + while (this._pending.length > 0) { if (!this.pair._ssl) break; @@ -355,6 +360,9 @@ CryptoStream.prototype._pull = function() { break; } + this._pendingBytes -= tmp.length; + assert(this._pendingBytes >= 0); + if (cb) cb(); assert(rv === tmp.length); @@ -375,7 +383,7 @@ function CleartextStream(pair) { util.inherits(CleartextStream, CryptoStream); -CleartextStream.prototype._pendingBytes = function() { +CleartextStream.prototype._internallyPendingBytes = function() { if (this.pair._ssl) { return this.pair._ssl.clearPending(); } else { @@ -403,7 +411,7 @@ function EncryptedStream(pair) { util.inherits(EncryptedStream, CryptoStream); -EncryptedStream.prototype._pendingBytes = function() { +EncryptedStream.prototype._internallyPendingBytes = function() { if (this.pair._ssl) { return this.pair._ssl.encPending(); } else { @@ -539,24 +547,28 @@ SecurePair.prototype._cycle = function(depth) { if (!this._cycleEncryptedPullLock) { this._cycleEncryptedPullLock = true; + debug("encrypted._pull"); this.encrypted._pull(); this._cycleEncryptedPullLock = false; } if (!this._cycleCleartextPullLock) { this._cycleCleartextPullLock = true; + debug("cleartext._pull"); this.cleartext._pull(); this._cycleCleartextPullLock = false; } if (!this._cycleCleartextPushLock) { this._cycleCleartextPushLock = true; + debug("cleartext._push"); this.cleartext._push(); this._cycleCleartextPushLock = false; } if (!this._cycleEncryptedPushLock) { this._cycleEncryptedPushLock = true; + debug("encrypted._push"); this.encrypted._push(); this._cycleEncryptedPushLock = false; } @@ -728,7 +740,7 @@ function Server(/* [options], listener */) { secureOptions: self.secureOptions, crl: self.crl }); - //creds.context.setCiphers('RC4-SHA:AES128-SHA:AES256-SHA'); + creds.context.setCiphers('RC4-SHA:AES128-SHA:AES256-SHA'); var pair = new SecurePair(creds, true, diff --git a/test/simple/test-stream-pipe-cleanup.js b/test/simple/test-stream-pipe-cleanup.js index fce4ac82a7d..32ecd153dc8 100644 --- a/test/simple/test-stream-pipe-cleanup.js +++ b/test/simple/test-stream-pipe-cleanup.js @@ -28,10 +28,13 @@ var util = require('util'); function Writable () { this.writable = true; + this.endCalls = 0; stream.Stream.call(this); } util.inherits(Writable, stream.Stream); -Writable.prototype.end = function () {} +Writable.prototype.end = function () { + this.endCalls++; +} function Readable () { this.readable = true; @@ -56,6 +59,9 @@ for (i = 0; i < limit; i++) { r.emit('end') } assert.equal(0, r.listeners('end').length); +assert.equal(limit, w.endCalls); + +w.endCalls = 0; for (i = 0; i < limit; i++) { r = new Readable() @@ -63,6 +69,19 @@ for (i = 0; i < limit; i++) { r.emit('close') } assert.equal(0, r.listeners('close').length); +assert.equal(limit, w.endCalls); + +w.endCalls = 0; + +var r2; +r = new Readable() +r2 = new Readable(); + +r.pipe(w) +r2.pipe(w) +r.emit('close') +r2.emit('close') +assert.equal(1, w.endCalls); r = new Readable(); diff --git a/wscript b/wscript index 16956b75f49..b582b5835af 100644 --- a/wscript +++ b/wscript @@ -889,7 +889,7 @@ def build(bld): , 'CPPFLAGS' : " ".join(program.env["CPPFLAGS"]).replace('"', '\\"') , 'LIBFLAGS' : " ".join(program.env["LIBFLAGS"]).replace('"', '\\"') , 'PREFIX' : safe_path(program.env["PREFIX"]) - , 'VERSION' : '0.4.5' # FIXME should not be hard-coded, see NODE_VERSION_STRING in src/node_version. + , 'VERSION' : '0.4.6' # FIXME should not be hard-coded, see NODE_VERSION_STRING in src/node_version. } return x