basant307/AI_Governance_Project
048
1'use strict'2 3const { InvalidArgumentError, SocketError } = require('../core/errors')4const { AsyncResource } = require('node:async_hooks')5const util = require('../core/util')6const { addSignal, removeSignal } = require('./abort-signal')7const assert = require('node:assert')8 9class UpgradeHandler extends AsyncResource {10 constructor (opts, callback) {11 if (!opts || typeof opts !== 'object') {12 throw new InvalidArgumentError('invalid opts')13 }14 15 if (typeof callback !== 'function') {16 throw new InvalidArgumentError('invalid callback')17 }18 19 const { signal, opaque, responseHeaders } = opts20 21 if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') {22 throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget')23 }24 25 super('UNDICI_UPGRADE')26 27 this.responseHeaders = responseHeaders || null28 this.opaque = opaque || null29 this.callback = callback30 this.abort = null31 this.context = null32 33 addSignal(this, signal)34 }35 36 onConnect (abort, context) {37 if (this.reason) {38 abort(this.reason)39 return40 }41 42 assert(this.callback)43 44 this.abort = abort45 this.context = null46 }47 48 onHeaders () {49 throw new SocketError('bad upgrade', null)50 }51 52 onUpgrade (statusCode, rawHeaders, socket) {53 assert(statusCode === 101)54 55 const { callback, opaque, context } = this56 57 removeSignal(this)58 59 this.callback = null60 const headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders)61 this.runInAsyncScope(callback, null, null, {62 headers,63 socket,64 opaque,65 context66 })67 }68 69 onError (err) {70 const { callback, opaque } = this71 72 removeSignal(this)73 74 if (callback) {75 this.callback = null76 queueMicrotask(() => {77 this.runInAsyncScope(callback, null, err, { opaque })78 })79 }80 }81}82 83function upgrade (opts, callback) {84 if (callback === undefined) {85 return new Promise((resolve, reject) => {86 upgrade.call(this, opts, (err, data) => {87 return err ? reject(err) : resolve(data)88 })89 })90 }91 92 try {93 const upgradeHandler = new UpgradeHandler(opts, callback)94 this.dispatch({95 ...opts,96 method: opts.method || 'GET',97 upgrade: opts.protocol || 'Websocket'98 }, upgradeHandler)99 } catch (err) {100 if (typeof callback !== 'function') {101 throw err102 }103 const opaque = opts?.opaque104 queueMicrotask(() => callback(err, { opaque }))105 }106}107 108module.exports = upgrade109 