11cb0ef41Sopenharmony_ci'use strict'
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ciconst { AsyncResource } = require('async_hooks')
41cb0ef41Sopenharmony_ciconst { InvalidArgumentError, RequestAbortedError, SocketError } = require('../core/errors')
51cb0ef41Sopenharmony_ciconst util = require('../core/util')
61cb0ef41Sopenharmony_ciconst { addSignal, removeSignal } = require('./abort-signal')
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ciclass ConnectHandler extends AsyncResource {
91cb0ef41Sopenharmony_ci  constructor (opts, callback) {
101cb0ef41Sopenharmony_ci    if (!opts || typeof opts !== 'object') {
111cb0ef41Sopenharmony_ci      throw new InvalidArgumentError('invalid opts')
121cb0ef41Sopenharmony_ci    }
131cb0ef41Sopenharmony_ci
141cb0ef41Sopenharmony_ci    if (typeof callback !== 'function') {
151cb0ef41Sopenharmony_ci      throw new InvalidArgumentError('invalid callback')
161cb0ef41Sopenharmony_ci    }
171cb0ef41Sopenharmony_ci
181cb0ef41Sopenharmony_ci    const { signal, opaque, responseHeaders } = opts
191cb0ef41Sopenharmony_ci
201cb0ef41Sopenharmony_ci    if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') {
211cb0ef41Sopenharmony_ci      throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget')
221cb0ef41Sopenharmony_ci    }
231cb0ef41Sopenharmony_ci
241cb0ef41Sopenharmony_ci    super('UNDICI_CONNECT')
251cb0ef41Sopenharmony_ci
261cb0ef41Sopenharmony_ci    this.opaque = opaque || null
271cb0ef41Sopenharmony_ci    this.responseHeaders = responseHeaders || null
281cb0ef41Sopenharmony_ci    this.callback = callback
291cb0ef41Sopenharmony_ci    this.abort = null
301cb0ef41Sopenharmony_ci
311cb0ef41Sopenharmony_ci    addSignal(this, signal)
321cb0ef41Sopenharmony_ci  }
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_ci  onConnect (abort, context) {
351cb0ef41Sopenharmony_ci    if (!this.callback) {
361cb0ef41Sopenharmony_ci      throw new RequestAbortedError()
371cb0ef41Sopenharmony_ci    }
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_ci    this.abort = abort
401cb0ef41Sopenharmony_ci    this.context = context
411cb0ef41Sopenharmony_ci  }
421cb0ef41Sopenharmony_ci
431cb0ef41Sopenharmony_ci  onHeaders () {
441cb0ef41Sopenharmony_ci    throw new SocketError('bad connect', null)
451cb0ef41Sopenharmony_ci  }
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_ci  onUpgrade (statusCode, rawHeaders, socket) {
481cb0ef41Sopenharmony_ci    const { callback, opaque, context } = this
491cb0ef41Sopenharmony_ci
501cb0ef41Sopenharmony_ci    removeSignal(this)
511cb0ef41Sopenharmony_ci
521cb0ef41Sopenharmony_ci    this.callback = null
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_ci    let headers = rawHeaders
551cb0ef41Sopenharmony_ci    // Indicates is an HTTP2Session
561cb0ef41Sopenharmony_ci    if (headers != null) {
571cb0ef41Sopenharmony_ci      headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders)
581cb0ef41Sopenharmony_ci    }
591cb0ef41Sopenharmony_ci
601cb0ef41Sopenharmony_ci    this.runInAsyncScope(callback, null, null, {
611cb0ef41Sopenharmony_ci      statusCode,
621cb0ef41Sopenharmony_ci      headers,
631cb0ef41Sopenharmony_ci      socket,
641cb0ef41Sopenharmony_ci      opaque,
651cb0ef41Sopenharmony_ci      context
661cb0ef41Sopenharmony_ci    })
671cb0ef41Sopenharmony_ci  }
681cb0ef41Sopenharmony_ci
691cb0ef41Sopenharmony_ci  onError (err) {
701cb0ef41Sopenharmony_ci    const { callback, opaque } = this
711cb0ef41Sopenharmony_ci
721cb0ef41Sopenharmony_ci    removeSignal(this)
731cb0ef41Sopenharmony_ci
741cb0ef41Sopenharmony_ci    if (callback) {
751cb0ef41Sopenharmony_ci      this.callback = null
761cb0ef41Sopenharmony_ci      queueMicrotask(() => {
771cb0ef41Sopenharmony_ci        this.runInAsyncScope(callback, null, err, { opaque })
781cb0ef41Sopenharmony_ci      })
791cb0ef41Sopenharmony_ci    }
801cb0ef41Sopenharmony_ci  }
811cb0ef41Sopenharmony_ci}
821cb0ef41Sopenharmony_ci
831cb0ef41Sopenharmony_cifunction connect (opts, callback) {
841cb0ef41Sopenharmony_ci  if (callback === undefined) {
851cb0ef41Sopenharmony_ci    return new Promise((resolve, reject) => {
861cb0ef41Sopenharmony_ci      connect.call(this, opts, (err, data) => {
871cb0ef41Sopenharmony_ci        return err ? reject(err) : resolve(data)
881cb0ef41Sopenharmony_ci      })
891cb0ef41Sopenharmony_ci    })
901cb0ef41Sopenharmony_ci  }
911cb0ef41Sopenharmony_ci
921cb0ef41Sopenharmony_ci  try {
931cb0ef41Sopenharmony_ci    const connectHandler = new ConnectHandler(opts, callback)
941cb0ef41Sopenharmony_ci    this.dispatch({ ...opts, method: 'CONNECT' }, connectHandler)
951cb0ef41Sopenharmony_ci  } catch (err) {
961cb0ef41Sopenharmony_ci    if (typeof callback !== 'function') {
971cb0ef41Sopenharmony_ci      throw err
981cb0ef41Sopenharmony_ci    }
991cb0ef41Sopenharmony_ci    const opaque = opts && opts.opaque
1001cb0ef41Sopenharmony_ci    queueMicrotask(() => callback(err, { opaque }))
1011cb0ef41Sopenharmony_ci  }
1021cb0ef41Sopenharmony_ci}
1031cb0ef41Sopenharmony_ci
1041cb0ef41Sopenharmony_cimodule.exports = connect
105