this.pair._destroy(err);
};
+// Push in any clear data coming from the application.
+// This arrives via some code like this:
+//
+// pair.cleartext.write("hello world");
+//
+CleartextStream.prototype._suck = function() {
+ var tmp, rv;
+ var havePending = this._pending.length > 0;
+
+ while (this._pending.length > 0) {
+ tmp = this._pending.shift();
+ try {
+ debug('writng from clearIn');
+ rv = this.pair._ssl.clearIn(tmp, 0, tmp.length);
+ } catch (e) {
+ return this.pair._error(e);
+ }
+
+ if (rv === 0) {
+ this._pending.unshift(tmp);
+ break;
+ }
+
+ assert(rv === tmp.length);
+ }
+
+ // If we've cleared all of incoming cleartext data, emit drain.
+ if (havePending && this._pending.length === 0) {
+ debug('cleartext drain');
+ this.emit('drain');
+ }
+};
+
+
+// Move decrypted, clear data out into the application.
+// From the user's perspective this occurs as a 'data' event
+// on the pair.cleartext.
+CleartextStream.prototype._blow = function() {
+ var self = this;
+ self.pair._mover(
+ function(pool, offset, length) {
+ debug('reading from clearOut');
+ return self.pair._ssl.clearOut(pool, offset, length);
+ },
+ function(chunk) {
+ self.emit('data', chunk);
+ },
+ function() {
+ return self._writeState === true;
+ });
+};
+
+
+
function EncryptedStream (pair) {
CryptoStream.call(this, pair);
};
+// Push in incoming encrypted data from the socket.
+// This arrives via some code like this:
+//
+// socket.on('data', function (d) {
+// pair.encrypted.write(d)
+// });
+//
+EncryptedStream.prototype._suck = function() {
+ var tmp, rv;
+ var havePending = this._pending.length > 0;
+ while (this._pending.length > 0) {
+ tmp = this._pending.shift();
+
+ try {
+ debug('writing from encIn');
+ rv = this.pair._ssl.encIn(tmp, 0, tmp.length);
+ } catch (e) {
+ return this.pair._error(e);
+ }
+
+ if (rv === 0) {
+ this._pending.unshift(tmp);
+ break;
+ }
+
+ assert(rv === tmp.length);
+ }
+
+ // If we've cleared all of incoming encrypted data, emit drain.
+ if (havePending && this._pending && this._pending.length === 0) {
+ debug('encrypted drain');
+ this.emit('drain');
+ }
+}
+
+
+// Move encrypted data to the stream. From the user's perspective this
+// occurs as a 'data' event on the pair.encrypted. Usually the application
+// will have some code which pipes the stream to a socket:
+//
+// pair.encrypted.on('data', function (d) {
+// socket.write(d);
+// });
+//
+EncryptedStream.prototype._blow = function () {
+ var self = this;
+
+ self.pair._mover(
+ function(pool, offset, length) {
+ debug('reading from encOut');
+ if (!self.pair._ssl) return -1;
+ return self.pair._ssl.encOut(pool, offset, length);
+ },
+ function(chunk) {
+ self.emit('data', chunk);
+ },
+ function() {
+ if (!self.pair._ssl) return false;
+ return self._writeState === true;
+ });
+};
+
/**
return;
}
- var self = this;
- var rv;
- var tmp;
- var bytesRead;
- var bytesWritten;
- var chunk = null;
- var pool = null;
-
- // Pull in incoming encrypted data from the socket.
- // This arrives via some code like this:
- //
- // socket.on('data', function (d) {
- // pair.encrypted.write(d)
- // });
- //
- var encPending = this.encrypted._pending.length > 0;
- while (this.encrypted._pending.length > 0) {
- tmp = this.encrypted._pending.shift();
-
- try {
- debug('writing from encIn');
- rv = this._ssl.encIn(tmp, 0, tmp.length);
- } catch (e) {
- return this._error(e);
- }
-
- if (rv === 0) {
- this.encrypted._pending.unshift(tmp);
- break;
- }
-
- assert(rv === tmp.length);
- }
-
- // If we've cleared all of incoming encrypted data, emit drain.
- if (this.encrypted._pending && this.encrypted._pending.length === 0) {
- debug('encrypted drain');
- this.encrypted.emit('drain');
- }
-
-
- // Pull in any clear data coming from the application.
- // This arrives via some code like this:
- //
- // pair.cleartext.write("hello world");
- //
- var clearPending = this.cleartext._pending.length > 0;
- while (this.cleartext._pending.length > 0) {
- tmp = this.cleartext._pending.shift();
- try {
- debug('writng from clearIn');
- rv = this._ssl.clearIn(tmp, 0, tmp.length);
- } catch (e) {
- return this._error(e);
- }
-
- if (rv === 0) {
- this.cleartext._pending.unshift(tmp);
- break;
- }
-
- assert(rv === tmp.length);
- }
-
- // If we've cleared all of incoming cleartext data, emit drain.
- if (clearPending && this.cleartext._pending.length === 0) {
- debug('cleartext drain');
- this.cleartext.emit('drain');
- }
-
-
- // Move decrypted, clear data out into the application.
- // From the user's perspective this occurs as a 'data' event
- // on the pair.cleartext.
- this._mover(
- function(pool, offset, length) {
- debug('reading from clearOut');
- return self._ssl.clearOut(pool, offset, length);
- },
- function(chunk) {
- self.cleartext.emit('data', chunk);
- },
- function() {
- return self.cleartext._writeState === true;
- });
-
- // Move encrypted data to the stream. From the user's perspective this
- // occurs as a 'data' event on the pair.encrypted. Usually the application
- // will have some code which pipes the stream to a socket:
- //
- // pair.encrypted.on('data', function (d) {
- // socket.write(d);
- // });
- //
- this._mover(
- function(pool, offset, length) {
- debug('reading from encOut');
- if (!self._ssl) return -1;
- return self._ssl.encOut(pool, offset, length);
- },
- function(chunk) {
- self.encrypted.emit('data', chunk);
- },
- function() {
- if (!self._ssl) return false;
- return self.encrypted._writeState === true;
- });
-
+ this.encrypted._suck();
+ this.cleartext._suck();
+ this.cleartext._blow();
+ this.encrypted._blow();
if (this._ssl && !this._secureEstablished && this._ssl.isInitFinished()) {
this._secureEstablished = true;