Spaces:
Runtime error
Runtime error
const { AsyncResource } = require('async_hooks') | |
const { InvalidArgumentError, RequestAbortedError, SocketError } = require('../core/errors') | |
const util = require('../core/util') | |
const { addSignal, removeSignal } = require('./abort-signal') | |
class ConnectHandler extends AsyncResource { | |
constructor (opts, callback) { | |
if (!opts || typeof opts !== 'object') { | |
throw new InvalidArgumentError('invalid opts') | |
} | |
if (typeof callback !== 'function') { | |
throw new InvalidArgumentError('invalid callback') | |
} | |
const { signal, opaque, responseHeaders } = opts | |
if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { | |
throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') | |
} | |
super('UNDICI_CONNECT') | |
this.opaque = opaque || null | |
this.responseHeaders = responseHeaders || null | |
this.callback = callback | |
this.abort = null | |
addSignal(this, signal) | |
} | |
onConnect (abort, context) { | |
if (!this.callback) { | |
throw new RequestAbortedError() | |
} | |
this.abort = abort | |
this.context = context | |
} | |
onHeaders () { | |
throw new SocketError('bad connect', null) | |
} | |
onUpgrade (statusCode, rawHeaders, socket) { | |
const { callback, opaque, context } = this | |
removeSignal(this) | |
this.callback = null | |
let headers = rawHeaders | |
// Indicates is an HTTP2Session | |
if (headers != null) { | |
headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) | |
} | |
this.runInAsyncScope(callback, null, null, { | |
statusCode, | |
headers, | |
socket, | |
opaque, | |
context | |
}) | |
} | |
onError (err) { | |
const { callback, opaque } = this | |
removeSignal(this) | |
if (callback) { | |
this.callback = null | |
queueMicrotask(() => { | |
this.runInAsyncScope(callback, null, err, { opaque }) | |
}) | |
} | |
} | |
} | |
function connect (opts, callback) { | |
if (callback === undefined) { | |
return new Promise((resolve, reject) => { | |
connect.call(this, opts, (err, data) => { | |
return err ? reject(err) : resolve(data) | |
}) | |
}) | |
} | |
try { | |
const connectHandler = new ConnectHandler(opts, callback) | |
this.dispatch({ ...opts, method: 'CONNECT' }, connectHandler) | |
} catch (err) { | |
if (typeof callback !== 'function') { | |
throw err | |
} | |
const opaque = opts && opts.opaque | |
queueMicrotask(() => callback(err, { opaque })) | |
} | |
} | |
module.exports = connect | |