Skip to content
Next Next commit
http2: add support for AbortSignal to http2Session.request
- Add support
- Add test
- Docs once PR is up
  • Loading branch information
MadaraUchiha committed Nov 21, 2020
commit ba7f38b1f376778f279b22a9a44f56c1079fe3b4
11 changes: 11 additions & 0 deletions lib/internal/http2/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ const {
validateNumber,
validateString,
validateUint32,
validateAbortSignal,
} = require('internal/validators');
const fsPromisesInternal = require('internal/fs/promises');
const { utcDate } = require('internal/http');
Expand Down Expand Up @@ -1721,6 +1722,16 @@ class ClientHttp2Session extends Http2Session {
if (options.waitForTrailers)
stream[kState].flags |= STREAM_FLAGS_HAS_TRAILERS;

const signal = options.signal;
if (options.signal) {
validateAbortSignal(signal, 'options.signal');
const listener = () => stream.destroy();
signal.addEventListener('abort', listener);
stream.once('close', () => {
signal.removeEventListener('abort', listener);
})
}

const onConnect = FunctionPrototypeBind(requestOnConnect,
stream, headersList, options);
if (this.connecting) {
Expand Down
29 changes: 29 additions & 0 deletions test/parallel/test-http2-client-destroy.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,3 +167,32 @@ const Countdown = require('../common/countdown');
req.on('close', common.mustCall(() => server.close()));
}));
}

// Destroy with AbortSignal
{
const server = h2.createServer();
const controller = new AbortController();

server.on('stream', common.mustNotCall());
server.listen(0, common.mustCall(() => {
const client = h2.connect(`http://localhost:${server.address().port}`);
client.on('close', common.mustCall());
const socket = client[kSocket];
socket.on('close', common.mustCall(() => {
assert(socket.destroyed);
}));

const req = client.request({}, { signal: controller.signal });
client.on('error', common.mustCall((err) => {
assert.strictEqual(err.code, 'ECONNREFUSED');
server.close();
}));

assert.strictEqual(req.aborted, false);
assert.strictEqual(req.destroyed, false);
controller.abort();
assert.strictEqual(req.aborted, false);
assert.strictEqual(req.destroyed, true);
req.on('close', common.mustCall(() => server.close()));
}));
}