From bb621f7c2eb9561af6bca34549294b381a98cdac Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Wed, 13 Apr 2011 13:54:47 -0700 Subject: [PATCH] CryptoStream.write returns false when queue > 128kb Previously the return value of write was dependent on if it was paused or not which was causing a strange error demoed in the previous commit. Fixes #892 --- lib/tls.js | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/lib/tls.js b/lib/tls.js index 0adba535e8..b34ed95204 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; }