Skip to content

Commit 1a3ca82

Browse files
committed
http_client: ensure empty socket on error
Read all pending data out of the socket on `error` event and ensure that no `data`/`end` handlers will be invoked on `socket.destroy()`. Otherwise following assertion happens: AssertionError: null == true at TLSSocket.socketOnData (_http_client.js:308:3) at TLSSocket.emit (events.js:107:17) at TLSSocket.Readable.read (_stream_readable.js:373:10) at TLSSocket.socketCloseListener (_http_client.js:229:10) at TLSSocket.emit (events.js:129:20) at TCP.close (net.js:476:12) Fix: nodejs/node-v0.x-archive#9348 PR-URL: #1103 Reviewed-By: Rod Vagg <[email protected]> Reviewed-By: Nicu Micleușanu <[email protected]>
1 parent 8670613 commit 1a3ca82

File tree

2 files changed

+50
-1
lines changed

2 files changed

+50
-1
lines changed

lib/_http_client.js

+8-1
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,6 @@ function socketCloseListener() {
247247

248248
function socketErrorListener(err) {
249249
var socket = this;
250-
var parser = socket.parser;
251250
var req = socket._httpMessage;
252251
debug('SOCKET ERROR:', err.message, err.stack);
253252

@@ -258,10 +257,18 @@ function socketErrorListener(err) {
258257
req.socket._hadError = true;
259258
}
260259

260+
// Handle any pending data
261+
socket.read();
262+
263+
var parser = socket.parser;
261264
if (parser) {
262265
parser.finish();
263266
freeParser(parser, req, socket);
264267
}
268+
269+
// Ensure that no further data will come out of the socket
270+
socket.removeListener('data', socketOnData);
271+
socket.removeListener('end', socketOnEnd);
265272
socket.destroy();
266273
}
267274

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
var net = require('net');
2+
var http = require('http');
3+
var util = require('util');
4+
5+
function Agent() {
6+
http.Agent.call(this);
7+
}
8+
util.inherits(Agent, http.Agent);
9+
10+
Agent.prototype.createConnection = function() {
11+
var self = this;
12+
var socket = new net.Socket();
13+
14+
socket.on('error', function() {
15+
socket.push('HTTP/1.1 200\r\n\r\n');
16+
});
17+
18+
socket.on('newListener', function onNewListener(name) {
19+
if (name !== 'error')
20+
return;
21+
socket.removeListener('newListener', onNewListener);
22+
23+
// Let other listeners to be set up too
24+
process.nextTick(function() {
25+
self.breakSocket(socket);
26+
});
27+
});
28+
29+
return socket;
30+
};
31+
32+
Agent.prototype.breakSocket = function breakSocket(socket) {
33+
socket.emit('error', new Error('Intentional error'));
34+
};
35+
36+
var agent = new Agent();
37+
38+
http.request({
39+
agent: agent
40+
}).once('error', function() {
41+
console.log('ignore');
42+
});

0 commit comments

Comments
 (0)