net: Defer reading until listeners could be added
Defer reading until user-land has a chance to add listeners. This allows the TLS wrapper to listen for _tlsError and trigger a clientError event if the socket already has data that could trigger. Fixes: https://github.com/nodejs/io.js/issues/1114 PR-URL: https://github.com/nodejs/io.js/pull/1496 Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com> Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>
This commit is contained in:
parent
7a3006efe4
commit
061342a500
@ -209,6 +209,20 @@ function onocspresponse(resp) {
|
|||||||
this.emit('OCSPResponse', resp);
|
this.emit('OCSPResponse', resp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function initRead(tls, wrapped) {
|
||||||
|
// If we were destroyed already don't bother reading
|
||||||
|
if (!tls._handle)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Socket already has some buffered data - emulate receiving it
|
||||||
|
if (wrapped && wrapped._readableState && wrapped._readableState.length) {
|
||||||
|
var buf;
|
||||||
|
while ((buf = wrapped.read()) !== null)
|
||||||
|
tls._handle.receive(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
tls.read(0);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a wrap of socket stream to do encrypted communication.
|
* Provides a wrap of socket stream to do encrypted communication.
|
||||||
@ -257,7 +271,9 @@ function TLSSocket(socket, options) {
|
|||||||
// starting the flow of the data
|
// starting the flow of the data
|
||||||
this.readable = true;
|
this.readable = true;
|
||||||
this.writable = true;
|
this.writable = true;
|
||||||
this.read(0);
|
|
||||||
|
// Read on next tick so the caller has a chance to setup listeners
|
||||||
|
process.nextTick(initRead, this, socket);
|
||||||
}
|
}
|
||||||
util.inherits(TLSSocket, net.Socket);
|
util.inherits(TLSSocket, net.Socket);
|
||||||
exports.TLSSocket = TLSSocket;
|
exports.TLSSocket = TLSSocket;
|
||||||
@ -416,13 +432,6 @@ TLSSocket.prototype._init = function(socket, wrap) {
|
|||||||
if (options.handshakeTimeout > 0)
|
if (options.handshakeTimeout > 0)
|
||||||
this.setTimeout(options.handshakeTimeout, this._handleTimeout);
|
this.setTimeout(options.handshakeTimeout, this._handleTimeout);
|
||||||
|
|
||||||
// Socket already has some buffered data - emulate receiving it
|
|
||||||
if (socket && socket._readableState && socket._readableState.length) {
|
|
||||||
var buf;
|
|
||||||
while ((buf = socket.read()) !== null)
|
|
||||||
ssl.receive(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (socket instanceof net.Socket) {
|
if (socket instanceof net.Socket) {
|
||||||
this._parent = socket;
|
this._parent = socket;
|
||||||
|
|
||||||
|
46
test/parallel/test-tls-delayed-attach-error.js
Normal file
46
test/parallel/test-tls-delayed-attach-error.js
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
'use strict';
|
||||||
|
var common = require('../common');
|
||||||
|
var assert = require('assert');
|
||||||
|
|
||||||
|
if (!common.hasCrypto) {
|
||||||
|
console.log('1..0 # Skipped: missing crypto');
|
||||||
|
process.exit();
|
||||||
|
}
|
||||||
|
var tls = require('tls');
|
||||||
|
var fs = require('fs');
|
||||||
|
var net = require('net');
|
||||||
|
|
||||||
|
var bonkers = new Buffer(1024);
|
||||||
|
bonkers.fill(42);
|
||||||
|
|
||||||
|
var receivedError = false;
|
||||||
|
var options = {
|
||||||
|
key: fs.readFileSync(common.fixturesDir + '/keys/agent1-key.pem'),
|
||||||
|
cert: fs.readFileSync(common.fixturesDir + '/keys/agent1-cert.pem')
|
||||||
|
};
|
||||||
|
|
||||||
|
var server = net.createServer(function(c) {
|
||||||
|
setTimeout(function() {
|
||||||
|
var s = new tls.TLSSocket(c, {
|
||||||
|
isServer: true,
|
||||||
|
secureContext: tls.createSecureContext(options)
|
||||||
|
});
|
||||||
|
|
||||||
|
s.on('_tlsError', function() {
|
||||||
|
receivedError = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
s.on('close', function() {
|
||||||
|
server.close();
|
||||||
|
s.destroy();
|
||||||
|
});
|
||||||
|
}, 200);
|
||||||
|
}).listen(common.PORT, function() {
|
||||||
|
var c = net.connect({port: common.PORT}, function() {
|
||||||
|
c.write(bonkers);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
process.on('exit', function() {
|
||||||
|
assert.ok(receivedError);
|
||||||
|
});
|
@ -13,7 +13,6 @@ var net = require('net');
|
|||||||
|
|
||||||
var sent = 'hello world';
|
var sent = 'hello world';
|
||||||
var received = '';
|
var received = '';
|
||||||
var ended = 0;
|
|
||||||
|
|
||||||
var options = {
|
var options = {
|
||||||
key: fs.readFileSync(common.fixturesDir + '/keys/agent1-key.pem'),
|
key: fs.readFileSync(common.fixturesDir + '/keys/agent1-key.pem'),
|
||||||
@ -32,7 +31,6 @@ var server = net.createServer(function(c) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
s.on('end', function() {
|
s.on('end', function() {
|
||||||
ended++;
|
|
||||||
server.close();
|
server.close();
|
||||||
s.destroy();
|
s.destroy();
|
||||||
});
|
});
|
||||||
@ -47,5 +45,4 @@ var server = net.createServer(function(c) {
|
|||||||
|
|
||||||
process.on('exit', function() {
|
process.on('exit', function() {
|
||||||
assert.equal(received, sent);
|
assert.equal(received, sent);
|
||||||
assert.equal(ended, 1);
|
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user