Browse Source

http: make request.abort() destroy the socket

`request.abort()` did not destroy the socket if it was called
before a socket was assigned to the request and the request
did not use an `Agent` or a Unix Domain Socket was used.

Fixes: https://github.com/nodejs/node/issues/10812
PR-URL: https://github.com/nodejs/node/pull/10818
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
v4.x
Luigi Pinca 8 years ago
committed by Myles Borins
parent
commit
48b5097ea8
No known key found for this signature in database GPG Key ID: 933B01F40B5CA946
  1. 6
      lib/_http_client.js
  2. 36
      test/parallel/test-http-abort-queued-2.js
  3. 19
      test/parallel/test-http-client-abort-no-agent.js
  4. 24
      test/parallel/test-http-client-abort-unix-socket.js

6
lib/_http_client.js

@ -530,7 +530,11 @@ ClientRequest.prototype.onSocket = function(socket) {
function onSocketNT(req, socket) { function onSocketNT(req, socket) {
if (req.aborted) { if (req.aborted) {
// If we were aborted while waiting for a socket, skip the whole thing. // If we were aborted while waiting for a socket, skip the whole thing.
socket.emit('free'); if (req.socketPath || !req.agent) {
socket.destroy();
} else {
socket.emit('free');
}
} else { } else {
tickOnSocket(req, socket); tickOnSocket(req, socket);
} }

36
test/parallel/test-http-abort-queued-2.js

@ -0,0 +1,36 @@
'use strict';
const common = require('../common');
const assert = require('assert');
const http = require('http');
let socketsCreated = 0;
class Agent extends http.Agent {
createConnection(options, oncreate) {
const socket = super.createConnection(options, oncreate);
socketsCreated++;
return socket;
}
}
const server = http.createServer((req, res) => res.end());
server.listen(0, common.mustCall(() => {
const port = server.address().port;
const agent = new Agent({
keepAlive: true,
maxSockets: 1
});
http.get({agent, port}, (res) => res.resume());
const req = http.get({agent, port}, common.fail);
req.abort();
http.get({agent, port}, common.mustCall((res) => {
res.resume();
assert.strictEqual(socketsCreated, 1);
agent.destroy();
server.close();
}));
}));

19
test/parallel/test-http-client-abort-no-agent.js

@ -0,0 +1,19 @@
'use strict';
const common = require('../common');
const http = require('http');
const net = require('net');
const server = http.createServer(common.fail);
server.listen(0, common.mustCall(() => {
const req = http.get({
createConnection(options, oncreate) {
const socket = net.createConnection(options, oncreate);
socket.once('close', () => server.close());
return socket;
},
port: server.address().port
});
req.abort();
}));

24
test/parallel/test-http-client-abort-unix-socket.js

@ -0,0 +1,24 @@
'use strict';
const common = require('../common');
const http = require('http');
const server = http.createServer(common.fail);
class Agent extends http.Agent {
createConnection(options, oncreate) {
const socket = super.createConnection(options, oncreate);
socket.once('close', () => server.close());
return socket;
}
}
common.refreshTmpDir();
server.listen(common.PIPE, common.mustCall(() => {
const req = http.get({
agent: new Agent(),
socketPath: common.PIPE
});
req.abort();
}));
Loading…
Cancel
Save