aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/node_modules/undici/lib/api/api-request.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/undici/lib/api/api-request.js')
-rw-r--r--node_modules/undici/lib/api/api-request.js84
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 }))
}
}