diff options
Diffstat (limited to 'node_modules/undici/lib/api/api-request.js')
| -rw-r--r-- | node_modules/undici/lib/api/api-request.js | 84 |
1 files changed, 59 insertions, 25 deletions
diff --git a/node_modules/undici/lib/api/api-request.js b/node_modules/undici/lib/api/api-request.js index d4281ce..be17d62 100644 --- a/node_modules/undici/lib/api/api-request.js +++ b/node_modules/undici/lib/api/api-request.js @@ -1,14 +1,11 @@ 'use strict' -const Readable = require('./readable') -const { - InvalidArgumentError, - RequestAbortedError -} = require('../core/errors') +const assert = require('node:assert') +const { Readable } = require('./readable') +const { InvalidArgumentError, RequestAbortedError } = require('../core/errors') const util = require('../core/util') const { getResolveErrorBodyCallback } = require('./util') -const { AsyncResource } = require('async_hooks') -const { addSignal, removeSignal } = require('./abort-signal') +const { AsyncResource } = require('node:async_hooks') class RequestHandler extends AsyncResource { constructor (opts, callback) { @@ -47,6 +44,7 @@ class RequestHandler extends AsyncResource { throw err } + this.method = method this.responseHeaders = responseHeaders || null this.opaque = opaque || null this.callback = callback @@ -58,6 +56,9 @@ class RequestHandler extends AsyncResource { this.onInfo = onInfo || null this.throwOnError = throwOnError this.highWaterMark = highWaterMark + this.signal = signal + this.reason = null + this.removeAbortListener = null if (util.isStream(body)) { body.on('error', (err) => { @@ -65,14 +66,36 @@ class RequestHandler extends AsyncResource { }) } - addSignal(this, signal) + if (this.signal) { + if (this.signal.aborted) { + this.reason = this.signal.reason ?? new RequestAbortedError() + } else { + this.removeAbortListener = util.addAbortListener(this.signal, () => { + this.reason = this.signal.reason ?? new RequestAbortedError() + if (this.res) { + util.destroy(this.res.on('error', util.nop), this.reason) + } else if (this.abort) { + this.abort(this.reason) + } + + if (this.removeAbortListener) { + this.res?.off('close', this.removeAbortListener) + this.removeAbortListener() + this.removeAbortListener = null + } + }) + } + } } onConnect (abort, context) { - if (!this.callback) { - throw new RequestAbortedError() + if (this.reason) { + abort(this.reason) + return } + assert(this.callback) + this.abort = abort this.context = context } @@ -91,14 +114,27 @@ class RequestHandler extends AsyncResource { const parsedHeaders = responseHeaders === 'raw' ? util.parseHeaders(rawHeaders) : headers const contentType = parsedHeaders['content-type'] - const body = new Readable({ resume, abort, contentType, highWaterMark }) + const contentLength = parsedHeaders['content-length'] + const res = new Readable({ + resume, + abort, + contentType, + contentLength: this.method !== 'HEAD' && contentLength + ? Number(contentLength) + : null, + highWaterMark + }) + + if (this.removeAbortListener) { + res.on('close', this.removeAbortListener) + } this.callback = null - this.res = body + this.res = res if (callback !== null) { if (this.throwOnError && statusCode >= 400) { this.runInAsyncScope(getResolveErrorBodyCallback, null, - { callback, body, contentType, statusCode, statusMessage, headers } + { callback, body: res, contentType, statusCode, statusMessage, headers } ) } else { this.runInAsyncScope(callback, null, null, { @@ -106,7 +142,7 @@ class RequestHandler extends AsyncResource { headers, trailers: this.trailers, opaque, - body, + body: res, context }) } @@ -114,25 +150,17 @@ class RequestHandler extends AsyncResource { } onData (chunk) { - const { res } = this - return res.push(chunk) + return this.res.push(chunk) } onComplete (trailers) { - const { res } = this - - removeSignal(this) - util.parseHeaders(trailers, this.trailers) - - res.push(null) + this.res.push(null) } onError (err) { const { res, callback, body, opaque } = this - removeSignal(this) - if (callback) { // TODO: Does this need queueMicrotask? this.callback = null @@ -153,6 +181,12 @@ class RequestHandler extends AsyncResource { this.body = null util.destroy(body, err) } + + if (this.removeAbortListener) { + res?.off('close', this.removeAbortListener) + this.removeAbortListener() + this.removeAbortListener = null + } } } @@ -171,7 +205,7 @@ function request (opts, callback) { if (typeof callback !== 'function') { throw err } - const opaque = opts && opts.opaque + const opaque = opts?.opaque queueMicrotask(() => callback(err, { opaque })) } } |
