Skip to content

Commit 061342a

Browse files
jameshartigbrendanashworth
authored andcommitted
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: #1114 PR-URL: #1496 Reviewed-By: Chris Dickinson <[email protected]> Reviewed-By: Fedor Indutny <[email protected]>
1 parent 7a3006e commit 061342a

File tree

3 files changed

+63
-11
lines changed

3 files changed

+63
-11
lines changed

lib/_tls_wrap.js

+17-8
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,20 @@ function onocspresponse(resp) {
209209
this.emit('OCSPResponse', resp);
210210
}
211211

212+
function initRead(tls, wrapped) {
213+
// If we were destroyed already don't bother reading
214+
if (!tls._handle)
215+
return;
216+
217+
// Socket already has some buffered data - emulate receiving it
218+
if (wrapped && wrapped._readableState && wrapped._readableState.length) {
219+
var buf;
220+
while ((buf = wrapped.read()) !== null)
221+
tls._handle.receive(buf);
222+
}
223+
224+
tls.read(0);
225+
}
212226

213227
/**
214228
* Provides a wrap of socket stream to do encrypted communication.
@@ -257,7 +271,9 @@ function TLSSocket(socket, options) {
257271
// starting the flow of the data
258272
this.readable = true;
259273
this.writable = true;
260-
this.read(0);
274+
275+
// Read on next tick so the caller has a chance to setup listeners
276+
process.nextTick(initRead, this, socket);
261277
}
262278
util.inherits(TLSSocket, net.Socket);
263279
exports.TLSSocket = TLSSocket;
@@ -416,13 +432,6 @@ TLSSocket.prototype._init = function(socket, wrap) {
416432
if (options.handshakeTimeout > 0)
417433
this.setTimeout(options.handshakeTimeout, this._handleTimeout);
418434

419-
// Socket already has some buffered data - emulate receiving it
420-
if (socket && socket._readableState && socket._readableState.length) {
421-
var buf;
422-
while ((buf = socket.read()) !== null)
423-
ssl.receive(buf);
424-
}
425-
426435
if (socket instanceof net.Socket) {
427436
this._parent = socket;
428437

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
'use strict';
2+
var common = require('../common');
3+
var assert = require('assert');
4+
5+
if (!common.hasCrypto) {
6+
console.log('1..0 # Skipped: missing crypto');
7+
process.exit();
8+
}
9+
var tls = require('tls');
10+
var fs = require('fs');
11+
var net = require('net');
12+
13+
var bonkers = new Buffer(1024);
14+
bonkers.fill(42);
15+
16+
var receivedError = false;
17+
var options = {
18+
key: fs.readFileSync(common.fixturesDir + '/keys/agent1-key.pem'),
19+
cert: fs.readFileSync(common.fixturesDir + '/keys/agent1-cert.pem')
20+
};
21+
22+
var server = net.createServer(function(c) {
23+
setTimeout(function() {
24+
var s = new tls.TLSSocket(c, {
25+
isServer: true,
26+
secureContext: tls.createSecureContext(options)
27+
});
28+
29+
s.on('_tlsError', function() {
30+
receivedError = true;
31+
});
32+
33+
s.on('close', function() {
34+
server.close();
35+
s.destroy();
36+
});
37+
}, 200);
38+
}).listen(common.PORT, function() {
39+
var c = net.connect({port: common.PORT}, function() {
40+
c.write(bonkers);
41+
});
42+
});
43+
44+
process.on('exit', function() {
45+
assert.ok(receivedError);
46+
});

test/parallel/test-tls-delayed-attach.js

-3
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ var net = require('net');
1313

1414
var sent = 'hello world';
1515
var received = '';
16-
var ended = 0;
1716

1817
var options = {
1918
key: fs.readFileSync(common.fixturesDir + '/keys/agent1-key.pem'),
@@ -32,7 +31,6 @@ var server = net.createServer(function(c) {
3231
});
3332

3433
s.on('end', function() {
35-
ended++;
3634
server.close();
3735
s.destroy();
3836
});
@@ -47,5 +45,4 @@ var server = net.createServer(function(c) {
4745

4846
process.on('exit', function() {
4947
assert.equal(received, sent);
50-
assert.equal(ended, 1);
5148
});

0 commit comments

Comments
 (0)