@@ -52,6 +52,7 @@ function CryptoStream(pair) {
5252 this . readable = this . writable = true ;
5353
5454 this . _paused = false ;
55+ this . _needDrain = false ;
5556 this . _pending = [ ] ;
5657 this . _pendingCallbacks = [ ] ;
5758 this . _pendingBytes = 0 ;
@@ -86,7 +87,7 @@ CryptoStream.prototype.write = function(data /* , encoding, cb */) {
8687 data = new Buffer ( data , encoding ) ;
8788 }
8889
89- debug ( 'clearIn data') ;
90+ debug ( ( this === this . pair . cleartext ? 'clear' : 'encrypted' ) + 'In data') ;
9091
9192 this . _pending . push ( data ) ;
9293 this . _pendingCallbacks . push ( cb ) ;
@@ -95,7 +96,26 @@ CryptoStream.prototype.write = function(data /* , encoding, cb */) {
9596 this . pair . _writeCalled = true ;
9697 this . pair . cycle ( ) ;
9798
98- return this . _pendingBytes < 128 * 1024 ;
99+ // In the following cases, write() should return a false,
100+ // then this stream should eventually emit 'drain' event.
101+ //
102+ // 1. There are pending data more than 128k bytes.
103+ // 2. A forward stream shown below is paused.
104+ // A) EncryptedStream for CleartextStream.write().
105+ // B) CleartextStream for EncryptedStream.write().
106+ //
107+ if ( ! this . _needDrain ) {
108+ if ( this . _pendingBytes >= 128 * 1024 ) {
109+ this . _needDrain = true ;
110+ } else {
111+ if ( this === this . pair . cleartext ) {
112+ this . _needDrain = this . pair . encrypted . _paused ;
113+ } else {
114+ this . _needDrain = this . pair . cleartext . _paused ;
115+ }
116+ }
117+ }
118+ return ! this . _needDrain ;
99119} ;
100120
101121
@@ -380,11 +400,25 @@ CryptoStream.prototype._pull = function() {
380400 assert ( rv === tmp . length ) ;
381401 }
382402
383- // If we've cleared all of incoming encrypted data, emit drain.
384- if ( havePending && this . _pending . length === 0 ) {
385- debug ( 'drain' ) ;
386- this . emit ( 'drain' ) ;
387- if ( this . __destroyOnDrain ) this . end ( ) ;
403+ // If pending data has cleared, 'drain' event should be emitted
404+ // after write() returns a false.
405+ // Except when a forward stream shown below is paused.
406+ // A) EncryptedStream for CleartextStream._pull().
407+ // B) CleartextStream for EncryptedStream._pull().
408+ //
409+ if ( this . _needDrain && this . _pending . length === 0 ) {
410+ var paused ;
411+ if ( this === this . pair . cleartext ) {
412+ paused = this . pair . encrypted . _paused ;
413+ } else {
414+ paused = this . pair . cleartext . _paused ;
415+ }
416+ if ( ! paused ) {
417+ debug ( 'drain' ) ;
418+ process . nextTick ( this . emit . bind ( this , 'drain' ) ) ;
419+ this . _needDrain = false ;
420+ if ( this . __destroyOnDrain ) this . end ( ) ;
421+ }
388422 }
389423} ;
390424
0 commit comments