@@ -176,6 +176,42 @@ function checkServerIdentity(host, cert) {
176176exports.checkServerIdentity = checkServerIdentity;
177177178178179+180+function SlabBuffer() {
181+this.create();
182+};
183+184+185+SlabBuffer.prototype.create = function create() {
186+this.isFull = false;
187+this.pool = new Buffer(10 * 1024 * 1024);
188+this.offset = 0;
189+this.remaining = this.pool.length;
190+};
191+192+193+SlabBuffer.prototype.use = function use(context, fn) {
194+if (this.remaining === 0) {
195+this.isFull = true;
196+return 0;
197+}
198+199+var bytes = fn.call(context, this.pool, this.offset, this.remaining);
200+201+if (bytes > 0) {
202+this.offset += bytes;
203+this.remaining -= bytes;
204+}
205+206+assert(this.remaining >= 0);
207+208+return bytes;
209+};
210+211+212+var slabBuffer = new SlabBuffer();
213+214+179215// Base class of both CleartextStream and EncryptedStream
180216function CryptoStream(pair) {
181217Stream.call(this);
@@ -189,6 +225,7 @@ function CryptoStream(pair) {
189225this._pending = [];
190226this._pendingCallbacks = [];
191227this._pendingBytes = 0;
228+this._buffer = slabBuffer;
192229}
193230util.inherits(CryptoStream, Stream);
194231@@ -438,18 +475,13 @@ CryptoStream.prototype._push = function() {
438475}
439476440477while (!this._paused) {
441-var chunkBytes = 0;
442-if (!this._pool || (this._poolStart >= this._poolEnd)) {
443-this._pool = new Buffer(16 * 4096);
444-this._poolStart = 0;
445-this._poolEnd = this._pool.length;
446-}
447-var start = this._poolStart;
478+var chunkBytes = 0,
479+bytesRead = 0,
480+start = this._buffer.offset;
448481449482do {
450-chunkBytes = this._pusher(this._pool,
451-this._poolStart,
452-this._poolEnd - this._poolStart);
483+chunkBytes = this._buffer.use(this, this._pusher);
484+if (chunkBytes > 0) bytesRead += chunkBytes;
453485454486if (this.pair.ssl && this.pair.ssl.error) {
455487this.pair.error();
@@ -458,13 +490,12 @@ CryptoStream.prototype._push = function() {
458490459491this.pair.maybeInitFinished();
460492461-if (chunkBytes >= 0) {
462-this._poolStart += chunkBytes;
463-}
493+} while (chunkBytes > 0 && !this._buffer.isFull);
464494465-} while (chunkBytes > 0 && this._poolStart < this._poolEnd);
495+var pool = this._buffer.pool;
466496467-var bytesRead = this._poolStart - start;
497+// Create new buffer if previous was filled up
498+if (this._buffer.isFull) this._buffer.create();
468499469500assert(bytesRead >= 0);
470501@@ -476,7 +507,7 @@ CryptoStream.prototype._push = function() {
476507return;
477508}
478509479-var chunk = this._pool.slice(start, this._poolStart);
510+var chunk = pool.slice(start, start + bytesRead);
480511481512if (this === this.pair.cleartext) {
482513debug('cleartext emit "data" with ' + bytesRead + ' bytes');
@@ -492,7 +523,7 @@ CryptoStream.prototype._push = function() {
492523}
493524494525// Optimization: emit the original buffer with end points
495-if (this.ondata) this.ondata(this._pool, start, this._poolStart);
526+if (this.ondata) this.ondata(pool, start, start + bytesRead);
496527}
497528};
498529