TLS: Simplify code from suck and blow
authorRyan Dahl <ry@tinyclouds.org>
Sat, 11 Dec 2010 09:42:34 +0000 (01:42 -0800)
committerRyan Dahl <ry@tinyclouds.org>
Sat, 11 Dec 2010 09:42:55 +0000 (01:42 -0800)
lib/tls.js

index 474f801..3598078 100644 (file)
@@ -93,73 +93,58 @@ CryptoStream.prototype.destroy = function(err) {
 };
 
 
-function CleartextStream (pair) {
-  CryptoStream.call(this, pair);
-}
-util.inherits(CleartextStream, CryptoStream);
-
-
-// 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;
-      });
-};
-
+// also
+// 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);
+//   });
+//
+CryptoStream.prototype._blow = function() {
+  var bytesRead;
+  var pool;
+  var chunkBytes;
+  var chunk;
 
+  do {
+    bytesRead = 0;
+    chunkBytes = 0;
+    pool = new Buffer(4096); // alloc every time?
+    pool.used = 0;
 
+    do {
+      try {
+        chunkBytes = this._blower(pool,
+                                  pool.used + bytesRead,
+                                  pool.length - pool.used - bytesRead);
+      } catch (e) {
+        return this.pair._error(e);
+      }
+      if (chunkBytes >= 0) {
+        bytesRead += chunkBytes;
+      }
+    } while ((chunkBytes > 0) && (pool.used + bytesRead < pool.length));
 
-function EncryptedStream (pair) {
-  CryptoStream.call(this, pair);
-}
-util.inherits(EncryptedStream, CryptoStream);
+    if (bytesRead > 0) {
+      chunk = pool.slice(0, bytesRead);
+      this.emit('data', chunk);
+    }
+  } while (bytesRead > 0 && this._writeState === true);
+};
 
 
+// Push in any clear data coming from the application.
+// This arrives via some code like this:
+//
+//   pair.cleartext.write("hello world");
+//
+// also
+//
 // Push in incoming encrypted data from the socket.
 // This arrives via some code like this:
 //
@@ -167,15 +152,14 @@ util.inherits(EncryptedStream, CryptoStream);
 //     pair.encrypted.write(d)
 //   });
 //
-EncryptedStream.prototype._suck = function() {
+CryptoStream.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);
+      rv = this._sucker(tmp);
     } catch (e) {
       return this.pair._error(e);
     }
@@ -190,39 +174,48 @@ EncryptedStream.prototype._suck = function() {
 
   // If we've cleared all of incoming encrypted data, emit drain.
   if (havePending && this._pending && this._pending.length === 0) {
-    debug('encrypted drain');
+    debug('drain');
     this.emit('drain');
   }
+};
+
+
+function CleartextStream (pair) {
+  CryptoStream.call(this, pair);
 }
+util.inherits(CleartextStream, CryptoStream);
 
 
-// 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;
+CleartextStream.prototype._sucker = function(b) {
+  debug('writng from clearIn');
+  return this.pair._ssl.clearIn(b, 0, b.length);
+};
+
+
+CleartextStream.prototype._blower = function(pool, offset, length) {
+  debug('reading from clearOut');
+  return this.pair._ssl.clearOut(pool, offset, length);
+};
+
 
-  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;
-      });
+function EncryptedStream (pair) {
+  CryptoStream.call(this, pair);
+}
+util.inherits(EncryptedStream, CryptoStream);
+
+
+EncryptedStream.prototype._sucker = function(b) {
+  debug('writing from encIn');
+  return this.pair._ssl.encIn(b, 0, b.length);
 };
 
 
+EncryptedStream.prototype._blower = function(pool, offset, length) {
+  debug('reading from encOut');
+  if (!this.pair._ssl) return -1;
+  return this.pair._ssl.encOut(pool, offset, length);
+};
+
 
 /**
  * Provides a pair of streams to do encrypted communication.
@@ -304,37 +297,6 @@ exports.createSecurePair = function(credentials,
 };
 
 
-SecurePair.prototype._mover = function(reader, writer, checker) {
-  var bytesRead;
-  var pool;
-  var chunkBytes;
-  var chunk;
-
-  do {
-    bytesRead = 0;
-    chunkBytes = 0;
-    pool = new Buffer(4096); // alloc every time?
-    pool.used = 0;
-
-    do {
-      try {
-        chunkBytes = reader(pool,
-                            pool.used + bytesRead,
-                            pool.length - pool.used - bytesRead);
-      } catch (e) {
-        return this._error(e);
-      }
-      if (chunkBytes >= 0) {
-        bytesRead += chunkBytes;
-      }
-    } while ((chunkBytes > 0) && (pool.used + bytesRead < pool.length));
-
-    if (bytesRead > 0) {
-      chunk = pool.slice(0, bytesRead);
-      writer(chunk);
-    }
-  } while (bytesRead > 0 && checker());
-};
 
 
 /**