@@ -176,6 +176,42 @@ function checkServerIdentity(host, cert) {
176176exports . checkServerIdentity = checkServerIdentity ;
177177
178178
179+
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 ) {
181217 Stream . call ( this ) ;
@@ -189,6 +225,7 @@ function CryptoStream(pair) {
189225 this . _pending = [ ] ;
190226 this . _pendingCallbacks = [ ] ;
191227 this . _pendingBytes = 0 ;
228+ this . _buffer = slabBuffer ;
192229}
193230util . inherits ( CryptoStream , Stream ) ;
194231
@@ -438,18 +475,13 @@ CryptoStream.prototype._push = function() {
438475 }
439476
440477 while ( ! 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 ;
448481
449482 do {
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 ;
453485
454486 if ( this . pair . ssl && this . pair . ssl . error ) {
455487 this . pair . error ( ) ;
@@ -458,13 +490,12 @@ CryptoStream.prototype._push = function() {
458490
459491 this . pair . maybeInitFinished ( ) ;
460492
461- if ( chunkBytes >= 0 ) {
462- this . _poolStart += chunkBytes ;
463- }
493+ } while ( chunkBytes > 0 && ! this . _buffer . isFull ) ;
464494
465- } while ( chunkBytes > 0 && this . _poolStart < this . _poolEnd ) ;
495+ var pool = this . _buffer . pool ;
466496
467- var bytesRead = this . _poolStart - start ;
497+ // Create new buffer if previous was filled up
498+ if ( this . _buffer . isFull ) this . _buffer . create ( ) ;
468499
469500 assert ( bytesRead >= 0 ) ;
470501
@@ -476,7 +507,7 @@ CryptoStream.prototype._push = function() {
476507 return ;
477508 }
478509
479- var chunk = this . _pool . slice ( start , this . _poolStart ) ;
510+ var chunk = pool . slice ( start , start + bytesRead ) ;
480511
481512 if ( this === this . pair . cleartext ) {
482513 debug ( 'cleartext emit "data" with ' + bytesRead + ' bytes' ) ;
@@ -492,7 +523,7 @@ CryptoStream.prototype._push = function() {
492523 }
493524
494525 // 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
0 commit comments