Factor out some _cycle functionality into Cleartext and EncrypteStreams
authorRyan Dahl <ry@tinyclouds.org>
Sat, 11 Dec 2010 06:29:46 +0000 (22:29 -0800)
committerRyan Dahl <ry@tinyclouds.org>
Sat, 11 Dec 2010 06:29:46 +0000 (22:29 -0800)
lib/tls.js

index f9cfd23..0407e79 100644 (file)
@@ -86,6 +86,60 @@ CleartextStream.prototype.end = function(err) {
   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);
@@ -104,6 +158,68 @@ EncryptedStream.prototype.end = function(err) {
 };
 
 
+// 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;
+      });
+};
+
 
 
 /**
@@ -252,114 +368,10 @@ SecurePair.prototype._cycle = function() {
     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;