http: added aborted property to request
PR-URL: https://github.com/nodejs/node/pull/20094 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
This commit is contained in:
parent
71059fbfa5
commit
d5e363b77e
@ -1483,7 +1483,7 @@ following additional events, methods, and properties.
|
|||||||
added: v0.3.8
|
added: v0.3.8
|
||||||
-->
|
-->
|
||||||
|
|
||||||
Emitted when the request has been aborted and the network socket has closed.
|
Emitted when the request has been aborted.
|
||||||
|
|
||||||
### Event: 'close'
|
### Event: 'close'
|
||||||
<!-- YAML
|
<!-- YAML
|
||||||
@ -1493,6 +1493,16 @@ added: v0.4.2
|
|||||||
Indicates that the underlying connection was closed.
|
Indicates that the underlying connection was closed.
|
||||||
Just like `'end'`, this event occurs only once per response.
|
Just like `'end'`, this event occurs only once per response.
|
||||||
|
|
||||||
|
### message.aborted
|
||||||
|
<!-- YAML
|
||||||
|
added: REPLACEME
|
||||||
|
-->
|
||||||
|
|
||||||
|
* {boolean}
|
||||||
|
|
||||||
|
The `message.aborted` property will be `true` if the request has
|
||||||
|
been aborted.
|
||||||
|
|
||||||
### message.destroy([error])
|
### message.destroy([error])
|
||||||
<!-- YAML
|
<!-- YAML
|
||||||
added: v0.3.0
|
added: v0.3.0
|
||||||
|
@ -2417,6 +2417,16 @@ added: v8.4.0
|
|||||||
Indicates that the underlying [`Http2Stream`][] was closed.
|
Indicates that the underlying [`Http2Stream`][] was closed.
|
||||||
Just like `'end'`, this event occurs only once per response.
|
Just like `'end'`, this event occurs only once per response.
|
||||||
|
|
||||||
|
#### request.aborted
|
||||||
|
<!-- YAML
|
||||||
|
added: REPLACEME
|
||||||
|
-->
|
||||||
|
|
||||||
|
* {boolean}
|
||||||
|
|
||||||
|
The `request.aborted` property will be `true` if the request has
|
||||||
|
been aborted.
|
||||||
|
|
||||||
#### request.destroy([error])
|
#### request.destroy([error])
|
||||||
<!-- YAML
|
<!-- YAML
|
||||||
added: v8.4.0
|
added: v8.4.0
|
||||||
|
@ -279,6 +279,7 @@ ClientRequest.prototype.abort = function abort() {
|
|||||||
if (!this.aborted) {
|
if (!this.aborted) {
|
||||||
process.nextTick(emitAbortNT.bind(this));
|
process.nextTick(emitAbortNT.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark as aborting so we can avoid sending queued request data
|
// Mark as aborting so we can avoid sending queued request data
|
||||||
// This is used as a truthy flag elsewhere. The use of Date.now is for
|
// This is used as a truthy flag elsewhere. The use of Date.now is for
|
||||||
// debugging purposes only.
|
// debugging purposes only.
|
||||||
@ -330,7 +331,10 @@ function socketCloseListener() {
|
|||||||
var parser = socket.parser;
|
var parser = socket.parser;
|
||||||
if (req.res && req.res.readable) {
|
if (req.res && req.res.readable) {
|
||||||
// Socket closed before we emitted 'end' below.
|
// Socket closed before we emitted 'end' below.
|
||||||
if (!req.res.complete) req.res.emit('aborted');
|
if (!req.res.complete) {
|
||||||
|
req.res.aborted = true;
|
||||||
|
req.res.emit('aborted');
|
||||||
|
}
|
||||||
var res = req.res;
|
var res = req.res;
|
||||||
res.on('end', function() {
|
res.on('end', function() {
|
||||||
res.emit('close');
|
res.emit('close');
|
||||||
|
@ -54,6 +54,8 @@ function IncomingMessage(socket) {
|
|||||||
|
|
||||||
this.readable = true;
|
this.readable = true;
|
||||||
|
|
||||||
|
this.aborted = false;
|
||||||
|
|
||||||
this.upgrade = null;
|
this.upgrade = null;
|
||||||
|
|
||||||
// request (server) only
|
// request (server) only
|
||||||
|
@ -440,6 +440,7 @@ function socketOnClose(socket, state) {
|
|||||||
function abortIncoming(incoming) {
|
function abortIncoming(incoming) {
|
||||||
while (incoming.length) {
|
while (incoming.length) {
|
||||||
var req = incoming.shift();
|
var req = incoming.shift();
|
||||||
|
req.aborted = true;
|
||||||
req.emit('aborted');
|
req.emit('aborted');
|
||||||
req.emit('close');
|
req.emit('close');
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ const kTrailers = Symbol('trailers');
|
|||||||
const kRawTrailers = Symbol('rawTrailers');
|
const kRawTrailers = Symbol('rawTrailers');
|
||||||
const kProxySocket = Symbol('proxySocket');
|
const kProxySocket = Symbol('proxySocket');
|
||||||
const kSetHeader = Symbol('setHeader');
|
const kSetHeader = Symbol('setHeader');
|
||||||
|
const kAborted = Symbol('aborted');
|
||||||
|
|
||||||
const {
|
const {
|
||||||
HTTP2_HEADER_AUTHORITY,
|
HTTP2_HEADER_AUTHORITY,
|
||||||
@ -137,6 +138,7 @@ function onStreamDrain() {
|
|||||||
function onStreamAbortedRequest() {
|
function onStreamAbortedRequest() {
|
||||||
const request = this[kRequest];
|
const request = this[kRequest];
|
||||||
if (request !== undefined && request[kState].closed === false) {
|
if (request !== undefined && request[kState].closed === false) {
|
||||||
|
request[kAborted] = true;
|
||||||
request.emit('aborted');
|
request.emit('aborted');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -233,6 +235,7 @@ class Http2ServerRequest extends Readable {
|
|||||||
this[kTrailers] = {};
|
this[kTrailers] = {};
|
||||||
this[kRawTrailers] = [];
|
this[kRawTrailers] = [];
|
||||||
this[kStream] = stream;
|
this[kStream] = stream;
|
||||||
|
this[kAborted] = false;
|
||||||
stream[kProxySocket] = null;
|
stream[kProxySocket] = null;
|
||||||
stream[kRequest] = this;
|
stream[kRequest] = this;
|
||||||
|
|
||||||
@ -248,6 +251,10 @@ class Http2ServerRequest extends Readable {
|
|||||||
this.on('resume', onRequestResume);
|
this.on('resume', onRequestResume);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get aborted() {
|
||||||
|
return this[kAborted];
|
||||||
|
}
|
||||||
|
|
||||||
get complete() {
|
get complete() {
|
||||||
return this._readableState.ended ||
|
return this._readableState.ended ||
|
||||||
this[kState].closed ||
|
this[kState].closed ||
|
||||||
|
26
test/parallel/test-http-aborted.js
Normal file
26
test/parallel/test-http-aborted.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const common = require('../common');
|
||||||
|
const http = require('http');
|
||||||
|
const assert = require('assert');
|
||||||
|
|
||||||
|
const server = http.createServer(common.mustCall(function(req, res) {
|
||||||
|
req.on('aborted', common.mustCall(function() {
|
||||||
|
assert.strictEqual(this.aborted, true);
|
||||||
|
server.close();
|
||||||
|
}));
|
||||||
|
assert.strictEqual(req.aborted, false);
|
||||||
|
res.write('hello');
|
||||||
|
}));
|
||||||
|
|
||||||
|
server.listen(0, common.mustCall(() => {
|
||||||
|
const req = http.get({
|
||||||
|
port: server.address().port,
|
||||||
|
headers: { connection: 'keep-alive' }
|
||||||
|
}, common.mustCall((res) => {
|
||||||
|
res.on('aborted', common.mustCall(() => {
|
||||||
|
assert.strictEqual(res.aborted, true);
|
||||||
|
}));
|
||||||
|
req.abort();
|
||||||
|
}));
|
||||||
|
}));
|
27
test/parallel/test-http2-compat-aborted.js
Normal file
27
test/parallel/test-http2-compat-aborted.js
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const common = require('../common');
|
||||||
|
if (!common.hasCrypto)
|
||||||
|
common.skip('missing crypto');
|
||||||
|
const h2 = require('http2');
|
||||||
|
const assert = require('assert');
|
||||||
|
|
||||||
|
|
||||||
|
const server = h2.createServer(common.mustCall(function(req, res) {
|
||||||
|
req.on('aborted', common.mustCall(function() {
|
||||||
|
assert.strictEqual(this.aborted, true);
|
||||||
|
}));
|
||||||
|
assert.strictEqual(req.aborted, false);
|
||||||
|
res.write('hello');
|
||||||
|
server.close();
|
||||||
|
}));
|
||||||
|
|
||||||
|
server.listen(0, common.mustCall(function() {
|
||||||
|
const url = `http://localhost:${server.address().port}`;
|
||||||
|
const client = h2.connect(url, common.mustCall(() => {
|
||||||
|
const request = client.request();
|
||||||
|
request.on('data', common.mustCall((chunk) => {
|
||||||
|
client.destroy();
|
||||||
|
}));
|
||||||
|
}));
|
||||||
|
}));
|
Loading…
x
Reference in New Issue
Block a user