@ -362,6 +362,16 @@ CryptoStream.prototype._write = function write(data, encoding, cb) {
return cb ( this . pair . error ( true ) ) ;
return cb ( this . pair . error ( true ) ) ;
}
}
// Force SSL_read call to cycle some states/data inside OpenSSL
this . pair . cleartext . read ( 0 ) ;
// Cycle encrypted data
if ( this . pair . encrypted . _ internallyPendingBytes ( ) )
this . pair . encrypted . read ( 0 ) ;
// Get NPN and Server name when ready
this . pair . maybeInitFinished ( ) ;
// Whole buffer was written
// Whole buffer was written
if ( written === data . length ) {
if ( written === data . length ) {
if ( this === this . pair . cleartext ) {
if ( this === this . pair . cleartext ) {
@ -377,19 +387,6 @@ CryptoStream.prototype._write = function write(data, encoding, cb) {
} else {
} else {
cb ( null ) ;
cb ( null ) ;
}
}
}
// Force SSL_read call to cycle some states/data inside OpenSSL
this . pair . cleartext . read ( 0 ) ;
// Cycle encrypted data
if ( this . pair . encrypted . _ internallyPendingBytes ( ) )
this . pair . encrypted . read ( 0 ) ;
// Get NPN and Server name when ready
this . pair . maybeInitFinished ( ) ;
if ( written === data . length ) {
return ;
return ;
} else if ( written !== 0 && written !== - 1 ) {
} else if ( written !== 0 && written !== - 1 ) {
assert ( ! this . _ retryAfterPartial ) ;
assert ( ! this . _ retryAfterPartial ) ;
@ -521,6 +518,7 @@ CryptoStream.prototype._read = function read(size) {
this . _ halfRead = halfRead ;
this . _ halfRead = halfRead ;
// Notify listeners about internal data end
// Notify listeners about internal data end
if ( ! halfRead ) {
if ( this === this . pair . cleartext ) {
if ( this === this . pair . cleartext ) {
debug ( 'cleartext.sslOutEnd' ) ;
debug ( 'cleartext.sslOutEnd' ) ;
} else {
} else {
@ -529,6 +527,7 @@ CryptoStream.prototype._read = function read(size) {
this . emit ( 'sslOutEnd' ) ;
this . emit ( 'sslOutEnd' ) ;
}
}
}
} ;
} ;
@ -640,10 +639,19 @@ CryptoStream.prototype.destroySoon = function(err) {
if ( this . writable )
if ( this . writable )
this . end ( ) ;
this . end ( ) ;
if ( this . _ writableState . finished && this . _ opposite . _ ended )
if ( this . _ writableState . finished && this . _ opposite . _ ended ) {
this . destroy ( ) ;
this . destroy ( ) ;
else
} else {
this . once ( 'finish' , this . destroy ) ;
// Wait for both `finish` and `end` events to ensure that all data that
// was written on this side was read from the other side.
var self = this ;
var waiting = 2 ;
function finish ( ) {
if ( -- waiting === 0 ) self . destroy ( ) ;
}
this . _ opposite . once ( 'end' , finish ) ;
this . once ( 'finish' , finish ) ;
}
} ;
} ;
@ -1379,6 +1387,9 @@ function pipe(pair, socket) {
pair . encrypted . on ( 'close' , function ( ) {
pair . encrypted . on ( 'close' , function ( ) {
process . nextTick ( function ( ) {
process . nextTick ( function ( ) {
// Encrypted should be unpiped from socket to prevent possible
// write after destroy.
pair . encrypted . unpipe ( socket ) ;
socket . destroy ( ) ;
socket . destroy ( ) ;
} ) ;
} ) ;
} ) ;
} ) ;