aboutsummaryrefslogtreecommitdiff
path: root/src/js/out/modules_dev/node/http.js.map
blob: fd2703e9a878566c9ab3fe30a331d7f4a9dc4dd8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
  "version": 3,
  "sources": ["src/js/node/http.js", "src/js/node/http.js", "src/js/node/http.js", "src/js/node/http.js", "src/js/node/http.js"],
  "sourcesContent": [
    "// Hardcoded module \"node:http\"\nconst { EventEmitter } = import.meta.require(\"node:events\");\nconst { isIPv6 } = import.meta.require(\"node:net\");\nconst { Readable, Writable, Duplex } = import.meta.require(\"node:stream\");\nconst { URL } = import.meta.require(\"node:url\");\nconst { newArrayWithSize, String, Object, Array } = import.meta.primordials;\nconst { isTypedArray } = import.meta.require(\"util/types\");\n\nconst globalReportError = globalThis.reportError;\nconst setTimeout = globalThis.setTimeout;\nconst fetch = Bun.fetch;\nconst nop = () => {};\n\nconst __DEBUG__ = process.env.__DEBUG__;\nconst debug = __DEBUG__ ? (...args) => console.log(\"node:http\", ...args) : nop;\n\nconst kEmptyObject = Object.freeze(Object.create(null));\nconst kOutHeaders = Symbol.for(\"kOutHeaders\");\nconst kEndCalled = Symbol.for(\"kEndCalled\");\nconst kAbortController = Symbol.for(\"kAbortController\");\nconst kClearTimeout = Symbol(\"kClearTimeout\");\n\nconst kCorked = Symbol.for(\"kCorked\");\nconst searchParamsSymbol = Symbol.for(\"query\"); // This is the symbol used in Node\n\n// Primordials\nconst StringPrototypeSlice = String.prototype.slice;\nconst StringPrototypeStartsWith = String.prototype.startsWith;\nconst StringPrototypeToUpperCase = String.prototype.toUpperCase;\nconst StringPrototypeIncludes = String.prototype.includes;\nconst StringPrototypeCharCodeAt = String.prototype.charCodeAt;\nconst StringPrototypeIndexOf = String.prototype.indexOf;\nconst ArrayIsArray = Array.isArray;\nconst RegExpPrototypeExec = RegExp.prototype.exec;\nconst ObjectAssign = Object.assign;\nconst ObjectPrototypeHasOwnProperty = Object.prototype.hasOwnProperty;\n\nconst INVALID_PATH_REGEX = /[^\\u0021-\\u00ff]/;\nconst NODE_HTTP_WARNING =\n  \"WARN: Agent is mostly unused in Bun's implementation of http. If you see strange behavior, this is probably the cause.\";\n\nvar _globalAgent;\nvar _defaultHTTPSAgent;\nvar kInternalRequest = Symbol(\"kInternalRequest\");\nvar kInternalSocketData = Symbol.for(\"::bunternal::\");\n\nconst kEmptyBuffer = Buffer.alloc(0);\n\nfunction isValidTLSArray(obj) {\n  if (typeof obj === \"string\" || isTypedArray(obj) || obj instanceof ArrayBuffer || obj instanceof Blob) return true;\n  if (Array.isArray(obj)) {\n    for (var i = 0; i < obj.length; i++) {\n      if (typeof obj !== \"string\" && !isTypedArray(obj) && !(obj instanceof ArrayBuffer) && !(obj instanceof Blob))\n        return false;\n    }\n    return true;\n  }\n}\n\nfunction getHeader(headers, name) {\n  if (!headers) return;\n  const result = headers.get(name);\n  return result == null ? undefined : result;\n}\n\nvar FakeSocket = class Socket extends Duplex {\n  bytesRead = 0;\n  bytesWritten = 0;\n  connecting = false;\n  remoteAddress = null;\n  localAddress = \"127.0.0.1\";\n  remotePort;\n  timeout = 0;\n\n  isServer = false;\n\n  address() {\n    return {\n      address: this.localAddress,\n      family: this.localFamily,\n      port: this.localPort,\n    };\n  }\n\n  get bufferSize() {\n    return this.writableLength;\n  }\n\n  connect(port, host, connectListener) {\n    return this;\n  }\n\n  _destroy(err, callback) {}\n\n  _final(callback) {}\n\n  get localAddress() {\n    return \"127.0.0.1\";\n  }\n\n  get localFamily() {\n    return \"IPv4\";\n  }\n\n  get localPort() {\n    return 80;\n  }\n\n  get pending() {\n    return this.connecting;\n  }\n\n  _read(size) {}\n\n  get readyState() {\n    if (this.connecting) return \"opening\";\n    if (this.readable) {\n      return this.writable ? \"open\" : \"readOnly\";\n    } else {\n      return this.writable ? \"writeOnly\" : \"closed\";\n    }\n  }\n\n  ref() {}\n\n  get remoteFamily() {\n    return \"IPv4\";\n  }\n\n  resetAndDestroy() {}\n\n  setKeepAlive(enable = false, initialDelay = 0) {}\n\n  setNoDelay(noDelay = true) {\n    return this;\n  }\n\n  setTimeout(timeout, callback) {\n    return this;\n  }\n\n  unref() {}\n\n  _write(chunk, encoding, callback) {}\n};\n\nexport function createServer(options, callback) {\n  return new Server(options, callback);\n}\n\nexport class Agent extends EventEmitter {\n  #defaultPort = 80;\n  #protocol = \"http:\";\n  #options;\n  #requests;\n  #sockets;\n  #freeSockets;\n\n  #keepAliveMsecs;\n  #keepAlive;\n  #maxSockets;\n  #maxFreeSockets;\n  #scheduling;\n  #maxTotalSockets;\n  #totalSocketCount;\n\n  #fakeSocket;\n\n  static get globalAgent() {\n    return (_globalAgent ??= new Agent());\n  }\n\n  static get defaultMaxSockets() {\n    return Infinity;\n  }\n\n  constructor(options = kEmptyObject) {\n    super();\n    this.#options = options = { ...options, path: null };\n    if (options.noDelay === undefined) options.noDelay = true;\n\n    // Don't confuse net and make it think that we're connecting to a pipe\n    this.#requests = kEmptyObject;\n    this.#sockets = kEmptyObject;\n    this.#freeSockets = kEmptyObject;\n\n    this.#keepAliveMsecs = options.keepAliveMsecs || 1000;\n    this.#keepAlive = options.keepAlive || false;\n    this.#maxSockets = options.maxSockets || Agent.defaultMaxSockets;\n    this.#maxFreeSockets = options.maxFreeSockets || 256;\n    this.#scheduling = options.scheduling || \"lifo\";\n    this.#maxTotalSockets = options.maxTotalSockets;\n    this.#totalSocketCount = 0;\n    this.#defaultPort = options.defaultPort || 80;\n    this.#protocol = options.protocol || \"http:\";\n  }\n\n  get defaultPort() {\n    return this.#defaultPort;\n  }\n\n  get protocol() {\n    return this.#protocol;\n  }\n\n  get requests() {\n    return this.#requests;\n  }\n\n  get sockets() {\n    return this.#sockets;\n  }\n\n  get freeSockets() {\n    return this.#freeSockets;\n  }\n\n  get options() {\n    return this.#options;\n  }\n\n  get keepAliveMsecs() {\n    return this.#keepAliveMsecs;\n  }\n\n  get keepAlive() {\n    return this.#keepAlive;\n  }\n\n  get maxSockets() {\n    return this.#maxSockets;\n  }\n\n  get maxFreeSockets() {\n    return this.#maxFreeSockets;\n  }\n\n  get scheduling() {\n    return this.#scheduling;\n  }\n\n  get maxTotalSockets() {\n    return this.#maxTotalSockets;\n  }\n\n  get totalSocketCount() {\n    return this.#totalSocketCount;\n  }\n\n  createConnection() {\n    debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: Agent.createConnection is a no-op, returns fake socket\");\n    return (this.#fakeSocket ??= new FakeSocket());\n  }\n\n  getName(options = kEmptyObject) {\n    let name = `http:${options.host || \"localhost\"}:`;\n    if (options.port) name += options.port;\n    name += \":\";\n    if (options.localAddress) name += options.localAddress;\n    // Pacify parallel/test-http-agent-getname by only appending\n    // the ':' when options.family is set.\n    if (options.family === 4 || options.family === 6) name += `:${options.family}`;\n    if (options.socketPath) name += `:${options.socketPath}`;\n    return name;\n  }\n\n  addRequest() {\n    debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: Agent.addRequest is a no-op\");\n  }\n\n  createSocket(req, options, cb) {\n    debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: Agent.createSocket returns fake socket\");\n    cb(null, (this.#fakeSocket ??= new FakeSocket()));\n  }\n\n  removeSocket() {\n    debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: Agent.removeSocket is a no-op\");\n  }\n\n  keepSocketAlive() {\n    debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: Agent.keepSocketAlive is a no-op\");\n\n    return true;\n  }\n\n  reuseSocket() {\n    debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: Agent.reuseSocket is a no-op\");\n  }\n\n  destroy() {\n    debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: Agent.destroy is a no-op\");\n  }\n}\nfunction emitListeningNextTick(self, onListen, err, hostname, port) {\n  if (typeof onListen === \"function\") {\n    try {\n      onListen(err, hostname, port);\n    } catch (err) {\n      self.emit(\"error\", err);\n    }\n  }\n\n  self.listening = !err;\n\n  if (err) {\n    self.emit(\"error\", err);\n  } else {\n    self.emit(\"listening\", hostname, port);\n  }\n}\n\nexport class Server extends EventEmitter {\n  #server;\n  #options;\n  #tls;\n  #is_tls = false;\n  listening = false;\n\n  constructor(options, callback) {\n    super();\n\n    if (typeof options === \"function\") {\n      callback = options;\n      options = {};\n    } else if (options == null || typeof options === \"object\") {\n      options = { ...options };\n      this.#tls = null;\n      let key = options.key;\n      if (key) {\n        if (!isValidTLSArray(key)) {\n          throw new TypeError(\n            \"key argument must be an string, Buffer, TypedArray, BunFile or an array containing string, Buffer, TypedArray or BunFile\",\n          );\n        }\n        this.#is_tls = true;\n      }\n      let cert = options.cert;\n      if (cert) {\n        if (!isValidTLSArray(cert)) {\n          throw new TypeError(\n            \"cert argument must be an string, Buffer, TypedArray, BunFile or an array containing string, Buffer, TypedArray or BunFile\",\n          );\n        }\n        this.#is_tls = true;\n      }\n\n      let ca = options.ca;\n      if (ca) {\n        if (!isValidTLSArray(ca)) {\n          throw new TypeError(\n            \"ca argument must be an string, Buffer, TypedArray, BunFile or an array containing string, Buffer, TypedArray or BunFile\",\n          );\n        }\n        this.#is_tls = true;\n      }\n      let passphrase = options.passphrase;\n      if (passphrase && typeof passphrase !== \"string\") {\n        throw new TypeError(\"passphrase argument must be an string\");\n      }\n\n      let serverName = options.servername;\n      if (serverName && typeof serverName !== \"string\") {\n        throw new TypeError(\"servername argument must be an string\");\n      }\n\n      let secureOptions = options.secureOptions || 0;\n      if (secureOptions && typeof secureOptions !== \"number\") {\n        throw new TypeError(\"secureOptions argument must be an number\");\n      }\n\n      if (this.#is_tls) {\n        this.#tls = {\n          serverName,\n          key: key,\n          cert: cert,\n          ca: ca,\n          passphrase: passphrase,\n          secureOptions: secureOptions,\n        };\n      } else {\n        this.#tls = null;\n      }\n    } else {\n      throw new Error(\"bun-http-polyfill: invalid arguments\");\n    }\n\n    this.#options = options;\n\n    if (callback) this.on(\"request\", callback);\n  }\n\n  closeAllConnections() {\n    const server = this.#server;\n    if (!server) {\n      return;\n    }\n    this.#server = undefined;\n    server.stop(true);\n    this.emit(\"close\");\n  }\n\n  closeIdleConnections() {\n    // not actually implemented\n  }\n\n  close(optionalCallback) {\n    const server = this.#server;\n    if (!server) {\n      if (typeof optionalCallback === \"function\")\n        process.nextTick(optionalCallback, new Error(\"Server is not running\"));\n      return;\n    }\n    this.#server = undefined;\n    if (typeof optionalCallback === \"function\") this.once(\"close\", optionalCallback);\n    server.stop();\n    this.emit(\"close\");\n  }\n\n  address() {\n    if (!this.#server) return null;\n\n    const address = this.#server.hostname;\n    return {\n      address,\n      family: isIPv6(address) ? \"IPv6\" : \"IPv4\",\n      port: this.#server.port,\n    };\n  }\n\n  listen(port, host, backlog, onListen) {\n    const server = this;\n    if (typeof host === \"function\") {\n      onListen = host;\n      host = undefined;\n    }\n\n    if (typeof port === \"function\") {\n      onListen = port;\n    } else if (typeof port === \"object\") {\n      port?.signal?.addEventListener(\"abort\", () => {\n        this.close();\n      });\n\n      host = port?.host;\n      port = port?.port;\n\n      if (typeof port?.callback === \"function\") onListen = port?.callback;\n    }\n\n    if (typeof backlog === \"function\") {\n      onListen = backlog;\n    }\n\n    const ResponseClass = this.#options.ServerResponse || ServerResponse;\n    const RequestClass = this.#options.IncomingMessage || IncomingMessage;\n\n    try {\n      const tls = this.#tls;\n      if (tls) {\n        this.serverName = tls.serverName || host || \"localhost\";\n      }\n      this.#server = Bun.serve({\n        tls,\n        port,\n        hostname: host,\n        // Bindings to be used for WS Server\n        websocket: {\n          open(ws) {\n            ws.data.open(ws);\n          },\n          message(ws, message) {\n            ws.data.message(ws, message);\n          },\n          close(ws, code, reason) {\n            ws.data.close(ws, code, reason);\n          },\n          drain(ws) {\n            ws.data.drain(ws);\n          },\n        },\n        fetch(req, _server) {\n          var pendingResponse;\n          var pendingError;\n          var rejectFunction, resolveFunction;\n          var reject = err => {\n            if (pendingError) return;\n            pendingError = err;\n            if (rejectFunction) rejectFunction(err);\n          };\n\n          var reply = function (resp) {\n            if (pendingResponse) return;\n            pendingResponse = resp;\n            if (resolveFunction) resolveFunction(resp);\n          };\n\n          const http_req = new RequestClass(req);\n          const http_res = new ResponseClass({ reply, req: http_req });\n\n          http_req.once(\"error\", err => reject(err));\n          http_res.once(\"error\", err => reject(err));\n\n          const upgrade = req.headers.get(\"upgrade\");\n          if (upgrade) {\n            const socket = new FakeSocket();\n            socket[kInternalSocketData] = [_server, http_res, req];\n            server.emit(\"upgrade\", http_req, socket, kEmptyBuffer);\n          } else {\n            server.emit(\"request\", http_req, http_res);\n          }\n\n          if (pendingError) {\n            throw pendingError;\n          }\n\n          if (pendingResponse) {\n            return pendingResponse;\n          }\n\n          return new Promise((resolve, reject) => {\n            resolveFunction = resolve;\n            rejectFunction = reject;\n          });\n        },\n      });\n      setTimeout(emitListeningNextTick, 1, this, onListen, null, this.#server.hostname, this.#server.port);\n    } catch (err) {\n      setTimeout(emitListeningNextTick, 1, this, onListen, err);\n    }\n\n    return this;\n  }\n  setTimeout(msecs, callback) {}\n}\n\nfunction assignHeaders(object, req) {\n  var headers = req.headers.toJSON();\n  const rawHeaders = newArrayWithSize(req.headers.count * 2);\n  var i = 0;\n  for (const key in headers) {\n    rawHeaders[i++] = key;\n    rawHeaders[i++] = headers[key];\n  }\n  object.headers = headers;\n  object.rawHeaders = rawHeaders;\n}\nfunction destroyBodyStreamNT(bodyStream) {\n  bodyStream.destroy();\n}\n\nvar defaultIncomingOpts = { type: \"request\" };\n\nfunction getDefaultHTTPSAgent() {\n  return (_defaultHTTPSAgent ??= new Agent({ defaultPort: 443, protocol: \"https:\" }));\n}\n\nexport class IncomingMessage extends Readable {\n  constructor(req, defaultIncomingOpts) {\n    const method = req.method;\n\n    super();\n\n    const url = new URL(req.url);\n\n    var { type = \"request\", [kInternalRequest]: nodeReq } = defaultIncomingOpts || {};\n\n    this.#noBody =\n      type === \"request\" // TODO: Add logic for checking for body on response\n        ? \"GET\" === method ||\n          \"HEAD\" === method ||\n          \"TRACE\" === method ||\n          \"CONNECT\" === method ||\n          \"OPTIONS\" === method ||\n          (parseInt(req.headers.get(\"Content-Length\") || \"\") || 0) === 0\n        : false;\n\n    this.#req = req;\n    this.method = method;\n    this.#type = type;\n    this.complete = !!this.#noBody;\n\n    this.#bodyStream = null;\n    const socket = new FakeSocket();\n    socket.remoteAddress = url.hostname;\n    socket.remotePort = url.port;\n    this.#fakeSocket = socket;\n\n    this.url = url.pathname + url.search;\n    this.#nodeReq = nodeReq;\n    assignHeaders(this, req);\n  }\n\n  headers;\n  rawHeaders;\n  _consuming = false;\n  _dumped = false;\n  #bodyStream = null;\n  #fakeSocket = undefined;\n  #noBody = false;\n  #aborted = false;\n  #req;\n  url;\n  #type;\n  #nodeReq;\n\n  get req() {\n    return this.#nodeReq;\n  }\n\n  _construct(callback) {\n    // TODO: streaming\n    if (this.#type === \"response\" || this.#noBody) {\n      callback();\n      return;\n    }\n\n    const contentLength = this.#req.headers.get(\"content-length\");\n    const length = contentLength ? parseInt(contentLength, 10) : 0;\n    if (length === 0) {\n      this.#noBody = true;\n      callback();\n      return;\n    }\n\n    callback();\n  }\n\n  #closeBodyStream() {\n    debug(\"closeBodyStream()\");\n    var bodyStream = this.#bodyStream;\n    if (bodyStream == null) return;\n    this.complete = true;\n    this.#bodyStream = undefined;\n    this.push(null);\n    // process.nextTick(destroyBodyStreamNT, bodyStream);\n  }\n\n  _read(size) {\n    if (this.#noBody) {\n      this.push(null);\n      this.complete = true;\n    } else if (this.#bodyStream == null) {\n      const contentLength = this.#req.headers.get(\"content-length\");\n      let remaining = contentLength ? parseInt(contentLength, 10) : 0;\n      this.#bodyStream = Readable.fromWeb(this.#req.body, {\n        highWaterMark: Number.isFinite(remaining) ? Math.min(remaining, 16384) : 16384,\n      });\n\n      const isBodySizeKnown = remaining > 0 && Number.isSafeInteger(remaining);\n\n      if (isBodySizeKnown) {\n        this.#bodyStream.on(\"data\", chunk => {\n          debug(\"body size known\", remaining);\n          this.push(chunk);\n          // when we are streaming a known body size, automatically close the stream when we have read enough\n          remaining -= chunk?.byteLength ?? 0;\n          if (remaining <= 0) {\n            this.#closeBodyStream();\n          }\n        });\n      } else {\n        this.#bodyStream.on(\"data\", chunk => {\n          this.push(chunk);\n        });\n      }\n\n      // this can be closed by the time we get here if enough data was synchronously available\n      this.#bodyStream &&\n        this.#bodyStream.on(\"end\", () => {\n          this.#closeBodyStream();\n        });\n    } else {\n      // this.#bodyStream.read(size);\n    }\n  }\n\n  get aborted() {\n    return this.#aborted;\n  }\n\n  abort() {\n    if (this.#aborted) return;\n    this.#aborted = true;\n\n    this.#closeBodyStream();\n  }\n\n  get connection() {\n    return this.#fakeSocket;\n  }\n\n  get statusCode() {\n    return this.#req.status;\n  }\n\n  get statusMessage() {\n    return STATUS_CODES[this.#req.status];\n  }\n\n  get httpVersion() {\n    return \"1.1\";\n  }\n\n  get rawTrailers() {\n    return [];\n  }\n\n  get httpVersionMajor() {\n    return 1;\n  }\n\n  get httpVersionMinor() {\n    return 1;\n  }\n\n  get trailers() {\n    return kEmptyObject;\n  }\n\n  get socket() {\n    return (this.#fakeSocket ??= new FakeSocket());\n  }\n\n  set socket(val) {\n    this.#fakeSocket = val;\n  }\n\n  setTimeout(msecs, callback) {\n    throw new Error(\"not implemented\");\n  }\n}\n\nfunction emitErrorNt(msg, err, callback) {\n  callback(err);\n  if (typeof msg.emit === \"function\" && !msg._closed) {\n    msg.emit(\"error\", err);\n  }\n}\n\nfunction onError(self, err, cb) {\n  process.nextTick(() => emitErrorNt(self, err, cb));\n}\n\nfunction write_(msg, chunk, encoding, callback, fromEnd) {\n  if (typeof callback !== \"function\") callback = nop;\n\n  let len;\n  if (chunk === null) {\n    // throw new ERR_STREAM_NULL_VALUES();\n    throw new Error(\"ERR_STREAM_NULL_VALUES\");\n  } else if (typeof chunk === \"string\") {\n    len = Buffer.byteLength(chunk, encoding);\n  } else {\n    throw new Error(\"Invalid arg type for chunk\");\n    // throw new ERR_INVALID_ARG_TYPE(\n    //   \"chunk\",\n    //   [\"string\", \"Buffer\", \"Uint8Array\"],\n    //   chunk,\n    // );\n  }\n\n  let err;\n  if (msg.finished) {\n    // err = new ERR_STREAM_WRITE_AFTER_END();\n    err = new Error(\"ERR_STREAM_WRITE_AFTER_END\");\n  } else if (msg.destroyed) {\n    // err = new ERR_STREAM_DESTROYED(\"write\");\n    err = new Error(\"ERR_STREAM_DESTROYED\");\n  }\n\n  if (err) {\n    if (!msg.destroyed) {\n      onError(msg, err, callback);\n    } else {\n      process.nextTick(callback, err);\n    }\n    return false;\n  }\n\n  if (!msg._header) {\n    if (fromEnd) {\n      msg._contentLength = len;\n    }\n    // msg._implicitHeader();\n  }\n\n  if (!msg._hasBody) {\n    debug(\"This type of response MUST NOT have a body. \" + \"Ignoring write() calls.\");\n    process.nextTick(callback);\n    return true;\n  }\n\n  // if (!fromEnd && msg.socket && !msg.socket.writableCorked) {\n  //   msg.socket.cork();\n  //   process.nextTick(connectionCorkNT, msg.socket);\n  // }\n\n  return true;\n}\n\nexport class OutgoingMessage extends Writable {\n  #headers;\n  headersSent = false;\n  sendDate = true;\n  req;\n\n  #finished = false;\n  [kEndCalled] = false;\n\n  #fakeSocket;\n  #timeoutTimer = null;\n  [kAbortController] = null;\n\n  // For compat with IncomingRequest\n  get headers() {\n    if (!this.#headers) return kEmptyObject;\n    return this.#headers.toJSON();\n  }\n\n  get shouldKeepAlive() {\n    return true;\n  }\n\n  get chunkedEncoding() {\n    return false;\n  }\n\n  set chunkedEncoding(value) {\n    // throw new Error('not implemented');\n  }\n\n  set shouldKeepAlive(value) {\n    // throw new Error('not implemented');\n  }\n\n  get useChunkedEncodingByDefault() {\n    return true;\n  }\n\n  set useChunkedEncodingByDefault(value) {\n    // throw new Error('not implemented');\n  }\n\n  get socket() {\n    return (this.#fakeSocket ??= new FakeSocket());\n  }\n\n  set socket(val) {\n    this.#fakeSocket = val;\n  }\n\n  get connection() {\n    return this.socket;\n  }\n\n  get finished() {\n    return this.#finished;\n  }\n\n  appendHeader(name, value) {\n    var headers = (this.#headers ??= new Headers());\n    headers.append(name, value);\n  }\n\n  flushHeaders() {}\n\n  getHeader(name) {\n    return getHeader(this.#headers, name);\n  }\n\n  getHeaders() {\n    if (!this.#headers) return kEmptyObject;\n    return this.#headers.toJSON();\n  }\n\n  getHeaderNames() {\n    var headers = this.#headers;\n    if (!headers) return [];\n    return Array.from(headers.keys());\n  }\n\n  removeHeader(name) {\n    if (!this.#headers) return;\n    this.#headers.delete(name);\n  }\n\n  setHeader(name, value) {\n    var headers = (this.#headers ??= new Headers());\n    headers.set(name, value);\n    return this;\n  }\n\n  hasHeader(name) {\n    if (!this.#headers) return false;\n    return this.#headers.has(name);\n  }\n\n  addTrailers(headers) {\n    throw new Error(\"not implemented\");\n  }\n\n  [kClearTimeout]() {\n    if (this.#timeoutTimer) {\n      clearTimeout(this.#timeoutTimer);\n      this.#timeoutTimer = null;\n    }\n  }\n\n  setTimeout(msecs, callback) {\n    if (this.#timeoutTimer) return this;\n    if (callback) {\n      this.on(\"timeout\", callback);\n    }\n\n    this.#timeoutTimer = setTimeout(async () => {\n      this.#timeoutTimer = null;\n      this[kAbortController]?.abort();\n      this.emit(\"timeout\");\n    }, msecs);\n\n    return this;\n  }\n}\n\nexport class ServerResponse extends Writable {\n  constructor({ req, reply }) {\n    super();\n    this.req = req;\n    this._reply = reply;\n    this.sendDate = true;\n    this.statusCode = 200;\n    this.headersSent = false;\n    this.statusMessage = undefined;\n    this.#controller = undefined;\n    this.#firstWrite = undefined;\n    this._writableState.decodeStrings = false;\n    this.#deferred = undefined;\n  }\n\n  req;\n  _reply;\n  sendDate;\n  statusCode;\n  #headers;\n  headersSent = false;\n  statusMessage;\n  #controller;\n  #firstWrite;\n  _sent100 = false;\n  _defaultKeepAlive = false;\n  _removedConnection = false;\n  _removedContLen = false;\n  #deferred = undefined;\n  #finished = false;\n\n  _write(chunk, encoding, callback) {\n    if (!this.#firstWrite && !this.headersSent) {\n      this.#firstWrite = chunk;\n      callback();\n      return;\n    }\n\n    this.#ensureReadableStreamController(controller => {\n      controller.write(chunk);\n      callback();\n    });\n  }\n\n  _writev(chunks, callback) {\n    if (chunks.length === 1 && !this.headersSent && !this.#firstWrite) {\n      this.#firstWrite = chunks[0].chunk;\n      callback();\n      return;\n    }\n\n    this.#ensureReadableStreamController(controller => {\n      for (const chunk of chunks) {\n        controller.write(chunk.chunk);\n      }\n\n      callback();\n    });\n  }\n\n  #ensureReadableStreamController(run) {\n    var thisController = this.#controller;\n    if (thisController) return run(thisController);\n    this.headersSent = true;\n    var firstWrite = this.#firstWrite;\n    this.#firstWrite = undefined;\n    this._reply(\n      new Response(\n        new ReadableStream({\n          type: \"direct\",\n          pull: controller => {\n            this.#controller = controller;\n            if (firstWrite) controller.write(firstWrite);\n            firstWrite = undefined;\n            run(controller);\n            if (!this.#finished) {\n              return new Promise(resolve => {\n                this.#deferred = resolve;\n              });\n            }\n          },\n        }),\n        {\n          headers: this.#headers,\n          status: this.statusCode,\n          statusText: this.statusMessage ?? STATUS_CODES[this.statusCode],\n        },\n      ),\n    );\n  }\n\n  _final(callback) {\n    if (!this.headersSent) {\n      var data = this.#firstWrite || \"\";\n      this.#firstWrite = undefined;\n      this.#finished = true;\n      this._reply(\n        new Response(data, {\n          headers: this.#headers,\n          status: this.statusCode,\n          statusText: this.statusMessage ?? STATUS_CODES[this.statusCode],\n        }),\n      );\n      callback && callback();\n      return;\n    }\n\n    this.#finished = true;\n    this.#ensureReadableStreamController(controller => {\n      controller.end();\n\n      callback();\n      var deferred = this.#deferred;\n      if (deferred) {\n        this.#deferred = undefined;\n        deferred();\n      }\n    });\n  }\n\n  writeProcessing() {\n    throw new Error(\"not implemented\");\n  }\n\n  addTrailers(headers) {\n    throw new Error(\"not implemented\");\n  }\n\n  assignSocket(socket) {\n    throw new Error(\"not implemented\");\n  }\n\n  detachSocket(socket) {\n    throw new Error(\"not implemented\");\n  }\n\n  writeContinue(callback) {\n    throw new Error(\"not implemented\");\n  }\n\n  setTimeout(msecs, callback) {\n    throw new Error(\"not implemented\");\n  }\n\n  get shouldKeepAlive() {\n    return true;\n  }\n\n  get chunkedEncoding() {\n    return false;\n  }\n\n  set chunkedEncoding(value) {\n    // throw new Error('not implemented');\n  }\n\n  set shouldKeepAlive(value) {\n    // throw new Error('not implemented');\n  }\n\n  get useChunkedEncodingByDefault() {\n    return true;\n  }\n\n  set useChunkedEncodingByDefault(value) {\n    // throw new Error('not implemented');\n  }\n\n  appendHeader(name, value) {\n    var headers = (this.#headers ??= new Headers());\n    headers.append(name, value);\n  }\n\n  flushHeaders() {}\n\n  getHeader(name) {\n    return getHeader(this.#headers, name);\n  }\n\n  getHeaders() {\n    var headers = this.#headers;\n    if (!headers) return kEmptyObject;\n    return headers.toJSON();\n  }\n\n  getHeaderNames() {\n    var headers = this.#headers;\n    if (!headers) return [];\n    return Array.from(headers.keys());\n  }\n\n  removeHeader(name) {\n    if (!this.#headers) return;\n    this.#headers.delete(name);\n  }\n\n  setHeader(name, value) {\n    var headers = (this.#headers ??= new Headers());\n    headers.set(name, value);\n    return this;\n  }\n\n  hasHeader(name) {\n    if (!this.#headers) return false;\n    return this.#headers.has(name);\n  }\n\n  writeHead(statusCode, statusMessage, headers) {\n    _writeHead(statusCode, statusMessage, headers, this);\n\n    return this;\n  }\n}\n\nexport class ClientRequest extends OutgoingMessage {\n  #timeout;\n  #res = null;\n  #upgradeOrConnect = false;\n  #parser = null;\n  #maxHeadersCount = null;\n  #reusedSocket = false;\n  #host;\n  #protocol;\n  #method;\n  #port;\n  #useDefaultPort;\n  #joinDuplicateHeaders;\n  #maxHeaderSize;\n  #agent = _globalAgent;\n  #path;\n  #socketPath;\n\n  #body = null;\n  #fetchRequest;\n  #signal = null;\n  [kAbortController] = null;\n  #timeoutTimer = null;\n  #options;\n  #finished;\n\n  get path() {\n    return this.#path;\n  }\n\n  get port() {\n    return this.#port;\n  }\n\n  get method() {\n    return this.#method;\n  }\n\n  get host() {\n    return this.#host;\n  }\n\n  get protocol() {\n    return this.#protocol;\n  }\n\n  _write(chunk, encoding, callback) {\n    var body = this.#body;\n    if (!body) {\n      this.#body = chunk;\n      callback();\n      return;\n    }\n    this.#body = body + chunk;\n    callback();\n  }\n\n  _writev(chunks, callback) {\n    var body = this.#body;\n    if (!body) {\n      this.#body = chunks.join();\n      callback();\n      return;\n    }\n    this.#body = body + chunks.join();\n    callback();\n  }\n\n  _final(callback) {\n    this.#finished = true;\n    this[kAbortController] = new AbortController();\n    this[kAbortController].signal.addEventListener(\"abort\", () => {\n      this[kClearTimeout]();\n    });\n    if (this.#signal?.aborted) {\n      this[kAbortController].abort();\n    }\n\n    var method = this.#method,\n      body = this.#body;\n\n    try {\n      this.#fetchRequest = fetch(\n        `${this.#protocol}//${this.#host}${this.#useDefaultPort ? \"\" : \":\" + this.#port}${this.#path}`,\n        {\n          method,\n          headers: this.getHeaders(),\n          body: body && method !== \"GET\" && method !== \"HEAD\" && method !== \"OPTIONS\" ? body : undefined,\n          redirect: \"manual\",\n          verbose: Boolean(__DEBUG__),\n          signal: this[kAbortController].signal,\n        },\n      )\n        .then(response => {\n          var res = (this.#res = new IncomingMessage(response, {\n            type: \"response\",\n            [kInternalRequest]: this,\n          }));\n          this.emit(\"response\", res);\n        })\n        .catch(err => {\n          if (__DEBUG__) globalReportError(err);\n          this.emit(\"error\", err);\n        })\n        .finally(() => {\n          this.#fetchRequest = null;\n          this[kClearTimeout]();\n        });\n    } catch (err) {\n      if (__DEBUG__) globalReportError(err);\n      this.emit(\"error\", err);\n    } finally {\n      callback();\n    }\n  }\n\n  get aborted() {\n    return this.#signal?.aborted || !!this[kAbortController]?.signal.aborted;\n  }\n\n  abort() {\n    if (this.aborted) return;\n    this[kAbortController].abort();\n    // TODO: Close stream if body streaming\n  }\n\n  constructor(input, options, cb) {\n    super();\n\n    if (typeof input === \"string\") {\n      const urlStr = input;\n      try {\n        var urlObject = new URL(urlStr);\n      } catch (e) {\n        throw new TypeError(`Invalid URL: ${urlStr}`);\n      }\n      input = urlToHttpOptions(urlObject);\n    } else if (input && typeof input === \"object\" && input instanceof URL) {\n      // url.URL instance\n      input = urlToHttpOptions(input);\n    } else {\n      cb = options;\n      options = input;\n      input = null;\n    }\n\n    if (typeof options === \"function\") {\n      cb = options;\n      options = input || kEmptyObject;\n    } else {\n      options = ObjectAssign(input || {}, options);\n    }\n\n    var defaultAgent = options._defaultAgent || Agent.globalAgent;\n\n    let protocol = options.protocol;\n    if (!protocol) {\n      if (options.port === 443) {\n        protocol = \"https:\";\n      } else {\n        protocol = defaultAgent.protocol || \"http:\";\n      }\n      this.#protocol = protocol;\n    }\n\n    switch (this.#agent?.protocol) {\n      case undefined: {\n        break;\n      }\n      case \"http:\": {\n        if (protocol === \"https:\") {\n          defaultAgent = this.#agent = getDefaultHTTPSAgent();\n          break;\n        }\n      }\n      case \"https:\": {\n        if (protocol === \"https\") {\n          defaultAgent = this.#agent = Agent.globalAgent;\n          break;\n        }\n      }\n      default: {\n        break;\n      }\n    }\n\n    if (options.path) {\n      const path = String(options.path);\n      if (RegExpPrototypeExec.call(INVALID_PATH_REGEX, path) !== null) {\n        debug('Path contains unescaped characters: \"%s\"', path);\n        throw new Error(\"Path contains unescaped characters\");\n        // throw new ERR_UNESCAPED_CHARACTERS(\"Request path\");\n      }\n    }\n\n    // Since we don't implement Agent, we don't need this\n    if (protocol !== \"http:\" && protocol !== \"https:\" && protocol) {\n      const expectedProtocol = defaultAgent?.protocol ?? \"http:\";\n      throw new Error(`Protocol mismatch. Expected: ${expectedProtocol}. Got: ${protocol}`);\n      // throw new ERR_INVALID_PROTOCOL(protocol, expectedProtocol);\n    }\n\n    const defaultPort = protocol === \"https:\" ? 443 : 80;\n\n    this.#port = options.port || options.defaultPort || this.#agent?.defaultPort || defaultPort;\n    this.#useDefaultPort = this.#port === defaultPort;\n    const host =\n      (this.#host =\n      options.host =\n        validateHost(options.hostname, \"hostname\") || validateHost(options.host, \"host\") || \"localhost\");\n\n    // const setHost = options.setHost === undefined || Boolean(options.setHost);\n\n    this.#socketPath = options.socketPath;\n\n    if (options.timeout !== undefined) this.setTimeout(options.timeout, null);\n\n    const signal = options.signal;\n    if (signal) {\n      //We still want to control abort function and timeout so signal call our AbortController\n      signal.addEventListener(\"abort\", () => {\n        this[kAbortController]?.abort();\n      });\n      this.#signal = signal;\n    }\n    let method = options.method;\n    const methodIsString = typeof method === \"string\";\n    if (method !== null && method !== undefined && !methodIsString) {\n      // throw new ERR_INVALID_ARG_TYPE(\"options.method\", \"string\", method);\n      throw new Error(\"ERR_INVALID_ARG_TYPE: options.method\");\n    }\n\n    if (methodIsString && method) {\n      if (!checkIsHttpToken(method)) {\n        // throw new ERR_INVALID_HTTP_TOKEN(\"Method\", method);\n        throw new Error(\"ERR_INVALID_HTTP_TOKEN: Method\");\n      }\n      method = this.#method = StringPrototypeToUpperCase.call(method);\n    } else {\n      method = this.#method = \"GET\";\n    }\n\n    const _maxHeaderSize = options.maxHeaderSize;\n    // TODO: Validators\n    // if (maxHeaderSize !== undefined)\n    //   validateInteger(maxHeaderSize, \"maxHeaderSize\", 0);\n    this.#maxHeaderSize = _maxHeaderSize;\n\n    // const insecureHTTPParser = options.insecureHTTPParser;\n    // if (insecureHTTPParser !== undefined) {\n    //   validateBoolean(insecureHTTPParser, 'options.insecureHTTPParser');\n    // }\n\n    // this.insecureHTTPParser = insecureHTTPParser;\n    var _joinDuplicateHeaders = options.joinDuplicateHeaders;\n    if (_joinDuplicateHeaders !== undefined) {\n      // TODO: Validators\n      // validateBoolean(\n      //   options.joinDuplicateHeaders,\n      //   \"options.joinDuplicateHeaders\",\n      // );\n    }\n\n    this.#joinDuplicateHeaders = _joinDuplicateHeaders;\n\n    this.#path = options.path || \"/\";\n    if (cb) {\n      this.once(\"response\", cb);\n    }\n\n    __DEBUG__ &&\n      debug(`new ClientRequest: ${this.#method} ${this.#protocol}//${this.#host}:${this.#port}${this.#path}`);\n\n    // if (\n    //   method === \"GET\" ||\n    //   method === \"HEAD\" ||\n    //   method === \"DELETE\" ||\n    //   method === \"OPTIONS\" ||\n    //   method === \"TRACE\" ||\n    //   method === \"CONNECT\"\n    // ) {\n    //   this.useChunkedEncodingByDefault = false;\n    // } else {\n    //   this.useChunkedEncodingByDefault = true;\n    // }\n\n    this.#finished = false;\n    this.#res = null;\n    this.#upgradeOrConnect = false;\n    this.#parser = null;\n    this.#maxHeadersCount = null;\n    this.#reusedSocket = false;\n    this.#host = host;\n    this.#protocol = protocol;\n    this.#timeoutTimer = null;\n    const headersArray = ArrayIsArray(headers);\n    if (!headersArray) {\n      var headers = options.headers;\n      if (headers) {\n        for (let key in headers) {\n          this.setHeader(key, headers[key]);\n        }\n      }\n\n      // if (host && !this.getHeader(\"host\") && setHost) {\n      //   let hostHeader = host;\n\n      //   // For the Host header, ensure that IPv6 addresses are enclosed\n      //   // in square brackets, as defined by URI formatting\n      //   // https://tools.ietf.org/html/rfc3986#section-3.2.2\n      //   const posColon = StringPrototypeIndexOf.call(hostHeader, \":\");\n      //   if (\n      //     posColon !== -1 &&\n      //     StringPrototypeIncludes(hostHeader, \":\", posColon + 1) &&\n      //     StringPrototypeCharCodeAt(hostHeader, 0) !== 91 /* '[' */\n      //   ) {\n      //     hostHeader = `[${hostHeader}]`;\n      //   }\n\n      //   if (port && +port !== defaultPort) {\n      //     hostHeader += \":\" + port;\n      //   }\n      //   this.setHeader(\"Host\", hostHeader);\n      // }\n\n      var auth = options.auth;\n      if (auth && !this.getHeader(\"Authorization\")) {\n        this.setHeader(\"Authorization\", \"Basic \" + Buffer.from(auth).toString(\"base64\"));\n      }\n\n      //   if (this.getHeader(\"expect\")) {\n      //     if (this._header) {\n      //       throw new ERR_HTTP_HEADERS_SENT(\"render\");\n      //     }\n\n      //     this._storeHeader(\n      //       this.method + \" \" + this.path + \" HTTP/1.1\\r\\n\",\n      //       this[kOutHeaders],\n      //     );\n      //   }\n      // } else {\n      //   this._storeHeader(\n      //     this.method + \" \" + this.path + \" HTTP/1.1\\r\\n\",\n      //     options.headers,\n      //   );\n    }\n\n    // this[kUniqueHeaders] = parseUniqueHeadersOption(options.uniqueHeaders);\n\n    var optsWithoutSignal = options;\n    if (optsWithoutSignal.signal) {\n      optsWithoutSignal = ObjectAssign({}, options);\n      delete optsWithoutSignal.signal;\n    }\n    this.#options = optsWithoutSignal;\n\n    var timeout = options.timeout;\n    if (timeout) {\n      this.setTimeout(timeout);\n    }\n  }\n\n  setSocketKeepAlive(enable = true, initialDelay = 0) {\n    __DEBUG__ && debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: ClientRequest.setSocketKeepAlive is a no-op\");\n  }\n\n  setNoDelay(noDelay = true) {\n    __DEBUG__ && debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: ClientRequest.setNoDelay is a no-op\");\n  }\n  [kClearTimeout]() {\n    if (this.#timeoutTimer) {\n      clearTimeout(this.#timeoutTimer);\n      this.#timeoutTimer = null;\n    }\n  }\n\n  setTimeout(msecs, callback) {\n    if (this.#timeoutTimer) return this;\n    if (callback) {\n      this.on(\"timeout\", callback);\n    }\n\n    this.#timeoutTimer = setTimeout(async () => {\n      this.#timeoutTimer = null;\n      this[kAbortController]?.abort();\n      this.emit(\"timeout\");\n    }, msecs);\n\n    return this;\n  }\n}\n\nfunction urlToHttpOptions(url) {\n  var { protocol, hostname, hash, search, pathname, href, port, username, password } = url;\n  return {\n    protocol,\n    hostname:\n      typeof hostname === \"string\" && StringPrototypeStartsWith.call(hostname, \"[\")\n        ? StringPrototypeSlice.call(hostname, 1, -1)\n        : hostname,\n    hash,\n    search,\n    pathname,\n    path: `${pathname || \"\"}${search || \"\"}`,\n    href,\n    port: port ? Number(port) : protocol === \"https:\" ? 443 : protocol === \"http:\" ? 80 : undefined,\n    auth: username || password ? `${decodeURIComponent(username)}:${decodeURIComponent(password)}` : undefined,\n  };\n}\n\nfunction validateHost(host, name) {\n  if (host !== null && host !== undefined && typeof host !== \"string\") {\n    // throw new ERR_INVALID_ARG_TYPE(\n    //   `options.${name}`,\n    //   [\"string\", \"undefined\", \"null\"],\n    //   host,\n    // );\n    throw new Error(\"Invalid arg type in options\");\n  }\n  return host;\n}\n\nconst tokenRegExp = /^[\\^_`a-zA-Z\\-0-9!#$%&'*+.|~]+$/;\n/**\n * Verifies that the given val is a valid HTTP token\n * per the rules defined in RFC 7230\n * See https://tools.ietf.org/html/rfc7230#section-3.2.6\n */\nfunction checkIsHttpToken(val) {\n  return RegExpPrototypeExec.call(tokenRegExp, val) !== null;\n}\n\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nexport const METHODS = [\n  \"ACL\",\n  \"BIND\",\n  \"CHECKOUT\",\n  \"CONNECT\",\n  \"COPY\",\n  \"DELETE\",\n  \"GET\",\n  \"HEAD\",\n  \"LINK\",\n  \"LOCK\",\n  \"M-SEARCH\",\n  \"MERGE\",\n  \"MKACTIVITY\",\n  \"MKCALENDAR\",\n  \"MKCOL\",\n  \"MOVE\",\n  \"NOTIFY\",\n  \"OPTIONS\",\n  \"PATCH\",\n  \"POST\",\n  \"PROPFIND\",\n  \"PROPPATCH\",\n  \"PURGE\",\n  \"PUT\",\n  \"REBIND\",\n  \"REPORT\",\n  \"SEARCH\",\n  \"SOURCE\",\n  \"SUBSCRIBE\",\n  \"TRACE\",\n  \"UNBIND\",\n  \"UNLINK\",\n  \"UNLOCK\",\n  \"UNSUBSCRIBE\",\n];\n\nexport const STATUS_CODES = {\n  100: \"Continue\",\n  101: \"Switching Protocols\",\n  102: \"Processing\",\n  103: \"Early Hints\",\n  200: \"OK\",\n  201: \"Created\",\n  202: \"Accepted\",\n  203: \"Non-Authoritative Information\",\n  204: \"No Content\",\n  205: \"Reset Content\",\n  206: \"Partial Content\",\n  207: \"Multi-Status\",\n  208: \"Already Reported\",\n  226: \"IM Used\",\n  300: \"Multiple Choices\",\n  301: \"Moved Permanently\",\n  302: \"Found\",\n  303: \"See Other\",\n  304: \"Not Modified\",\n  305: \"Use Proxy\",\n  307: \"Temporary Redirect\",\n  308: \"Permanent Redirect\",\n  400: \"Bad Request\",\n  401: \"Unauthorized\",\n  402: \"Payment Required\",\n  403: \"Forbidden\",\n  404: \"Not Found\",\n  405: \"Method Not Allowed\",\n  406: \"Not Acceptable\",\n  407: \"Proxy Authentication Required\",\n  408: \"Request Timeout\",\n  409: \"Conflict\",\n  410: \"Gone\",\n  411: \"Length Required\",\n  412: \"Precondition Failed\",\n  413: \"Payload Too Large\",\n  414: \"URI Too Long\",\n  415: \"Unsupported Media Type\",\n  416: \"Range Not Satisfiable\",\n  417: \"Expectation Failed\",\n  418: \"I'm a Teapot\",\n  421: \"Misdirected Request\",\n  422: \"Unprocessable Entity\",\n  423: \"Locked\",\n  424: \"Failed Dependency\",\n  425: \"Too Early\",\n  426: \"Upgrade Required\",\n  428: \"Precondition Required\",\n  429: \"Too Many Requests\",\n  431: \"Request Header Fields Too Large\",\n  451: \"Unavailable For Legal Reasons\",\n  500: \"Internal Server Error\",\n  501: \"Not Implemented\",\n  502: \"Bad Gateway\",\n  503: \"Service Unavailable\",\n  504: \"Gateway Timeout\",\n  505: \"HTTP Version Not Supported\",\n  506: \"Variant Also Negotiates\",\n  507: \"Insufficient Storage\",\n  508: \"Loop Detected\",\n  509: \"Bandwidth Limit Exceeded\",\n  510: \"Not Extended\",\n  511: \"Network Authentication Required\",\n};\n\nfunction _normalizeArgs(args) {\n  let arr;\n\n  if (args.length === 0) {\n    arr = [{}, null];\n    // arr[normalizedArgsSymbol] = true;\n    return arr;\n  }\n\n  const arg0 = args[0];\n  let options = {};\n  if (typeof arg0 === \"object\" && arg0 !== null) {\n    // (options[...][, cb])\n    options = arg0;\n    // } else if (isPipeName(arg0)) {\n    // (path[...][, cb])\n    // options.path = arg0;\n  } else {\n    // ([port][, host][...][, cb])\n    options.port = arg0;\n    if (args.length > 1 && typeof args[1] === \"string\") {\n      options.host = args[1];\n    }\n  }\n\n  const cb = args[args.length - 1];\n  if (typeof cb !== \"function\") arr = [options, null];\n  else arr = [options, cb];\n\n  // arr[normalizedArgsSymbol] = true;\n  return arr;\n}\n\nfunction _writeHead(statusCode, reason, obj, response) {\n  statusCode |= 0;\n  if (statusCode < 100 || statusCode > 999) {\n    throw new Error(\"status code must be between 100 and 999\");\n  }\n\n  if (typeof reason === \"string\") {\n    // writeHead(statusCode, reasonPhrase[, headers])\n    response.statusMessage = reason;\n  } else {\n    // writeHead(statusCode[, headers])\n    if (!response.statusMessage) response.statusMessage = STATUS_CODES[statusCode] || \"unknown\";\n    obj = reason;\n  }\n  response.statusCode = statusCode;\n\n  {\n    // Slow-case: when progressive API and header fields are passed.\n    let k;\n    if (Array.isArray(obj)) {\n      if (obj.length % 2 !== 0) {\n        throw new Error(\"raw headers must have an even number of elements\");\n      }\n\n      for (let n = 0; n < obj.length; n += 2) {\n        k = obj[n + 0];\n        if (k) response.setHeader(k, obj[n + 1]);\n      }\n    } else if (obj) {\n      const keys = Object.keys(obj);\n      // Retain for(;;) loop for performance reasons\n      // Refs: https://github.com/nodejs/node/pull/30958\n      for (let i = 0; i < keys.length; i++) {\n        k = keys[i];\n        if (k) response.setHeader(k, obj[k]);\n      }\n    }\n  }\n}\n\n/**\n * Makes an HTTP request.\n * @param {string | URL} url\n * @param {HTTPRequestOptions} [options]\n * @param {Function} [cb]\n * @returns {ClientRequest}\n */\nexport function request(url, options, cb) {\n  return new ClientRequest(url, options, cb);\n}\n\n/**\n * Makes a `GET` HTTP request.\n * @param {string | URL} url\n * @param {HTTPRequestOptions} [options]\n * @param {Function} [cb]\n * @returns {ClientRequest}\n */\nexport function get(url, options, cb) {\n  const req = request(url, options, cb);\n  req.end();\n  return req;\n}\n\nvar defaultObject = {\n  Agent,\n  Server,\n  METHODS,\n  STATUS_CODES,\n  createServer,\n  ServerResponse,\n  IncomingMessage,\n  request,\n  get,\n  maxHeaderSize: 16384,\n  // validateHeaderName,\n  // validateHeaderValue,\n  setMaxIdleHTTPParsers(max) {\n    debug(`${NODE_HTTP_WARNING}\\n`, \"setMaxIdleHTTPParsers() is a no-op\");\n  },\n  get globalAgent() {\n    return (_globalAgent ??= new Agent());\n  },\n  set globalAgent(agent) {},\n  [Symbol.for(\"CommonJS\")]: 0,\n};\n\nexport default defaultObject;\n",
  "// Hardcoded module \"node:http\"\nconst { EventEmitter } = import.meta.require(\"node:events\");\nconst { isIPv6 } = import.meta.require(\"node:net\");\nconst { Readable, Writable, Duplex } = import.meta.require(\"node:stream\");\nconst { URL } = import.meta.require(\"node:url\");\nconst { newArrayWithSize, String, Object, Array } = import.meta.primordials;\nconst { isTypedArray } = import.meta.require(\"util/types\");\n\nconst globalReportError = globalThis.reportError;\nconst setTimeout = globalThis.setTimeout;\nconst fetch = Bun.fetch;\nconst nop = () => {};\n\nconst __DEBUG__ = process.env.__DEBUG__;\nconst debug = __DEBUG__ ? (...args) => console.log(\"node:http\", ...args) : nop;\n\nconst kEmptyObject = Object.freeze(Object.create(null));\nconst kOutHeaders = Symbol.for(\"kOutHeaders\");\nconst kEndCalled = Symbol.for(\"kEndCalled\");\nconst kAbortController = Symbol.for(\"kAbortController\");\nconst kClearTimeout = Symbol(\"kClearTimeout\");\n\nconst kCorked = Symbol.for(\"kCorked\");\nconst searchParamsSymbol = Symbol.for(\"query\"); // This is the symbol used in Node\n\n// Primordials\nconst StringPrototypeSlice = String.prototype.slice;\nconst StringPrototypeStartsWith = String.prototype.startsWith;\nconst StringPrototypeToUpperCase = String.prototype.toUpperCase;\nconst StringPrototypeIncludes = String.prototype.includes;\nconst StringPrototypeCharCodeAt = String.prototype.charCodeAt;\nconst StringPrototypeIndexOf = String.prototype.indexOf;\nconst ArrayIsArray = Array.isArray;\nconst RegExpPrototypeExec = RegExp.prototype.exec;\nconst ObjectAssign = Object.assign;\nconst ObjectPrototypeHasOwnProperty = Object.prototype.hasOwnProperty;\n\nconst INVALID_PATH_REGEX = /[^\\u0021-\\u00ff]/;\nconst NODE_HTTP_WARNING =\n  \"WARN: Agent is mostly unused in Bun's implementation of http. If you see strange behavior, this is probably the cause.\";\n\nvar _globalAgent;\nvar _defaultHTTPSAgent;\nvar kInternalRequest = Symbol(\"kInternalRequest\");\nvar kInternalSocketData = Symbol.for(\"::bunternal::\");\n\nconst kEmptyBuffer = Buffer.alloc(0);\n\nfunction isValidTLSArray(obj) {\n  if (typeof obj === \"string\" || isTypedArray(obj) || obj instanceof ArrayBuffer || obj instanceof Blob) return true;\n  if (Array.isArray(obj)) {\n    for (var i = 0; i < obj.length; i++) {\n      if (typeof obj !== \"string\" && !isTypedArray(obj) && !(obj instanceof ArrayBuffer) && !(obj instanceof Blob))\n        return false;\n    }\n    return true;\n  }\n}\n\nfunction getHeader(headers, name) {\n  if (!headers) return;\n  const result = headers.get(name);\n  return result == null ? undefined : result;\n}\n\nvar FakeSocket = class Socket extends Duplex {\n  bytesRead = 0;\n  bytesWritten = 0;\n  connecting = false;\n  remoteAddress = null;\n  localAddress = \"127.0.0.1\";\n  remotePort;\n  timeout = 0;\n\n  isServer = false;\n\n  address() {\n    return {\n      address: this.localAddress,\n      family: this.localFamily,\n      port: this.localPort,\n    };\n  }\n\n  get bufferSize() {\n    return this.writableLength;\n  }\n\n  connect(port, host, connectListener) {\n    return this;\n  }\n\n  _destroy(err, callback) {}\n\n  _final(callback) {}\n\n  get localAddress() {\n    return \"127.0.0.1\";\n  }\n\n  get localFamily() {\n    return \"IPv4\";\n  }\n\n  get localPort() {\n    return 80;\n  }\n\n  get pending() {\n    return this.connecting;\n  }\n\n  _read(size) {}\n\n  get readyState() {\n    if (this.connecting) return \"opening\";\n    if (this.readable) {\n      return this.writable ? \"open\" : \"readOnly\";\n    } else {\n      return this.writable ? \"writeOnly\" : \"closed\";\n    }\n  }\n\n  ref() {}\n\n  get remoteFamily() {\n    return \"IPv4\";\n  }\n\n  resetAndDestroy() {}\n\n  setKeepAlive(enable = false, initialDelay = 0) {}\n\n  setNoDelay(noDelay = true) {\n    return this;\n  }\n\n  setTimeout(timeout, callback) {\n    return this;\n  }\n\n  unref() {}\n\n  _write(chunk, encoding, callback) {}\n};\n\nexport function createServer(options, callback) {\n  return new Server(options, callback);\n}\n\nexport class Agent extends EventEmitter {\n  #defaultPort = 80;\n  #protocol = \"http:\";\n  #options;\n  #requests;\n  #sockets;\n  #freeSockets;\n\n  #keepAliveMsecs;\n  #keepAlive;\n  #maxSockets;\n  #maxFreeSockets;\n  #scheduling;\n  #maxTotalSockets;\n  #totalSocketCount;\n\n  #fakeSocket;\n\n  static get globalAgent() {\n    return (_globalAgent ??= new Agent());\n  }\n\n  static get defaultMaxSockets() {\n    return Infinity;\n  }\n\n  constructor(options = kEmptyObject) {\n    super();\n    this.#options = options = { ...options, path: null };\n    if (options.noDelay === undefined) options.noDelay = true;\n\n    // Don't confuse net and make it think that we're connecting to a pipe\n    this.#requests = kEmptyObject;\n    this.#sockets = kEmptyObject;\n    this.#freeSockets = kEmptyObject;\n\n    this.#keepAliveMsecs = options.keepAliveMsecs || 1000;\n    this.#keepAlive = options.keepAlive || false;\n    this.#maxSockets = options.maxSockets || Agent.defaultMaxSockets;\n    this.#maxFreeSockets = options.maxFreeSockets || 256;\n    this.#scheduling = options.scheduling || \"lifo\";\n    this.#maxTotalSockets = options.maxTotalSockets;\n    this.#totalSocketCount = 0;\n    this.#defaultPort = options.defaultPort || 80;\n    this.#protocol = options.protocol || \"http:\";\n  }\n\n  get defaultPort() {\n    return this.#defaultPort;\n  }\n\n  get protocol() {\n    return this.#protocol;\n  }\n\n  get requests() {\n    return this.#requests;\n  }\n\n  get sockets() {\n    return this.#sockets;\n  }\n\n  get freeSockets() {\n    return this.#freeSockets;\n  }\n\n  get options() {\n    return this.#options;\n  }\n\n  get keepAliveMsecs() {\n    return this.#keepAliveMsecs;\n  }\n\n  get keepAlive() {\n    return this.#keepAlive;\n  }\n\n  get maxSockets() {\n    return this.#maxSockets;\n  }\n\n  get maxFreeSockets() {\n    return this.#maxFreeSockets;\n  }\n\n  get scheduling() {\n    return this.#scheduling;\n  }\n\n  get maxTotalSockets() {\n    return this.#maxTotalSockets;\n  }\n\n  get totalSocketCount() {\n    return this.#totalSocketCount;\n  }\n\n  createConnection() {\n    debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: Agent.createConnection is a no-op, returns fake socket\");\n    return (this.#fakeSocket ??= new FakeSocket());\n  }\n\n  getName(options = kEmptyObject) {\n    let name = `http:${options.host || \"localhost\"}:`;\n    if (options.port) name += options.port;\n    name += \":\";\n    if (options.localAddress) name += options.localAddress;\n    // Pacify parallel/test-http-agent-getname by only appending\n    // the ':' when options.family is set.\n    if (options.family === 4 || options.family === 6) name += `:${options.family}`;\n    if (options.socketPath) name += `:${options.socketPath}`;\n    return name;\n  }\n\n  addRequest() {\n    debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: Agent.addRequest is a no-op\");\n  }\n\n  createSocket(req, options, cb) {\n    debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: Agent.createSocket returns fake socket\");\n    cb(null, (this.#fakeSocket ??= new FakeSocket()));\n  }\n\n  removeSocket() {\n    debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: Agent.removeSocket is a no-op\");\n  }\n\n  keepSocketAlive() {\n    debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: Agent.keepSocketAlive is a no-op\");\n\n    return true;\n  }\n\n  reuseSocket() {\n    debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: Agent.reuseSocket is a no-op\");\n  }\n\n  destroy() {\n    debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: Agent.destroy is a no-op\");\n  }\n}\nfunction emitListeningNextTick(self, onListen, err, hostname, port) {\n  if (typeof onListen === \"function\") {\n    try {\n      onListen(err, hostname, port);\n    } catch (err) {\n      self.emit(\"error\", err);\n    }\n  }\n\n  self.listening = !err;\n\n  if (err) {\n    self.emit(\"error\", err);\n  } else {\n    self.emit(\"listening\", hostname, port);\n  }\n}\n\nexport class Server extends EventEmitter {\n  #server;\n  #options;\n  #tls;\n  #is_tls = false;\n  listening = false;\n\n  constructor(options, callback) {\n    super();\n\n    if (typeof options === \"function\") {\n      callback = options;\n      options = {};\n    } else if (options == null || typeof options === \"object\") {\n      options = { ...options };\n      this.#tls = null;\n      let key = options.key;\n      if (key) {\n        if (!isValidTLSArray(key)) {\n          throw new TypeError(\n            \"key argument must be an string, Buffer, TypedArray, BunFile or an array containing string, Buffer, TypedArray or BunFile\",\n          );\n        }\n        this.#is_tls = true;\n      }\n      let cert = options.cert;\n      if (cert) {\n        if (!isValidTLSArray(cert)) {\n          throw new TypeError(\n            \"cert argument must be an string, Buffer, TypedArray, BunFile or an array containing string, Buffer, TypedArray or BunFile\",\n          );\n        }\n        this.#is_tls = true;\n      }\n\n      let ca = options.ca;\n      if (ca) {\n        if (!isValidTLSArray(ca)) {\n          throw new TypeError(\n            \"ca argument must be an string, Buffer, TypedArray, BunFile or an array containing string, Buffer, TypedArray or BunFile\",\n          );\n        }\n        this.#is_tls = true;\n      }\n      let passphrase = options.passphrase;\n      if (passphrase && typeof passphrase !== \"string\") {\n        throw new TypeError(\"passphrase argument must be an string\");\n      }\n\n      let serverName = options.servername;\n      if (serverName && typeof serverName !== \"string\") {\n        throw new TypeError(\"servername argument must be an string\");\n      }\n\n      let secureOptions = options.secureOptions || 0;\n      if (secureOptions && typeof secureOptions !== \"number\") {\n        throw new TypeError(\"secureOptions argument must be an number\");\n      }\n\n      if (this.#is_tls) {\n        this.#tls = {\n          serverName,\n          key: key,\n          cert: cert,\n          ca: ca,\n          passphrase: passphrase,\n          secureOptions: secureOptions,\n        };\n      } else {\n        this.#tls = null;\n      }\n    } else {\n      throw new Error(\"bun-http-polyfill: invalid arguments\");\n    }\n\n    this.#options = options;\n\n    if (callback) this.on(\"request\", callback);\n  }\n\n  closeAllConnections() {\n    const server = this.#server;\n    if (!server) {\n      return;\n    }\n    this.#server = undefined;\n    server.stop(true);\n    this.emit(\"close\");\n  }\n\n  closeIdleConnections() {\n    // not actually implemented\n  }\n\n  close(optionalCallback) {\n    const server = this.#server;\n    if (!server) {\n      if (typeof optionalCallback === \"function\")\n        process.nextTick(optionalCallback, new Error(\"Server is not running\"));\n      return;\n    }\n    this.#server = undefined;\n    if (typeof optionalCallback === \"function\") this.once(\"close\", optionalCallback);\n    server.stop();\n    this.emit(\"close\");\n  }\n\n  address() {\n    if (!this.#server) return null;\n\n    const address = this.#server.hostname;\n    return {\n      address,\n      family: isIPv6(address) ? \"IPv6\" : \"IPv4\",\n      port: this.#server.port,\n    };\n  }\n\n  listen(port, host, backlog, onListen) {\n    const server = this;\n    if (typeof host === \"function\") {\n      onListen = host;\n      host = undefined;\n    }\n\n    if (typeof port === \"function\") {\n      onListen = port;\n    } else if (typeof port === \"object\") {\n      port?.signal?.addEventListener(\"abort\", () => {\n        this.close();\n      });\n\n      host = port?.host;\n      port = port?.port;\n\n      if (typeof port?.callback === \"function\") onListen = port?.callback;\n    }\n\n    if (typeof backlog === \"function\") {\n      onListen = backlog;\n    }\n\n    const ResponseClass = this.#options.ServerResponse || ServerResponse;\n    const RequestClass = this.#options.IncomingMessage || IncomingMessage;\n\n    try {\n      const tls = this.#tls;\n      if (tls) {\n        this.serverName = tls.serverName || host || \"localhost\";\n      }\n      this.#server = Bun.serve({\n        tls,\n        port,\n        hostname: host,\n        // Bindings to be used for WS Server\n        websocket: {\n          open(ws) {\n            ws.data.open(ws);\n          },\n          message(ws, message) {\n            ws.data.message(ws, message);\n          },\n          close(ws, code, reason) {\n            ws.data.close(ws, code, reason);\n          },\n          drain(ws) {\n            ws.data.drain(ws);\n          },\n        },\n        fetch(req, _server) {\n          var pendingResponse;\n          var pendingError;\n          var rejectFunction, resolveFunction;\n          var reject = err => {\n            if (pendingError) return;\n            pendingError = err;\n            if (rejectFunction) rejectFunction(err);\n          };\n\n          var reply = function (resp) {\n            if (pendingResponse) return;\n            pendingResponse = resp;\n            if (resolveFunction) resolveFunction(resp);\n          };\n\n          const http_req = new RequestClass(req);\n          const http_res = new ResponseClass({ reply, req: http_req });\n\n          http_req.once(\"error\", err => reject(err));\n          http_res.once(\"error\", err => reject(err));\n\n          const upgrade = req.headers.get(\"upgrade\");\n          if (upgrade) {\n            const socket = new FakeSocket();\n            socket[kInternalSocketData] = [_server, http_res, req];\n            server.emit(\"upgrade\", http_req, socket, kEmptyBuffer);\n          } else {\n            server.emit(\"request\", http_req, http_res);\n          }\n\n          if (pendingError) {\n            throw pendingError;\n          }\n\n          if (pendingResponse) {\n            return pendingResponse;\n          }\n\n          return new Promise((resolve, reject) => {\n            resolveFunction = resolve;\n            rejectFunction = reject;\n          });\n        },\n      });\n      setTimeout(emitListeningNextTick, 1, this, onListen, null, this.#server.hostname, this.#server.port);\n    } catch (err) {\n      setTimeout(emitListeningNextTick, 1, this, onListen, err);\n    }\n\n    return this;\n  }\n  setTimeout(msecs, callback) {}\n}\n\nfunction assignHeaders(object, req) {\n  var headers = req.headers.toJSON();\n  const rawHeaders = newArrayWithSize(req.headers.count * 2);\n  var i = 0;\n  for (const key in headers) {\n    rawHeaders[i++] = key;\n    rawHeaders[i++] = headers[key];\n  }\n  object.headers = headers;\n  object.rawHeaders = rawHeaders;\n}\nfunction destroyBodyStreamNT(bodyStream) {\n  bodyStream.destroy();\n}\n\nvar defaultIncomingOpts = { type: \"request\" };\n\nfunction getDefaultHTTPSAgent() {\n  return (_defaultHTTPSAgent ??= new Agent({ defaultPort: 443, protocol: \"https:\" }));\n}\n\nexport class IncomingMessage extends Readable {\n  constructor(req, defaultIncomingOpts) {\n    const method = req.method;\n\n    super();\n\n    const url = new URL(req.url);\n\n    var { type = \"request\", [kInternalRequest]: nodeReq } = defaultIncomingOpts || {};\n\n    this.#noBody =\n      type === \"request\" // TODO: Add logic for checking for body on response\n        ? \"GET\" === method ||\n          \"HEAD\" === method ||\n          \"TRACE\" === method ||\n          \"CONNECT\" === method ||\n          \"OPTIONS\" === method ||\n          (parseInt(req.headers.get(\"Content-Length\") || \"\") || 0) === 0\n        : false;\n\n    this.#req = req;\n    this.method = method;\n    this.#type = type;\n    this.complete = !!this.#noBody;\n\n    this.#bodyStream = null;\n    const socket = new FakeSocket();\n    socket.remoteAddress = url.hostname;\n    socket.remotePort = url.port;\n    this.#fakeSocket = socket;\n\n    this.url = url.pathname + url.search;\n    this.#nodeReq = nodeReq;\n    assignHeaders(this, req);\n  }\n\n  headers;\n  rawHeaders;\n  _consuming = false;\n  _dumped = false;\n  #bodyStream = null;\n  #fakeSocket = undefined;\n  #noBody = false;\n  #aborted = false;\n  #req;\n  url;\n  #type;\n  #nodeReq;\n\n  get req() {\n    return this.#nodeReq;\n  }\n\n  _construct(callback) {\n    // TODO: streaming\n    if (this.#type === \"response\" || this.#noBody) {\n      callback();\n      return;\n    }\n\n    const contentLength = this.#req.headers.get(\"content-length\");\n    const length = contentLength ? parseInt(contentLength, 10) : 0;\n    if (length === 0) {\n      this.#noBody = true;\n      callback();\n      return;\n    }\n\n    callback();\n  }\n\n  #closeBodyStream() {\n    debug(\"closeBodyStream()\");\n    var bodyStream = this.#bodyStream;\n    if (bodyStream == null) return;\n    this.complete = true;\n    this.#bodyStream = undefined;\n    this.push(null);\n    // process.nextTick(destroyBodyStreamNT, bodyStream);\n  }\n\n  _read(size) {\n    if (this.#noBody) {\n      this.push(null);\n      this.complete = true;\n    } else if (this.#bodyStream == null) {\n      const contentLength = this.#req.headers.get(\"content-length\");\n      let remaining = contentLength ? parseInt(contentLength, 10) : 0;\n      this.#bodyStream = Readable.fromWeb(this.#req.body, {\n        highWaterMark: Number.isFinite(remaining) ? Math.min(remaining, 16384) : 16384,\n      });\n\n      const isBodySizeKnown = remaining > 0 && Number.isSafeInteger(remaining);\n\n      if (isBodySizeKnown) {\n        this.#bodyStream.on(\"data\", chunk => {\n          debug(\"body size known\", remaining);\n          this.push(chunk);\n          // when we are streaming a known body size, automatically close the stream when we have read enough\n          remaining -= chunk?.byteLength ?? 0;\n          if (remaining <= 0) {\n            this.#closeBodyStream();\n          }\n        });\n      } else {\n        this.#bodyStream.on(\"data\", chunk => {\n          this.push(chunk);\n        });\n      }\n\n      // this can be closed by the time we get here if enough data was synchronously available\n      this.#bodyStream &&\n        this.#bodyStream.on(\"end\", () => {\n          this.#closeBodyStream();\n        });\n    } else {\n      // this.#bodyStream.read(size);\n    }\n  }\n\n  get aborted() {\n    return this.#aborted;\n  }\n\n  abort() {\n    if (this.#aborted) return;\n    this.#aborted = true;\n\n    this.#closeBodyStream();\n  }\n\n  get connection() {\n    return this.#fakeSocket;\n  }\n\n  get statusCode() {\n    return this.#req.status;\n  }\n\n  get statusMessage() {\n    return STATUS_CODES[this.#req.status];\n  }\n\n  get httpVersion() {\n    return \"1.1\";\n  }\n\n  get rawTrailers() {\n    return [];\n  }\n\n  get httpVersionMajor() {\n    return 1;\n  }\n\n  get httpVersionMinor() {\n    return 1;\n  }\n\n  get trailers() {\n    return kEmptyObject;\n  }\n\n  get socket() {\n    return (this.#fakeSocket ??= new FakeSocket());\n  }\n\n  set socket(val) {\n    this.#fakeSocket = val;\n  }\n\n  setTimeout(msecs, callback) {\n    throw new Error(\"not implemented\");\n  }\n}\n\nfunction emitErrorNt(msg, err, callback) {\n  callback(err);\n  if (typeof msg.emit === \"function\" && !msg._closed) {\n    msg.emit(\"error\", err);\n  }\n}\n\nfunction onError(self, err, cb) {\n  process.nextTick(() => emitErrorNt(self, err, cb));\n}\n\nfunction write_(msg, chunk, encoding, callback, fromEnd) {\n  if (typeof callback !== \"function\") callback = nop;\n\n  let len;\n  if (chunk === null) {\n    // throw new ERR_STREAM_NULL_VALUES();\n    throw new Error(\"ERR_STREAM_NULL_VALUES\");\n  } else if (typeof chunk === \"string\") {\n    len = Buffer.byteLength(chunk, encoding);\n  } else {\n    throw new Error(\"Invalid arg type for chunk\");\n    // throw new ERR_INVALID_ARG_TYPE(\n    //   \"chunk\",\n    //   [\"string\", \"Buffer\", \"Uint8Array\"],\n    //   chunk,\n    // );\n  }\n\n  let err;\n  if (msg.finished) {\n    // err = new ERR_STREAM_WRITE_AFTER_END();\n    err = new Error(\"ERR_STREAM_WRITE_AFTER_END\");\n  } else if (msg.destroyed) {\n    // err = new ERR_STREAM_DESTROYED(\"write\");\n    err = new Error(\"ERR_STREAM_DESTROYED\");\n  }\n\n  if (err) {\n    if (!msg.destroyed) {\n      onError(msg, err, callback);\n    } else {\n      process.nextTick(callback, err);\n    }\n    return false;\n  }\n\n  if (!msg._header) {\n    if (fromEnd) {\n      msg._contentLength = len;\n    }\n    // msg._implicitHeader();\n  }\n\n  if (!msg._hasBody) {\n    debug(\"This type of response MUST NOT have a body. \" + \"Ignoring write() calls.\");\n    process.nextTick(callback);\n    return true;\n  }\n\n  // if (!fromEnd && msg.socket && !msg.socket.writableCorked) {\n  //   msg.socket.cork();\n  //   process.nextTick(connectionCorkNT, msg.socket);\n  // }\n\n  return true;\n}\n\nexport class OutgoingMessage extends Writable {\n  #headers;\n  headersSent = false;\n  sendDate = true;\n  req;\n\n  #finished = false;\n  [kEndCalled] = false;\n\n  #fakeSocket;\n  #timeoutTimer = null;\n  [kAbortController] = null;\n\n  // For compat with IncomingRequest\n  get headers() {\n    if (!this.#headers) return kEmptyObject;\n    return this.#headers.toJSON();\n  }\n\n  get shouldKeepAlive() {\n    return true;\n  }\n\n  get chunkedEncoding() {\n    return false;\n  }\n\n  set chunkedEncoding(value) {\n    // throw new Error('not implemented');\n  }\n\n  set shouldKeepAlive(value) {\n    // throw new Error('not implemented');\n  }\n\n  get useChunkedEncodingByDefault() {\n    return true;\n  }\n\n  set useChunkedEncodingByDefault(value) {\n    // throw new Error('not implemented');\n  }\n\n  get socket() {\n    return (this.#fakeSocket ??= new FakeSocket());\n  }\n\n  set socket(val) {\n    this.#fakeSocket = val;\n  }\n\n  get connection() {\n    return this.socket;\n  }\n\n  get finished() {\n    return this.#finished;\n  }\n\n  appendHeader(name, value) {\n    var headers = (this.#headers ??= new Headers());\n    headers.append(name, value);\n  }\n\n  flushHeaders() {}\n\n  getHeader(name) {\n    return getHeader(this.#headers, name);\n  }\n\n  getHeaders() {\n    if (!this.#headers) return kEmptyObject;\n    return this.#headers.toJSON();\n  }\n\n  getHeaderNames() {\n    var headers = this.#headers;\n    if (!headers) return [];\n    return Array.from(headers.keys());\n  }\n\n  removeHeader(name) {\n    if (!this.#headers) return;\n    this.#headers.delete(name);\n  }\n\n  setHeader(name, value) {\n    var headers = (this.#headers ??= new Headers());\n    headers.set(name, value);\n    return this;\n  }\n\n  hasHeader(name) {\n    if (!this.#headers) return false;\n    return this.#headers.has(name);\n  }\n\n  addTrailers(headers) {\n    throw new Error(\"not implemented\");\n  }\n\n  [kClearTimeout]() {\n    if (this.#timeoutTimer) {\n      clearTimeout(this.#timeoutTimer);\n      this.#timeoutTimer = null;\n    }\n  }\n\n  setTimeout(msecs, callback) {\n    if (this.#timeoutTimer) return this;\n    if (callback) {\n      this.on(\"timeout\", callback);\n    }\n\n    this.#timeoutTimer = setTimeout(async () => {\n      this.#timeoutTimer = null;\n      this[kAbortController]?.abort();\n      this.emit(\"timeout\");\n    }, msecs);\n\n    return this;\n  }\n}\n\nexport class ServerResponse extends Writable {\n  constructor({ req, reply }) {\n    super();\n    this.req = req;\n    this._reply = reply;\n    this.sendDate = true;\n    this.statusCode = 200;\n    this.headersSent = false;\n    this.statusMessage = undefined;\n    this.#controller = undefined;\n    this.#firstWrite = undefined;\n    this._writableState.decodeStrings = false;\n    this.#deferred = undefined;\n  }\n\n  req;\n  _reply;\n  sendDate;\n  statusCode;\n  #headers;\n  headersSent = false;\n  statusMessage;\n  #controller;\n  #firstWrite;\n  _sent100 = false;\n  _defaultKeepAlive = false;\n  _removedConnection = false;\n  _removedContLen = false;\n  #deferred = undefined;\n  #finished = false;\n\n  _write(chunk, encoding, callback) {\n    if (!this.#firstWrite && !this.headersSent) {\n      this.#firstWrite = chunk;\n      callback();\n      return;\n    }\n\n    this.#ensureReadableStreamController(controller => {\n      controller.write(chunk);\n      callback();\n    });\n  }\n\n  _writev(chunks, callback) {\n    if (chunks.length === 1 && !this.headersSent && !this.#firstWrite) {\n      this.#firstWrite = chunks[0].chunk;\n      callback();\n      return;\n    }\n\n    this.#ensureReadableStreamController(controller => {\n      for (const chunk of chunks) {\n        controller.write(chunk.chunk);\n      }\n\n      callback();\n    });\n  }\n\n  #ensureReadableStreamController(run) {\n    var thisController = this.#controller;\n    if (thisController) return run(thisController);\n    this.headersSent = true;\n    var firstWrite = this.#firstWrite;\n    this.#firstWrite = undefined;\n    this._reply(\n      new Response(\n        new ReadableStream({\n          type: \"direct\",\n          pull: controller => {\n            this.#controller = controller;\n            if (firstWrite) controller.write(firstWrite);\n            firstWrite = undefined;\n            run(controller);\n            if (!this.#finished) {\n              return new Promise(resolve => {\n                this.#deferred = resolve;\n              });\n            }\n          },\n        }),\n        {\n          headers: this.#headers,\n          status: this.statusCode,\n          statusText: this.statusMessage ?? STATUS_CODES[this.statusCode],\n        },\n      ),\n    );\n  }\n\n  _final(callback) {\n    if (!this.headersSent) {\n      var data = this.#firstWrite || \"\";\n      this.#firstWrite = undefined;\n      this.#finished = true;\n      this._reply(\n        new Response(data, {\n          headers: this.#headers,\n          status: this.statusCode,\n          statusText: this.statusMessage ?? STATUS_CODES[this.statusCode],\n        }),\n      );\n      callback && callback();\n      return;\n    }\n\n    this.#finished = true;\n    this.#ensureReadableStreamController(controller => {\n      controller.end();\n\n      callback();\n      var deferred = this.#deferred;\n      if (deferred) {\n        this.#deferred = undefined;\n        deferred();\n      }\n    });\n  }\n\n  writeProcessing() {\n    throw new Error(\"not implemented\");\n  }\n\n  addTrailers(headers) {\n    throw new Error(\"not implemented\");\n  }\n\n  assignSocket(socket) {\n    throw new Error(\"not implemented\");\n  }\n\n  detachSocket(socket) {\n    throw new Error(\"not implemented\");\n  }\n\n  writeContinue(callback) {\n    throw new Error(\"not implemented\");\n  }\n\n  setTimeout(msecs, callback) {\n    throw new Error(\"not implemented\");\n  }\n\n  get shouldKeepAlive() {\n    return true;\n  }\n\n  get chunkedEncoding() {\n    return false;\n  }\n\n  set chunkedEncoding(value) {\n    // throw new Error('not implemented');\n  }\n\n  set shouldKeepAlive(value) {\n    // throw new Error('not implemented');\n  }\n\n  get useChunkedEncodingByDefault() {\n    return true;\n  }\n\n  set useChunkedEncodingByDefault(value) {\n    // throw new Error('not implemented');\n  }\n\n  appendHeader(name, value) {\n    var headers = (this.#headers ??= new Headers());\n    headers.append(name, value);\n  }\n\n  flushHeaders() {}\n\n  getHeader(name) {\n    return getHeader(this.#headers, name);\n  }\n\n  getHeaders() {\n    var headers = this.#headers;\n    if (!headers) return kEmptyObject;\n    return headers.toJSON();\n  }\n\n  getHeaderNames() {\n    var headers = this.#headers;\n    if (!headers) return [];\n    return Array.from(headers.keys());\n  }\n\n  removeHeader(name) {\n    if (!this.#headers) return;\n    this.#headers.delete(name);\n  }\n\n  setHeader(name, value) {\n    var headers = (this.#headers ??= new Headers());\n    headers.set(name, value);\n    return this;\n  }\n\n  hasHeader(name) {\n    if (!this.#headers) return false;\n    return this.#headers.has(name);\n  }\n\n  writeHead(statusCode, statusMessage, headers) {\n    _writeHead(statusCode, statusMessage, headers, this);\n\n    return this;\n  }\n}\n\nexport class ClientRequest extends OutgoingMessage {\n  #timeout;\n  #res = null;\n  #upgradeOrConnect = false;\n  #parser = null;\n  #maxHeadersCount = null;\n  #reusedSocket = false;\n  #host;\n  #protocol;\n  #method;\n  #port;\n  #useDefaultPort;\n  #joinDuplicateHeaders;\n  #maxHeaderSize;\n  #agent = _globalAgent;\n  #path;\n  #socketPath;\n\n  #body = null;\n  #fetchRequest;\n  #signal = null;\n  [kAbortController] = null;\n  #timeoutTimer = null;\n  #options;\n  #finished;\n\n  get path() {\n    return this.#path;\n  }\n\n  get port() {\n    return this.#port;\n  }\n\n  get method() {\n    return this.#method;\n  }\n\n  get host() {\n    return this.#host;\n  }\n\n  get protocol() {\n    return this.#protocol;\n  }\n\n  _write(chunk, encoding, callback) {\n    var body = this.#body;\n    if (!body) {\n      this.#body = chunk;\n      callback();\n      return;\n    }\n    this.#body = body + chunk;\n    callback();\n  }\n\n  _writev(chunks, callback) {\n    var body = this.#body;\n    if (!body) {\n      this.#body = chunks.join();\n      callback();\n      return;\n    }\n    this.#body = body + chunks.join();\n    callback();\n  }\n\n  _final(callback) {\n    this.#finished = true;\n    this[kAbortController] = new AbortController();\n    this[kAbortController].signal.addEventListener(\"abort\", () => {\n      this[kClearTimeout]();\n    });\n    if (this.#signal?.aborted) {\n      this[kAbortController].abort();\n    }\n\n    var method = this.#method,\n      body = this.#body;\n\n    try {\n      this.#fetchRequest = fetch(\n        `${this.#protocol}//${this.#host}${this.#useDefaultPort ? \"\" : \":\" + this.#port}${this.#path}`,\n        {\n          method,\n          headers: this.getHeaders(),\n          body: body && method !== \"GET\" && method !== \"HEAD\" && method !== \"OPTIONS\" ? body : undefined,\n          redirect: \"manual\",\n          verbose: Boolean(__DEBUG__),\n          signal: this[kAbortController].signal,\n        },\n      )\n        .then(response => {\n          var res = (this.#res = new IncomingMessage(response, {\n            type: \"response\",\n            [kInternalRequest]: this,\n          }));\n          this.emit(\"response\", res);\n        })\n        .catch(err => {\n          if (__DEBUG__) globalReportError(err);\n          this.emit(\"error\", err);\n        })\n        .finally(() => {\n          this.#fetchRequest = null;\n          this[kClearTimeout]();\n        });\n    } catch (err) {\n      if (__DEBUG__) globalReportError(err);\n      this.emit(\"error\", err);\n    } finally {\n      callback();\n    }\n  }\n\n  get aborted() {\n    return this.#signal?.aborted || !!this[kAbortController]?.signal.aborted;\n  }\n\n  abort() {\n    if (this.aborted) return;\n    this[kAbortController].abort();\n    // TODO: Close stream if body streaming\n  }\n\n  constructor(input, options, cb) {\n    super();\n\n    if (typeof input === \"string\") {\n      const urlStr = input;\n      try {\n        var urlObject = new URL(urlStr);\n      } catch (e) {\n        throw new TypeError(`Invalid URL: ${urlStr}`);\n      }\n      input = urlToHttpOptions(urlObject);\n    } else if (input && typeof input === \"object\" && input instanceof URL) {\n      // url.URL instance\n      input = urlToHttpOptions(input);\n    } else {\n      cb = options;\n      options = input;\n      input = null;\n    }\n\n    if (typeof options === \"function\") {\n      cb = options;\n      options = input || kEmptyObject;\n    } else {\n      options = ObjectAssign(input || {}, options);\n    }\n\n    var defaultAgent = options._defaultAgent || Agent.globalAgent;\n\n    let protocol = options.protocol;\n    if (!protocol) {\n      if (options.port === 443) {\n        protocol = \"https:\";\n      } else {\n        protocol = defaultAgent.protocol || \"http:\";\n      }\n      this.#protocol = protocol;\n    }\n\n    switch (this.#agent?.protocol) {\n      case undefined: {\n        break;\n      }\n      case \"http:\": {\n        if (protocol === \"https:\") {\n          defaultAgent = this.#agent = getDefaultHTTPSAgent();\n          break;\n        }\n      }\n      case \"https:\": {\n        if (protocol === \"https\") {\n          defaultAgent = this.#agent = Agent.globalAgent;\n          break;\n        }\n      }\n      default: {\n        break;\n      }\n    }\n\n    if (options.path) {\n      const path = String(options.path);\n      if (RegExpPrototypeExec.call(INVALID_PATH_REGEX, path) !== null) {\n        debug('Path contains unescaped characters: \"%s\"', path);\n        throw new Error(\"Path contains unescaped characters\");\n        // throw new ERR_UNESCAPED_CHARACTERS(\"Request path\");\n      }\n    }\n\n    // Since we don't implement Agent, we don't need this\n    if (protocol !== \"http:\" && protocol !== \"https:\" && protocol) {\n      const expectedProtocol = defaultAgent?.protocol ?? \"http:\";\n      throw new Error(`Protocol mismatch. Expected: ${expectedProtocol}. Got: ${protocol}`);\n      // throw new ERR_INVALID_PROTOCOL(protocol, expectedProtocol);\n    }\n\n    const defaultPort = protocol === \"https:\" ? 443 : 80;\n\n    this.#port = options.port || options.defaultPort || this.#agent?.defaultPort || defaultPort;\n    this.#useDefaultPort = this.#port === defaultPort;\n    const host =\n      (this.#host =\n      options.host =\n        validateHost(options.hostname, \"hostname\") || validateHost(options.host, \"host\") || \"localhost\");\n\n    // const setHost = options.setHost === undefined || Boolean(options.setHost);\n\n    this.#socketPath = options.socketPath;\n\n    if (options.timeout !== undefined) this.setTimeout(options.timeout, null);\n\n    const signal = options.signal;\n    if (signal) {\n      //We still want to control abort function and timeout so signal call our AbortController\n      signal.addEventListener(\"abort\", () => {\n        this[kAbortController]?.abort();\n      });\n      this.#signal = signal;\n    }\n    let method = options.method;\n    const methodIsString = typeof method === \"string\";\n    if (method !== null && method !== undefined && !methodIsString) {\n      // throw new ERR_INVALID_ARG_TYPE(\"options.method\", \"string\", method);\n      throw new Error(\"ERR_INVALID_ARG_TYPE: options.method\");\n    }\n\n    if (methodIsString && method) {\n      if (!checkIsHttpToken(method)) {\n        // throw new ERR_INVALID_HTTP_TOKEN(\"Method\", method);\n        throw new Error(\"ERR_INVALID_HTTP_TOKEN: Method\");\n      }\n      method = this.#method = StringPrototypeToUpperCase.call(method);\n    } else {\n      method = this.#method = \"GET\";\n    }\n\n    const _maxHeaderSize = options.maxHeaderSize;\n    // TODO: Validators\n    // if (maxHeaderSize !== undefined)\n    //   validateInteger(maxHeaderSize, \"maxHeaderSize\", 0);\n    this.#maxHeaderSize = _maxHeaderSize;\n\n    // const insecureHTTPParser = options.insecureHTTPParser;\n    // if (insecureHTTPParser !== undefined) {\n    //   validateBoolean(insecureHTTPParser, 'options.insecureHTTPParser');\n    // }\n\n    // this.insecureHTTPParser = insecureHTTPParser;\n    var _joinDuplicateHeaders = options.joinDuplicateHeaders;\n    if (_joinDuplicateHeaders !== undefined) {\n      // TODO: Validators\n      // validateBoolean(\n      //   options.joinDuplicateHeaders,\n      //   \"options.joinDuplicateHeaders\",\n      // );\n    }\n\n    this.#joinDuplicateHeaders = _joinDuplicateHeaders;\n\n    this.#path = options.path || \"/\";\n    if (cb) {\n      this.once(\"response\", cb);\n    }\n\n    __DEBUG__ &&\n      debug(`new ClientRequest: ${this.#method} ${this.#protocol}//${this.#host}:${this.#port}${this.#path}`);\n\n    // if (\n    //   method === \"GET\" ||\n    //   method === \"HEAD\" ||\n    //   method === \"DELETE\" ||\n    //   method === \"OPTIONS\" ||\n    //   method === \"TRACE\" ||\n    //   method === \"CONNECT\"\n    // ) {\n    //   this.useChunkedEncodingByDefault = false;\n    // } else {\n    //   this.useChunkedEncodingByDefault = true;\n    // }\n\n    this.#finished = false;\n    this.#res = null;\n    this.#upgradeOrConnect = false;\n    this.#parser = null;\n    this.#maxHeadersCount = null;\n    this.#reusedSocket = false;\n    this.#host = host;\n    this.#protocol = protocol;\n    this.#timeoutTimer = null;\n    const headersArray = ArrayIsArray(headers);\n    if (!headersArray) {\n      var headers = options.headers;\n      if (headers) {\n        for (let key in headers) {\n          this.setHeader(key, headers[key]);\n        }\n      }\n\n      // if (host && !this.getHeader(\"host\") && setHost) {\n      //   let hostHeader = host;\n\n      //   // For the Host header, ensure that IPv6 addresses are enclosed\n      //   // in square brackets, as defined by URI formatting\n      //   // https://tools.ietf.org/html/rfc3986#section-3.2.2\n      //   const posColon = StringPrototypeIndexOf.call(hostHeader, \":\");\n      //   if (\n      //     posColon !== -1 &&\n      //     StringPrototypeIncludes(hostHeader, \":\", posColon + 1) &&\n      //     StringPrototypeCharCodeAt(hostHeader, 0) !== 91 /* '[' */\n      //   ) {\n      //     hostHeader = `[${hostHeader}]`;\n      //   }\n\n      //   if (port && +port !== defaultPort) {\n      //     hostHeader += \":\" + port;\n      //   }\n      //   this.setHeader(\"Host\", hostHeader);\n      // }\n\n      var auth = options.auth;\n      if (auth && !this.getHeader(\"Authorization\")) {\n        this.setHeader(\"Authorization\", \"Basic \" + Buffer.from(auth).toString(\"base64\"));\n      }\n\n      //   if (this.getHeader(\"expect\")) {\n      //     if (this._header) {\n      //       throw new ERR_HTTP_HEADERS_SENT(\"render\");\n      //     }\n\n      //     this._storeHeader(\n      //       this.method + \" \" + this.path + \" HTTP/1.1\\r\\n\",\n      //       this[kOutHeaders],\n      //     );\n      //   }\n      // } else {\n      //   this._storeHeader(\n      //     this.method + \" \" + this.path + \" HTTP/1.1\\r\\n\",\n      //     options.headers,\n      //   );\n    }\n\n    // this[kUniqueHeaders] = parseUniqueHeadersOption(options.uniqueHeaders);\n\n    var optsWithoutSignal = options;\n    if (optsWithoutSignal.signal) {\n      optsWithoutSignal = ObjectAssign({}, options);\n      delete optsWithoutSignal.signal;\n    }\n    this.#options = optsWithoutSignal;\n\n    var timeout = options.timeout;\n    if (timeout) {\n      this.setTimeout(timeout);\n    }\n  }\n\n  setSocketKeepAlive(enable = true, initialDelay = 0) {\n    __DEBUG__ && debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: ClientRequest.setSocketKeepAlive is a no-op\");\n  }\n\n  setNoDelay(noDelay = true) {\n    __DEBUG__ && debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: ClientRequest.setNoDelay is a no-op\");\n  }\n  [kClearTimeout]() {\n    if (this.#timeoutTimer) {\n      clearTimeout(this.#timeoutTimer);\n      this.#timeoutTimer = null;\n    }\n  }\n\n  setTimeout(msecs, callback) {\n    if (this.#timeoutTimer) return this;\n    if (callback) {\n      this.on(\"timeout\", callback);\n    }\n\n    this.#timeoutTimer = setTimeout(async () => {\n      this.#timeoutTimer = null;\n      this[kAbortController]?.abort();\n      this.emit(\"timeout\");\n    }, msecs);\n\n    return this;\n  }\n}\n\nfunction urlToHttpOptions(url) {\n  var { protocol, hostname, hash, search, pathname, href, port, username, password } = url;\n  return {\n    protocol,\n    hostname:\n      typeof hostname === \"string\" && StringPrototypeStartsWith.call(hostname, \"[\")\n        ? StringPrototypeSlice.call(hostname, 1, -1)\n        : hostname,\n    hash,\n    search,\n    pathname,\n    path: `${pathname || \"\"}${search || \"\"}`,\n    href,\n    port: port ? Number(port) : protocol === \"https:\" ? 443 : protocol === \"http:\" ? 80 : undefined,\n    auth: username || password ? `${decodeURIComponent(username)}:${decodeURIComponent(password)}` : undefined,\n  };\n}\n\nfunction validateHost(host, name) {\n  if (host !== null && host !== undefined && typeof host !== \"string\") {\n    // throw new ERR_INVALID_ARG_TYPE(\n    //   `options.${name}`,\n    //   [\"string\", \"undefined\", \"null\"],\n    //   host,\n    // );\n    throw new Error(\"Invalid arg type in options\");\n  }\n  return host;\n}\n\nconst tokenRegExp = /^[\\^_`a-zA-Z\\-0-9!#$%&'*+.|~]+$/;\n/**\n * Verifies that the given val is a valid HTTP token\n * per the rules defined in RFC 7230\n * See https://tools.ietf.org/html/rfc7230#section-3.2.6\n */\nfunction checkIsHttpToken(val) {\n  return RegExpPrototypeExec.call(tokenRegExp, val) !== null;\n}\n\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nexport const METHODS = [\n  \"ACL\",\n  \"BIND\",\n  \"CHECKOUT\",\n  \"CONNECT\",\n  \"COPY\",\n  \"DELETE\",\n  \"GET\",\n  \"HEAD\",\n  \"LINK\",\n  \"LOCK\",\n  \"M-SEARCH\",\n  \"MERGE\",\n  \"MKACTIVITY\",\n  \"MKCALENDAR\",\n  \"MKCOL\",\n  \"MOVE\",\n  \"NOTIFY\",\n  \"OPTIONS\",\n  \"PATCH\",\n  \"POST\",\n  \"PROPFIND\",\n  \"PROPPATCH\",\n  \"PURGE\",\n  \"PUT\",\n  \"REBIND\",\n  \"REPORT\",\n  \"SEARCH\",\n  \"SOURCE\",\n  \"SUBSCRIBE\",\n  \"TRACE\",\n  \"UNBIND\",\n  \"UNLINK\",\n  \"UNLOCK\",\n  \"UNSUBSCRIBE\",\n];\n\nexport const STATUS_CODES = {\n  100: \"Continue\",\n  101: \"Switching Protocols\",\n  102: \"Processing\",\n  103: \"Early Hints\",\n  200: \"OK\",\n  201: \"Created\",\n  202: \"Accepted\",\n  203: \"Non-Authoritative Information\",\n  204: \"No Content\",\n  205: \"Reset Content\",\n  206: \"Partial Content\",\n  207: \"Multi-Status\",\n  208: \"Already Reported\",\n  226: \"IM Used\",\n  300: \"Multiple Choices\",\n  301: \"Moved Permanently\",\n  302: \"Found\",\n  303: \"See Other\",\n  304: \"Not Modified\",\n  305: \"Use Proxy\",\n  307: \"Temporary Redirect\",\n  308: \"Permanent Redirect\",\n  400: \"Bad Request\",\n  401: \"Unauthorized\",\n  402: \"Payment Required\",\n  403: \"Forbidden\",\n  404: \"Not Found\",\n  405: \"Method Not Allowed\",\n  406: \"Not Acceptable\",\n  407: \"Proxy Authentication Required\",\n  408: \"Request Timeout\",\n  409: \"Conflict\",\n  410: \"Gone\",\n  411: \"Length Required\",\n  412: \"Precondition Failed\",\n  413: \"Payload Too Large\",\n  414: \"URI Too Long\",\n  415: \"Unsupported Media Type\",\n  416: \"Range Not Satisfiable\",\n  417: \"Expectation Failed\",\n  418: \"I'm a Teapot\",\n  421: \"Misdirected Request\",\n  422: \"Unprocessable Entity\",\n  423: \"Locked\",\n  424: \"Failed Dependency\",\n  425: \"Too Early\",\n  426: \"Upgrade Required\",\n  428: \"Precondition Required\",\n  429: \"Too Many Requests\",\n  431: \"Request Header Fields Too Large\",\n  451: \"Unavailable For Legal Reasons\",\n  500: \"Internal Server Error\",\n  501: \"Not Implemented\",\n  502: \"Bad Gateway\",\n  503: \"Service Unavailable\",\n  504: \"Gateway Timeout\",\n  505: \"HTTP Version Not Supported\",\n  506: \"Variant Also Negotiates\",\n  507: \"Insufficient Storage\",\n  508: \"Loop Detected\",\n  509: \"Bandwidth Limit Exceeded\",\n  510: \"Not Extended\",\n  511: \"Network Authentication Required\",\n};\n\nfunction _normalizeArgs(args) {\n  let arr;\n\n  if (args.length === 0) {\n    arr = [{}, null];\n    // arr[normalizedArgsSymbol] = true;\n    return arr;\n  }\n\n  const arg0 = args[0];\n  let options = {};\n  if (typeof arg0 === \"object\" && arg0 !== null) {\n    // (options[...][, cb])\n    options = arg0;\n    // } else if (isPipeName(arg0)) {\n    // (path[...][, cb])\n    // options.path = arg0;\n  } else {\n    // ([port][, host][...][, cb])\n    options.port = arg0;\n    if (args.length > 1 && typeof args[1] === \"string\") {\n      options.host = args[1];\n    }\n  }\n\n  const cb = args[args.length - 1];\n  if (typeof cb !== \"function\") arr = [options, null];\n  else arr = [options, cb];\n\n  // arr[normalizedArgsSymbol] = true;\n  return arr;\n}\n\nfunction _writeHead(statusCode, reason, obj, response) {\n  statusCode |= 0;\n  if (statusCode < 100 || statusCode > 999) {\n    throw new Error(\"status code must be between 100 and 999\");\n  }\n\n  if (typeof reason === \"string\") {\n    // writeHead(statusCode, reasonPhrase[, headers])\n    response.statusMessage = reason;\n  } else {\n    // writeHead(statusCode[, headers])\n    if (!response.statusMessage) response.statusMessage = STATUS_CODES[statusCode] || \"unknown\";\n    obj = reason;\n  }\n  response.statusCode = statusCode;\n\n  {\n    // Slow-case: when progressive API and header fields are passed.\n    let k;\n    if (Array.isArray(obj)) {\n      if (obj.length % 2 !== 0) {\n        throw new Error(\"raw headers must have an even number of elements\");\n      }\n\n      for (let n = 0; n < obj.length; n += 2) {\n        k = obj[n + 0];\n        if (k) response.setHeader(k, obj[n + 1]);\n      }\n    } else if (obj) {\n      const keys = Object.keys(obj);\n      // Retain for(;;) loop for performance reasons\n      // Refs: https://github.com/nodejs/node/pull/30958\n      for (let i = 0; i < keys.length; i++) {\n        k = keys[i];\n        if (k) response.setHeader(k, obj[k]);\n      }\n    }\n  }\n}\n\n/**\n * Makes an HTTP request.\n * @param {string | URL} url\n * @param {HTTPRequestOptions} [options]\n * @param {Function} [cb]\n * @returns {ClientRequest}\n */\nexport function request(url, options, cb) {\n  return new ClientRequest(url, options, cb);\n}\n\n/**\n * Makes a `GET` HTTP request.\n * @param {string | URL} url\n * @param {HTTPRequestOptions} [options]\n * @param {Function} [cb]\n * @returns {ClientRequest}\n */\nexport function get(url, options, cb) {\n  const req = request(url, options, cb);\n  req.end();\n  return req;\n}\n\nvar defaultObject = {\n  Agent,\n  Server,\n  METHODS,\n  STATUS_CODES,\n  createServer,\n  ServerResponse,\n  IncomingMessage,\n  request,\n  get,\n  maxHeaderSize: 16384,\n  // validateHeaderName,\n  // validateHeaderValue,\n  setMaxIdleHTTPParsers(max) {\n    debug(`${NODE_HTTP_WARNING}\\n`, \"setMaxIdleHTTPParsers() is a no-op\");\n  },\n  get globalAgent() {\n    return (_globalAgent ??= new Agent());\n  },\n  set globalAgent(agent) {},\n  [Symbol.for(\"CommonJS\")]: 0,\n};\n\nexport default defaultObject;\n",
  "// Hardcoded module \"node:http\"\nconst { EventEmitter } = import.meta.require(\"node:events\");\nconst { isIPv6 } = import.meta.require(\"node:net\");\nconst { Readable, Writable, Duplex } = import.meta.require(\"node:stream\");\nconst { URL } = import.meta.require(\"node:url\");\nconst { newArrayWithSize, String, Object, Array } = import.meta.primordials;\nconst { isTypedArray } = import.meta.require(\"util/types\");\n\nconst globalReportError = globalThis.reportError;\nconst setTimeout = globalThis.setTimeout;\nconst fetch = Bun.fetch;\nconst nop = () => {};\n\nconst __DEBUG__ = process.env.__DEBUG__;\nconst debug = __DEBUG__ ? (...args) => console.log(\"node:http\", ...args) : nop;\n\nconst kEmptyObject = Object.freeze(Object.create(null));\nconst kOutHeaders = Symbol.for(\"kOutHeaders\");\nconst kEndCalled = Symbol.for(\"kEndCalled\");\nconst kAbortController = Symbol.for(\"kAbortController\");\nconst kClearTimeout = Symbol(\"kClearTimeout\");\n\nconst kCorked = Symbol.for(\"kCorked\");\nconst searchParamsSymbol = Symbol.for(\"query\"); // This is the symbol used in Node\n\n// Primordials\nconst StringPrototypeSlice = String.prototype.slice;\nconst StringPrototypeStartsWith = String.prototype.startsWith;\nconst StringPrototypeToUpperCase = String.prototype.toUpperCase;\nconst StringPrototypeIncludes = String.prototype.includes;\nconst StringPrototypeCharCodeAt = String.prototype.charCodeAt;\nconst StringPrototypeIndexOf = String.prototype.indexOf;\nconst ArrayIsArray = Array.isArray;\nconst RegExpPrototypeExec = RegExp.prototype.exec;\nconst ObjectAssign = Object.assign;\nconst ObjectPrototypeHasOwnProperty = Object.prototype.hasOwnProperty;\n\nconst INVALID_PATH_REGEX = /[^\\u0021-\\u00ff]/;\nconst NODE_HTTP_WARNING =\n  \"WARN: Agent is mostly unused in Bun's implementation of http. If you see strange behavior, this is probably the cause.\";\n\nvar _globalAgent;\nvar _defaultHTTPSAgent;\nvar kInternalRequest = Symbol(\"kInternalRequest\");\nvar kInternalSocketData = Symbol.for(\"::bunternal::\");\n\nconst kEmptyBuffer = Buffer.alloc(0);\n\nfunction isValidTLSArray(obj) {\n  if (typeof obj === \"string\" || isTypedArray(obj) || obj instanceof ArrayBuffer || obj instanceof Blob) return true;\n  if (Array.isArray(obj)) {\n    for (var i = 0; i < obj.length; i++) {\n      if (typeof obj !== \"string\" && !isTypedArray(obj) && !(obj instanceof ArrayBuffer) && !(obj instanceof Blob))\n        return false;\n    }\n    return true;\n  }\n}\n\nfunction getHeader(headers, name) {\n  if (!headers) return;\n  const result = headers.get(name);\n  return result == null ? undefined : result;\n}\n\nvar FakeSocket = class Socket extends Duplex {\n  bytesRead = 0;\n  bytesWritten = 0;\n  connecting = false;\n  remoteAddress = null;\n  localAddress = \"127.0.0.1\";\n  remotePort;\n  timeout = 0;\n\n  isServer = false;\n\n  address() {\n    return {\n      address: this.localAddress,\n      family: this.localFamily,\n      port: this.localPort,\n    };\n  }\n\n  get bufferSize() {\n    return this.writableLength;\n  }\n\n  connect(port, host, connectListener) {\n    return this;\n  }\n\n  _destroy(err, callback) {}\n\n  _final(callback) {}\n\n  get localAddress() {\n    return \"127.0.0.1\";\n  }\n\n  get localFamily() {\n    return \"IPv4\";\n  }\n\n  get localPort() {\n    return 80;\n  }\n\n  get pending() {\n    return this.connecting;\n  }\n\n  _read(size) {}\n\n  get readyState() {\n    if (this.connecting) return \"opening\";\n    if (this.readable) {\n      return this.writable ? \"open\" : \"readOnly\";\n    } else {\n      return this.writable ? \"writeOnly\" : \"closed\";\n    }\n  }\n\n  ref() {}\n\n  get remoteFamily() {\n    return \"IPv4\";\n  }\n\n  resetAndDestroy() {}\n\n  setKeepAlive(enable = false, initialDelay = 0) {}\n\n  setNoDelay(noDelay = true) {\n    return this;\n  }\n\n  setTimeout(timeout, callback) {\n    return this;\n  }\n\n  unref() {}\n\n  _write(chunk, encoding, callback) {}\n};\n\nexport function createServer(options, callback) {\n  return new Server(options, callback);\n}\n\nexport class Agent extends EventEmitter {\n  #defaultPort = 80;\n  #protocol = \"http:\";\n  #options;\n  #requests;\n  #sockets;\n  #freeSockets;\n\n  #keepAliveMsecs;\n  #keepAlive;\n  #maxSockets;\n  #maxFreeSockets;\n  #scheduling;\n  #maxTotalSockets;\n  #totalSocketCount;\n\n  #fakeSocket;\n\n  static get globalAgent() {\n    return (_globalAgent ??= new Agent());\n  }\n\n  static get defaultMaxSockets() {\n    return Infinity;\n  }\n\n  constructor(options = kEmptyObject) {\n    super();\n    this.#options = options = { ...options, path: null };\n    if (options.noDelay === undefined) options.noDelay = true;\n\n    // Don't confuse net and make it think that we're connecting to a pipe\n    this.#requests = kEmptyObject;\n    this.#sockets = kEmptyObject;\n    this.#freeSockets = kEmptyObject;\n\n    this.#keepAliveMsecs = options.keepAliveMsecs || 1000;\n    this.#keepAlive = options.keepAlive || false;\n    this.#maxSockets = options.maxSockets || Agent.defaultMaxSockets;\n    this.#maxFreeSockets = options.maxFreeSockets || 256;\n    this.#scheduling = options.scheduling || \"lifo\";\n    this.#maxTotalSockets = options.maxTotalSockets;\n    this.#totalSocketCount = 0;\n    this.#defaultPort = options.defaultPort || 80;\n    this.#protocol = options.protocol || \"http:\";\n  }\n\n  get defaultPort() {\n    return this.#defaultPort;\n  }\n\n  get protocol() {\n    return this.#protocol;\n  }\n\n  get requests() {\n    return this.#requests;\n  }\n\n  get sockets() {\n    return this.#sockets;\n  }\n\n  get freeSockets() {\n    return this.#freeSockets;\n  }\n\n  get options() {\n    return this.#options;\n  }\n\n  get keepAliveMsecs() {\n    return this.#keepAliveMsecs;\n  }\n\n  get keepAlive() {\n    return this.#keepAlive;\n  }\n\n  get maxSockets() {\n    return this.#maxSockets;\n  }\n\n  get maxFreeSockets() {\n    return this.#maxFreeSockets;\n  }\n\n  get scheduling() {\n    return this.#scheduling;\n  }\n\n  get maxTotalSockets() {\n    return this.#maxTotalSockets;\n  }\n\n  get totalSocketCount() {\n    return this.#totalSocketCount;\n  }\n\n  createConnection() {\n    debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: Agent.createConnection is a no-op, returns fake socket\");\n    return (this.#fakeSocket ??= new FakeSocket());\n  }\n\n  getName(options = kEmptyObject) {\n    let name = `http:${options.host || \"localhost\"}:`;\n    if (options.port) name += options.port;\n    name += \":\";\n    if (options.localAddress) name += options.localAddress;\n    // Pacify parallel/test-http-agent-getname by only appending\n    // the ':' when options.family is set.\n    if (options.family === 4 || options.family === 6) name += `:${options.family}`;\n    if (options.socketPath) name += `:${options.socketPath}`;\n    return name;\n  }\n\n  addRequest() {\n    debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: Agent.addRequest is a no-op\");\n  }\n\n  createSocket(req, options, cb) {\n    debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: Agent.createSocket returns fake socket\");\n    cb(null, (this.#fakeSocket ??= new FakeSocket()));\n  }\n\n  removeSocket() {\n    debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: Agent.removeSocket is a no-op\");\n  }\n\n  keepSocketAlive() {\n    debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: Agent.keepSocketAlive is a no-op\");\n\n    return true;\n  }\n\n  reuseSocket() {\n    debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: Agent.reuseSocket is a no-op\");\n  }\n\n  destroy() {\n    debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: Agent.destroy is a no-op\");\n  }\n}\nfunction emitListeningNextTick(self, onListen, err, hostname, port) {\n  if (typeof onListen === \"function\") {\n    try {\n      onListen(err, hostname, port);\n    } catch (err) {\n      self.emit(\"error\", err);\n    }\n  }\n\n  self.listening = !err;\n\n  if (err) {\n    self.emit(\"error\", err);\n  } else {\n    self.emit(\"listening\", hostname, port);\n  }\n}\n\nexport class Server extends EventEmitter {\n  #server;\n  #options;\n  #tls;\n  #is_tls = false;\n  listening = false;\n\n  constructor(options, callback) {\n    super();\n\n    if (typeof options === \"function\") {\n      callback = options;\n      options = {};\n    } else if (options == null || typeof options === \"object\") {\n      options = { ...options };\n      this.#tls = null;\n      let key = options.key;\n      if (key) {\n        if (!isValidTLSArray(key)) {\n          throw new TypeError(\n            \"key argument must be an string, Buffer, TypedArray, BunFile or an array containing string, Buffer, TypedArray or BunFile\",\n          );\n        }\n        this.#is_tls = true;\n      }\n      let cert = options.cert;\n      if (cert) {\n        if (!isValidTLSArray(cert)) {\n          throw new TypeError(\n            \"cert argument must be an string, Buffer, TypedArray, BunFile or an array containing string, Buffer, TypedArray or BunFile\",\n          );\n        }\n        this.#is_tls = true;\n      }\n\n      let ca = options.ca;\n      if (ca) {\n        if (!isValidTLSArray(ca)) {\n          throw new TypeError(\n            \"ca argument must be an string, Buffer, TypedArray, BunFile or an array containing string, Buffer, TypedArray or BunFile\",\n          );\n        }\n        this.#is_tls = true;\n      }\n      let passphrase = options.passphrase;\n      if (passphrase && typeof passphrase !== \"string\") {\n        throw new TypeError(\"passphrase argument must be an string\");\n      }\n\n      let serverName = options.servername;\n      if (serverName && typeof serverName !== \"string\") {\n        throw new TypeError(\"servername argument must be an string\");\n      }\n\n      let secureOptions = options.secureOptions || 0;\n      if (secureOptions && typeof secureOptions !== \"number\") {\n        throw new TypeError(\"secureOptions argument must be an number\");\n      }\n\n      if (this.#is_tls) {\n        this.#tls = {\n          serverName,\n          key: key,\n          cert: cert,\n          ca: ca,\n          passphrase: passphrase,\n          secureOptions: secureOptions,\n        };\n      } else {\n        this.#tls = null;\n      }\n    } else {\n      throw new Error(\"bun-http-polyfill: invalid arguments\");\n    }\n\n    this.#options = options;\n\n    if (callback) this.on(\"request\", callback);\n  }\n\n  closeAllConnections() {\n    const server = this.#server;\n    if (!server) {\n      return;\n    }\n    this.#server = undefined;\n    server.stop(true);\n    this.emit(\"close\");\n  }\n\n  closeIdleConnections() {\n    // not actually implemented\n  }\n\n  close(optionalCallback) {\n    const server = this.#server;\n    if (!server) {\n      if (typeof optionalCallback === \"function\")\n        process.nextTick(optionalCallback, new Error(\"Server is not running\"));\n      return;\n    }\n    this.#server = undefined;\n    if (typeof optionalCallback === \"function\") this.once(\"close\", optionalCallback);\n    server.stop();\n    this.emit(\"close\");\n  }\n\n  address() {\n    if (!this.#server) return null;\n\n    const address = this.#server.hostname;\n    return {\n      address,\n      family: isIPv6(address) ? \"IPv6\" : \"IPv4\",\n      port: this.#server.port,\n    };\n  }\n\n  listen(port, host, backlog, onListen) {\n    const server = this;\n    if (typeof host === \"function\") {\n      onListen = host;\n      host = undefined;\n    }\n\n    if (typeof port === \"function\") {\n      onListen = port;\n    } else if (typeof port === \"object\") {\n      port?.signal?.addEventListener(\"abort\", () => {\n        this.close();\n      });\n\n      host = port?.host;\n      port = port?.port;\n\n      if (typeof port?.callback === \"function\") onListen = port?.callback;\n    }\n\n    if (typeof backlog === \"function\") {\n      onListen = backlog;\n    }\n\n    const ResponseClass = this.#options.ServerResponse || ServerResponse;\n    const RequestClass = this.#options.IncomingMessage || IncomingMessage;\n\n    try {\n      const tls = this.#tls;\n      if (tls) {\n        this.serverName = tls.serverName || host || \"localhost\";\n      }\n      this.#server = Bun.serve({\n        tls,\n        port,\n        hostname: host,\n        // Bindings to be used for WS Server\n        websocket: {\n          open(ws) {\n            ws.data.open(ws);\n          },\n          message(ws, message) {\n            ws.data.message(ws, message);\n          },\n          close(ws, code, reason) {\n            ws.data.close(ws, code, reason);\n          },\n          drain(ws) {\n            ws.data.drain(ws);\n          },\n        },\n        fetch(req, _server) {\n          var pendingResponse;\n          var pendingError;\n          var rejectFunction, resolveFunction;\n          var reject = err => {\n            if (pendingError) return;\n            pendingError = err;\n            if (rejectFunction) rejectFunction(err);\n          };\n\n          var reply = function (resp) {\n            if (pendingResponse) return;\n            pendingResponse = resp;\n            if (resolveFunction) resolveFunction(resp);\n          };\n\n          const http_req = new RequestClass(req);\n          const http_res = new ResponseClass({ reply, req: http_req });\n\n          http_req.once(\"error\", err => reject(err));\n          http_res.once(\"error\", err => reject(err));\n\n          const upgrade = req.headers.get(\"upgrade\");\n          if (upgrade) {\n            const socket = new FakeSocket();\n            socket[kInternalSocketData] = [_server, http_res, req];\n            server.emit(\"upgrade\", http_req, socket, kEmptyBuffer);\n          } else {\n            server.emit(\"request\", http_req, http_res);\n          }\n\n          if (pendingError) {\n            throw pendingError;\n          }\n\n          if (pendingResponse) {\n            return pendingResponse;\n          }\n\n          return new Promise((resolve, reject) => {\n            resolveFunction = resolve;\n            rejectFunction = reject;\n          });\n        },\n      });\n      setTimeout(emitListeningNextTick, 1, this, onListen, null, this.#server.hostname, this.#server.port);\n    } catch (err) {\n      setTimeout(emitListeningNextTick, 1, this, onListen, err);\n    }\n\n    return this;\n  }\n  setTimeout(msecs, callback) {}\n}\n\nfunction assignHeaders(object, req) {\n  var headers = req.headers.toJSON();\n  const rawHeaders = newArrayWithSize(req.headers.count * 2);\n  var i = 0;\n  for (const key in headers) {\n    rawHeaders[i++] = key;\n    rawHeaders[i++] = headers[key];\n  }\n  object.headers = headers;\n  object.rawHeaders = rawHeaders;\n}\nfunction destroyBodyStreamNT(bodyStream) {\n  bodyStream.destroy();\n}\n\nvar defaultIncomingOpts = { type: \"request\" };\n\nfunction getDefaultHTTPSAgent() {\n  return (_defaultHTTPSAgent ??= new Agent({ defaultPort: 443, protocol: \"https:\" }));\n}\n\nexport class IncomingMessage extends Readable {\n  constructor(req, defaultIncomingOpts) {\n    const method = req.method;\n\n    super();\n\n    const url = new URL(req.url);\n\n    var { type = \"request\", [kInternalRequest]: nodeReq } = defaultIncomingOpts || {};\n\n    this.#noBody =\n      type === \"request\" // TODO: Add logic for checking for body on response\n        ? \"GET\" === method ||\n          \"HEAD\" === method ||\n          \"TRACE\" === method ||\n          \"CONNECT\" === method ||\n          \"OPTIONS\" === method ||\n          (parseInt(req.headers.get(\"Content-Length\") || \"\") || 0) === 0\n        : false;\n\n    this.#req = req;\n    this.method = method;\n    this.#type = type;\n    this.complete = !!this.#noBody;\n\n    this.#bodyStream = null;\n    const socket = new FakeSocket();\n    socket.remoteAddress = url.hostname;\n    socket.remotePort = url.port;\n    this.#fakeSocket = socket;\n\n    this.url = url.pathname + url.search;\n    this.#nodeReq = nodeReq;\n    assignHeaders(this, req);\n  }\n\n  headers;\n  rawHeaders;\n  _consuming = false;\n  _dumped = false;\n  #bodyStream = null;\n  #fakeSocket = undefined;\n  #noBody = false;\n  #aborted = false;\n  #req;\n  url;\n  #type;\n  #nodeReq;\n\n  get req() {\n    return this.#nodeReq;\n  }\n\n  _construct(callback) {\n    // TODO: streaming\n    if (this.#type === \"response\" || this.#noBody) {\n      callback();\n      return;\n    }\n\n    const contentLength = this.#req.headers.get(\"content-length\");\n    const length = contentLength ? parseInt(contentLength, 10) : 0;\n    if (length === 0) {\n      this.#noBody = true;\n      callback();\n      return;\n    }\n\n    callback();\n  }\n\n  #closeBodyStream() {\n    debug(\"closeBodyStream()\");\n    var bodyStream = this.#bodyStream;\n    if (bodyStream == null) return;\n    this.complete = true;\n    this.#bodyStream = undefined;\n    this.push(null);\n    // process.nextTick(destroyBodyStreamNT, bodyStream);\n  }\n\n  _read(size) {\n    if (this.#noBody) {\n      this.push(null);\n      this.complete = true;\n    } else if (this.#bodyStream == null) {\n      const contentLength = this.#req.headers.get(\"content-length\");\n      let remaining = contentLength ? parseInt(contentLength, 10) : 0;\n      this.#bodyStream = Readable.fromWeb(this.#req.body, {\n        highWaterMark: Number.isFinite(remaining) ? Math.min(remaining, 16384) : 16384,\n      });\n\n      const isBodySizeKnown = remaining > 0 && Number.isSafeInteger(remaining);\n\n      if (isBodySizeKnown) {\n        this.#bodyStream.on(\"data\", chunk => {\n          debug(\"body size known\", remaining);\n          this.push(chunk);\n          // when we are streaming a known body size, automatically close the stream when we have read enough\n          remaining -= chunk?.byteLength ?? 0;\n          if (remaining <= 0) {\n            this.#closeBodyStream();\n          }\n        });\n      } else {\n        this.#bodyStream.on(\"data\", chunk => {\n          this.push(chunk);\n        });\n      }\n\n      // this can be closed by the time we get here if enough data was synchronously available\n      this.#bodyStream &&\n        this.#bodyStream.on(\"end\", () => {\n          this.#closeBodyStream();\n        });\n    } else {\n      // this.#bodyStream.read(size);\n    }\n  }\n\n  get aborted() {\n    return this.#aborted;\n  }\n\n  abort() {\n    if (this.#aborted) return;\n    this.#aborted = true;\n\n    this.#closeBodyStream();\n  }\n\n  get connection() {\n    return this.#fakeSocket;\n  }\n\n  get statusCode() {\n    return this.#req.status;\n  }\n\n  get statusMessage() {\n    return STATUS_CODES[this.#req.status];\n  }\n\n  get httpVersion() {\n    return \"1.1\";\n  }\n\n  get rawTrailers() {\n    return [];\n  }\n\n  get httpVersionMajor() {\n    return 1;\n  }\n\n  get httpVersionMinor() {\n    return 1;\n  }\n\n  get trailers() {\n    return kEmptyObject;\n  }\n\n  get socket() {\n    return (this.#fakeSocket ??= new FakeSocket());\n  }\n\n  set socket(val) {\n    this.#fakeSocket = val;\n  }\n\n  setTimeout(msecs, callback) {\n    throw new Error(\"not implemented\");\n  }\n}\n\nfunction emitErrorNt(msg, err, callback) {\n  callback(err);\n  if (typeof msg.emit === \"function\" && !msg._closed) {\n    msg.emit(\"error\", err);\n  }\n}\n\nfunction onError(self, err, cb) {\n  process.nextTick(() => emitErrorNt(self, err, cb));\n}\n\nfunction write_(msg, chunk, encoding, callback, fromEnd) {\n  if (typeof callback !== \"function\") callback = nop;\n\n  let len;\n  if (chunk === null) {\n    // throw new ERR_STREAM_NULL_VALUES();\n    throw new Error(\"ERR_STREAM_NULL_VALUES\");\n  } else if (typeof chunk === \"string\") {\n    len = Buffer.byteLength(chunk, encoding);\n  } else {\n    throw new Error(\"Invalid arg type for chunk\");\n    // throw new ERR_INVALID_ARG_TYPE(\n    //   \"chunk\",\n    //   [\"string\", \"Buffer\", \"Uint8Array\"],\n    //   chunk,\n    // );\n  }\n\n  let err;\n  if (msg.finished) {\n    // err = new ERR_STREAM_WRITE_AFTER_END();\n    err = new Error(\"ERR_STREAM_WRITE_AFTER_END\");\n  } else if (msg.destroyed) {\n    // err = new ERR_STREAM_DESTROYED(\"write\");\n    err = new Error(\"ERR_STREAM_DESTROYED\");\n  }\n\n  if (err) {\n    if (!msg.destroyed) {\n      onError(msg, err, callback);\n    } else {\n      process.nextTick(callback, err);\n    }\n    return false;\n  }\n\n  if (!msg._header) {\n    if (fromEnd) {\n      msg._contentLength = len;\n    }\n    // msg._implicitHeader();\n  }\n\n  if (!msg._hasBody) {\n    debug(\"This type of response MUST NOT have a body. \" + \"Ignoring write() calls.\");\n    process.nextTick(callback);\n    return true;\n  }\n\n  // if (!fromEnd && msg.socket && !msg.socket.writableCorked) {\n  //   msg.socket.cork();\n  //   process.nextTick(connectionCorkNT, msg.socket);\n  // }\n\n  return true;\n}\n\nexport class OutgoingMessage extends Writable {\n  #headers;\n  headersSent = false;\n  sendDate = true;\n  req;\n\n  #finished = false;\n  [kEndCalled] = false;\n\n  #fakeSocket;\n  #timeoutTimer = null;\n  [kAbortController] = null;\n\n  // For compat with IncomingRequest\n  get headers() {\n    if (!this.#headers) return kEmptyObject;\n    return this.#headers.toJSON();\n  }\n\n  get shouldKeepAlive() {\n    return true;\n  }\n\n  get chunkedEncoding() {\n    return false;\n  }\n\n  set chunkedEncoding(value) {\n    // throw new Error('not implemented');\n  }\n\n  set shouldKeepAlive(value) {\n    // throw new Error('not implemented');\n  }\n\n  get useChunkedEncodingByDefault() {\n    return true;\n  }\n\n  set useChunkedEncodingByDefault(value) {\n    // throw new Error('not implemented');\n  }\n\n  get socket() {\n    return (this.#fakeSocket ??= new FakeSocket());\n  }\n\n  set socket(val) {\n    this.#fakeSocket = val;\n  }\n\n  get connection() {\n    return this.socket;\n  }\n\n  get finished() {\n    return this.#finished;\n  }\n\n  appendHeader(name, value) {\n    var headers = (this.#headers ??= new Headers());\n    headers.append(name, value);\n  }\n\n  flushHeaders() {}\n\n  getHeader(name) {\n    return getHeader(this.#headers, name);\n  }\n\n  getHeaders() {\n    if (!this.#headers) return kEmptyObject;\n    return this.#headers.toJSON();\n  }\n\n  getHeaderNames() {\n    var headers = this.#headers;\n    if (!headers) return [];\n    return Array.from(headers.keys());\n  }\n\n  removeHeader(name) {\n    if (!this.#headers) return;\n    this.#headers.delete(name);\n  }\n\n  setHeader(name, value) {\n    var headers = (this.#headers ??= new Headers());\n    headers.set(name, value);\n    return this;\n  }\n\n  hasHeader(name) {\n    if (!this.#headers) return false;\n    return this.#headers.has(name);\n  }\n\n  addTrailers(headers) {\n    throw new Error(\"not implemented\");\n  }\n\n  [kClearTimeout]() {\n    if (this.#timeoutTimer) {\n      clearTimeout(this.#timeoutTimer);\n      this.#timeoutTimer = null;\n    }\n  }\n\n  setTimeout(msecs, callback) {\n    if (this.#timeoutTimer) return this;\n    if (callback) {\n      this.on(\"timeout\", callback);\n    }\n\n    this.#timeoutTimer = setTimeout(async () => {\n      this.#timeoutTimer = null;\n      this[kAbortController]?.abort();\n      this.emit(\"timeout\");\n    }, msecs);\n\n    return this;\n  }\n}\n\nexport class ServerResponse extends Writable {\n  constructor({ req, reply }) {\n    super();\n    this.req = req;\n    this._reply = reply;\n    this.sendDate = true;\n    this.statusCode = 200;\n    this.headersSent = false;\n    this.statusMessage = undefined;\n    this.#controller = undefined;\n    this.#firstWrite = undefined;\n    this._writableState.decodeStrings = false;\n    this.#deferred = undefined;\n  }\n\n  req;\n  _reply;\n  sendDate;\n  statusCode;\n  #headers;\n  headersSent = false;\n  statusMessage;\n  #controller;\n  #firstWrite;\n  _sent100 = false;\n  _defaultKeepAlive = false;\n  _removedConnection = false;\n  _removedContLen = false;\n  #deferred = undefined;\n  #finished = false;\n\n  _write(chunk, encoding, callback) {\n    if (!this.#firstWrite && !this.headersSent) {\n      this.#firstWrite = chunk;\n      callback();\n      return;\n    }\n\n    this.#ensureReadableStreamController(controller => {\n      controller.write(chunk);\n      callback();\n    });\n  }\n\n  _writev(chunks, callback) {\n    if (chunks.length === 1 && !this.headersSent && !this.#firstWrite) {\n      this.#firstWrite = chunks[0].chunk;\n      callback();\n      return;\n    }\n\n    this.#ensureReadableStreamController(controller => {\n      for (const chunk of chunks) {\n        controller.write(chunk.chunk);\n      }\n\n      callback();\n    });\n  }\n\n  #ensureReadableStreamController(run) {\n    var thisController = this.#controller;\n    if (thisController) return run(thisController);\n    this.headersSent = true;\n    var firstWrite = this.#firstWrite;\n    this.#firstWrite = undefined;\n    this._reply(\n      new Response(\n        new ReadableStream({\n          type: \"direct\",\n          pull: controller => {\n            this.#controller = controller;\n            if (firstWrite) controller.write(firstWrite);\n            firstWrite = undefined;\n            run(controller);\n            if (!this.#finished) {\n              return new Promise(resolve => {\n                this.#deferred = resolve;\n              });\n            }\n          },\n        }),\n        {\n          headers: this.#headers,\n          status: this.statusCode,\n          statusText: this.statusMessage ?? STATUS_CODES[this.statusCode],\n        },\n      ),\n    );\n  }\n\n  _final(callback) {\n    if (!this.headersSent) {\n      var data = this.#firstWrite || \"\";\n      this.#firstWrite = undefined;\n      this.#finished = true;\n      this._reply(\n        new Response(data, {\n          headers: this.#headers,\n          status: this.statusCode,\n          statusText: this.statusMessage ?? STATUS_CODES[this.statusCode],\n        }),\n      );\n      callback && callback();\n      return;\n    }\n\n    this.#finished = true;\n    this.#ensureReadableStreamController(controller => {\n      controller.end();\n\n      callback();\n      var deferred = this.#deferred;\n      if (deferred) {\n        this.#deferred = undefined;\n        deferred();\n      }\n    });\n  }\n\n  writeProcessing() {\n    throw new Error(\"not implemented\");\n  }\n\n  addTrailers(headers) {\n    throw new Error(\"not implemented\");\n  }\n\n  assignSocket(socket) {\n    throw new Error(\"not implemented\");\n  }\n\n  detachSocket(socket) {\n    throw new Error(\"not implemented\");\n  }\n\n  writeContinue(callback) {\n    throw new Error(\"not implemented\");\n  }\n\n  setTimeout(msecs, callback) {\n    throw new Error(\"not implemented\");\n  }\n\n  get shouldKeepAlive() {\n    return true;\n  }\n\n  get chunkedEncoding() {\n    return false;\n  }\n\n  set chunkedEncoding(value) {\n    // throw new Error('not implemented');\n  }\n\n  set shouldKeepAlive(value) {\n    // throw new Error('not implemented');\n  }\n\n  get useChunkedEncodingByDefault() {\n    return true;\n  }\n\n  set useChunkedEncodingByDefault(value) {\n    // throw new Error('not implemented');\n  }\n\n  appendHeader(name, value) {\n    var headers = (this.#headers ??= new Headers());\n    headers.append(name, value);\n  }\n\n  flushHeaders() {}\n\n  getHeader(name) {\n    return getHeader(this.#headers, name);\n  }\n\n  getHeaders() {\n    var headers = this.#headers;\n    if (!headers) return kEmptyObject;\n    return headers.toJSON();\n  }\n\n  getHeaderNames() {\n    var headers = this.#headers;\n    if (!headers) return [];\n    return Array.from(headers.keys());\n  }\n\n  removeHeader(name) {\n    if (!this.#headers) return;\n    this.#headers.delete(name);\n  }\n\n  setHeader(name, value) {\n    var headers = (this.#headers ??= new Headers());\n    headers.set(name, value);\n    return this;\n  }\n\n  hasHeader(name) {\n    if (!this.#headers) return false;\n    return this.#headers.has(name);\n  }\n\n  writeHead(statusCode, statusMessage, headers) {\n    _writeHead(statusCode, statusMessage, headers, this);\n\n    return this;\n  }\n}\n\nexport class ClientRequest extends OutgoingMessage {\n  #timeout;\n  #res = null;\n  #upgradeOrConnect = false;\n  #parser = null;\n  #maxHeadersCount = null;\n  #reusedSocket = false;\n  #host;\n  #protocol;\n  #method;\n  #port;\n  #useDefaultPort;\n  #joinDuplicateHeaders;\n  #maxHeaderSize;\n  #agent = _globalAgent;\n  #path;\n  #socketPath;\n\n  #body = null;\n  #fetchRequest;\n  #signal = null;\n  [kAbortController] = null;\n  #timeoutTimer = null;\n  #options;\n  #finished;\n\n  get path() {\n    return this.#path;\n  }\n\n  get port() {\n    return this.#port;\n  }\n\n  get method() {\n    return this.#method;\n  }\n\n  get host() {\n    return this.#host;\n  }\n\n  get protocol() {\n    return this.#protocol;\n  }\n\n  _write(chunk, encoding, callback) {\n    var body = this.#body;\n    if (!body) {\n      this.#body = chunk;\n      callback();\n      return;\n    }\n    this.#body = body + chunk;\n    callback();\n  }\n\n  _writev(chunks, callback) {\n    var body = this.#body;\n    if (!body) {\n      this.#body = chunks.join();\n      callback();\n      return;\n    }\n    this.#body = body + chunks.join();\n    callback();\n  }\n\n  _final(callback) {\n    this.#finished = true;\n    this[kAbortController] = new AbortController();\n    this[kAbortController].signal.addEventListener(\"abort\", () => {\n      this[kClearTimeout]();\n    });\n    if (this.#signal?.aborted) {\n      this[kAbortController].abort();\n    }\n\n    var method = this.#method,\n      body = this.#body;\n\n    try {\n      this.#fetchRequest = fetch(\n        `${this.#protocol}//${this.#host}${this.#useDefaultPort ? \"\" : \":\" + this.#port}${this.#path}`,\n        {\n          method,\n          headers: this.getHeaders(),\n          body: body && method !== \"GET\" && method !== \"HEAD\" && method !== \"OPTIONS\" ? body : undefined,\n          redirect: \"manual\",\n          verbose: Boolean(__DEBUG__),\n          signal: this[kAbortController].signal,\n        },\n      )\n        .then(response => {\n          var res = (this.#res = new IncomingMessage(response, {\n            type: \"response\",\n            [kInternalRequest]: this,\n          }));\n          this.emit(\"response\", res);\n        })\n        .catch(err => {\n          if (__DEBUG__) globalReportError(err);\n          this.emit(\"error\", err);\n        })\n        .finally(() => {\n          this.#fetchRequest = null;\n          this[kClearTimeout]();\n        });\n    } catch (err) {\n      if (__DEBUG__) globalReportError(err);\n      this.emit(\"error\", err);\n    } finally {\n      callback();\n    }\n  }\n\n  get aborted() {\n    return this.#signal?.aborted || !!this[kAbortController]?.signal.aborted;\n  }\n\n  abort() {\n    if (this.aborted) return;\n    this[kAbortController].abort();\n    // TODO: Close stream if body streaming\n  }\n\n  constructor(input, options, cb) {\n    super();\n\n    if (typeof input === \"string\") {\n      const urlStr = input;\n      try {\n        var urlObject = new URL(urlStr);\n      } catch (e) {\n        throw new TypeError(`Invalid URL: ${urlStr}`);\n      }\n      input = urlToHttpOptions(urlObject);\n    } else if (input && typeof input === \"object\" && input instanceof URL) {\n      // url.URL instance\n      input = urlToHttpOptions(input);\n    } else {\n      cb = options;\n      options = input;\n      input = null;\n    }\n\n    if (typeof options === \"function\") {\n      cb = options;\n      options = input || kEmptyObject;\n    } else {\n      options = ObjectAssign(input || {}, options);\n    }\n\n    var defaultAgent = options._defaultAgent || Agent.globalAgent;\n\n    let protocol = options.protocol;\n    if (!protocol) {\n      if (options.port === 443) {\n        protocol = \"https:\";\n      } else {\n        protocol = defaultAgent.protocol || \"http:\";\n      }\n      this.#protocol = protocol;\n    }\n\n    switch (this.#agent?.protocol) {\n      case undefined: {\n        break;\n      }\n      case \"http:\": {\n        if (protocol === \"https:\") {\n          defaultAgent = this.#agent = getDefaultHTTPSAgent();\n          break;\n        }\n      }\n      case \"https:\": {\n        if (protocol === \"https\") {\n          defaultAgent = this.#agent = Agent.globalAgent;\n          break;\n        }\n      }\n      default: {\n        break;\n      }\n    }\n\n    if (options.path) {\n      const path = String(options.path);\n      if (RegExpPrototypeExec.call(INVALID_PATH_REGEX, path) !== null) {\n        debug('Path contains unescaped characters: \"%s\"', path);\n        throw new Error(\"Path contains unescaped characters\");\n        // throw new ERR_UNESCAPED_CHARACTERS(\"Request path\");\n      }\n    }\n\n    // Since we don't implement Agent, we don't need this\n    if (protocol !== \"http:\" && protocol !== \"https:\" && protocol) {\n      const expectedProtocol = defaultAgent?.protocol ?? \"http:\";\n      throw new Error(`Protocol mismatch. Expected: ${expectedProtocol}. Got: ${protocol}`);\n      // throw new ERR_INVALID_PROTOCOL(protocol, expectedProtocol);\n    }\n\n    const defaultPort = protocol === \"https:\" ? 443 : 80;\n\n    this.#port = options.port || options.defaultPort || this.#agent?.defaultPort || defaultPort;\n    this.#useDefaultPort = this.#port === defaultPort;\n    const host =\n      (this.#host =\n      options.host =\n        validateHost(options.hostname, \"hostname\") || validateHost(options.host, \"host\") || \"localhost\");\n\n    // const setHost = options.setHost === undefined || Boolean(options.setHost);\n\n    this.#socketPath = options.socketPath;\n\n    if (options.timeout !== undefined) this.setTimeout(options.timeout, null);\n\n    const signal = options.signal;\n    if (signal) {\n      //We still want to control abort function and timeout so signal call our AbortController\n      signal.addEventListener(\"abort\", () => {\n        this[kAbortController]?.abort();\n      });\n      this.#signal = signal;\n    }\n    let method = options.method;\n    const methodIsString = typeof method === \"string\";\n    if (method !== null && method !== undefined && !methodIsString) {\n      // throw new ERR_INVALID_ARG_TYPE(\"options.method\", \"string\", method);\n      throw new Error(\"ERR_INVALID_ARG_TYPE: options.method\");\n    }\n\n    if (methodIsString && method) {\n      if (!checkIsHttpToken(method)) {\n        // throw new ERR_INVALID_HTTP_TOKEN(\"Method\", method);\n        throw new Error(\"ERR_INVALID_HTTP_TOKEN: Method\");\n      }\n      method = this.#method = StringPrototypeToUpperCase.call(method);\n    } else {\n      method = this.#method = \"GET\";\n    }\n\n    const _maxHeaderSize = options.maxHeaderSize;\n    // TODO: Validators\n    // if (maxHeaderSize !== undefined)\n    //   validateInteger(maxHeaderSize, \"maxHeaderSize\", 0);\n    this.#maxHeaderSize = _maxHeaderSize;\n\n    // const insecureHTTPParser = options.insecureHTTPParser;\n    // if (insecureHTTPParser !== undefined) {\n    //   validateBoolean(insecureHTTPParser, 'options.insecureHTTPParser');\n    // }\n\n    // this.insecureHTTPParser = insecureHTTPParser;\n    var _joinDuplicateHeaders = options.joinDuplicateHeaders;\n    if (_joinDuplicateHeaders !== undefined) {\n      // TODO: Validators\n      // validateBoolean(\n      //   options.joinDuplicateHeaders,\n      //   \"options.joinDuplicateHeaders\",\n      // );\n    }\n\n    this.#joinDuplicateHeaders = _joinDuplicateHeaders;\n\n    this.#path = options.path || \"/\";\n    if (cb) {\n      this.once(\"response\", cb);\n    }\n\n    __DEBUG__ &&\n      debug(`new ClientRequest: ${this.#method} ${this.#protocol}//${this.#host}:${this.#port}${this.#path}`);\n\n    // if (\n    //   method === \"GET\" ||\n    //   method === \"HEAD\" ||\n    //   method === \"DELETE\" ||\n    //   method === \"OPTIONS\" ||\n    //   method === \"TRACE\" ||\n    //   method === \"CONNECT\"\n    // ) {\n    //   this.useChunkedEncodingByDefault = false;\n    // } else {\n    //   this.useChunkedEncodingByDefault = true;\n    // }\n\n    this.#finished = false;\n    this.#res = null;\n    this.#upgradeOrConnect = false;\n    this.#parser = null;\n    this.#maxHeadersCount = null;\n    this.#reusedSocket = false;\n    this.#host = host;\n    this.#protocol = protocol;\n    this.#timeoutTimer = null;\n    const headersArray = ArrayIsArray(headers);\n    if (!headersArray) {\n      var headers = options.headers;\n      if (headers) {\n        for (let key in headers) {\n          this.setHeader(key, headers[key]);\n        }\n      }\n\n      // if (host && !this.getHeader(\"host\") && setHost) {\n      //   let hostHeader = host;\n\n      //   // For the Host header, ensure that IPv6 addresses are enclosed\n      //   // in square brackets, as defined by URI formatting\n      //   // https://tools.ietf.org/html/rfc3986#section-3.2.2\n      //   const posColon = StringPrototypeIndexOf.call(hostHeader, \":\");\n      //   if (\n      //     posColon !== -1 &&\n      //     StringPrototypeIncludes(hostHeader, \":\", posColon + 1) &&\n      //     StringPrototypeCharCodeAt(hostHeader, 0) !== 91 /* '[' */\n      //   ) {\n      //     hostHeader = `[${hostHeader}]`;\n      //   }\n\n      //   if (port && +port !== defaultPort) {\n      //     hostHeader += \":\" + port;\n      //   }\n      //   this.setHeader(\"Host\", hostHeader);\n      // }\n\n      var auth = options.auth;\n      if (auth && !this.getHeader(\"Authorization\")) {\n        this.setHeader(\"Authorization\", \"Basic \" + Buffer.from(auth).toString(\"base64\"));\n      }\n\n      //   if (this.getHeader(\"expect\")) {\n      //     if (this._header) {\n      //       throw new ERR_HTTP_HEADERS_SENT(\"render\");\n      //     }\n\n      //     this._storeHeader(\n      //       this.method + \" \" + this.path + \" HTTP/1.1\\r\\n\",\n      //       this[kOutHeaders],\n      //     );\n      //   }\n      // } else {\n      //   this._storeHeader(\n      //     this.method + \" \" + this.path + \" HTTP/1.1\\r\\n\",\n      //     options.headers,\n      //   );\n    }\n\n    // this[kUniqueHeaders] = parseUniqueHeadersOption(options.uniqueHeaders);\n\n    var optsWithoutSignal = options;\n    if (optsWithoutSignal.signal) {\n      optsWithoutSignal = ObjectAssign({}, options);\n      delete optsWithoutSignal.signal;\n    }\n    this.#options = optsWithoutSignal;\n\n    var timeout = options.timeout;\n    if (timeout) {\n      this.setTimeout(timeout);\n    }\n  }\n\n  setSocketKeepAlive(enable = true, initialDelay = 0) {\n    __DEBUG__ && debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: ClientRequest.setSocketKeepAlive is a no-op\");\n  }\n\n  setNoDelay(noDelay = true) {\n    __DEBUG__ && debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: ClientRequest.setNoDelay is a no-op\");\n  }\n  [kClearTimeout]() {\n    if (this.#timeoutTimer) {\n      clearTimeout(this.#timeoutTimer);\n      this.#timeoutTimer = null;\n    }\n  }\n\n  setTimeout(msecs, callback) {\n    if (this.#timeoutTimer) return this;\n    if (callback) {\n      this.on(\"timeout\", callback);\n    }\n\n    this.#timeoutTimer = setTimeout(async () => {\n      this.#timeoutTimer = null;\n      this[kAbortController]?.abort();\n      this.emit(\"timeout\");\n    }, msecs);\n\n    return this;\n  }\n}\n\nfunction urlToHttpOptions(url) {\n  var { protocol, hostname, hash, search, pathname, href, port, username, password } = url;\n  return {\n    protocol,\n    hostname:\n      typeof hostname === \"string\" && StringPrototypeStartsWith.call(hostname, \"[\")\n        ? StringPrototypeSlice.call(hostname, 1, -1)\n        : hostname,\n    hash,\n    search,\n    pathname,\n    path: `${pathname || \"\"}${search || \"\"}`,\n    href,\n    port: port ? Number(port) : protocol === \"https:\" ? 443 : protocol === \"http:\" ? 80 : undefined,\n    auth: username || password ? `${decodeURIComponent(username)}:${decodeURIComponent(password)}` : undefined,\n  };\n}\n\nfunction validateHost(host, name) {\n  if (host !== null && host !== undefined && typeof host !== \"string\") {\n    // throw new ERR_INVALID_ARG_TYPE(\n    //   `options.${name}`,\n    //   [\"string\", \"undefined\", \"null\"],\n    //   host,\n    // );\n    throw new Error(\"Invalid arg type in options\");\n  }\n  return host;\n}\n\nconst tokenRegExp = /^[\\^_`a-zA-Z\\-0-9!#$%&'*+.|~]+$/;\n/**\n * Verifies that the given val is a valid HTTP token\n * per the rules defined in RFC 7230\n * See https://tools.ietf.org/html/rfc7230#section-3.2.6\n */\nfunction checkIsHttpToken(val) {\n  return RegExpPrototypeExec.call(tokenRegExp, val) !== null;\n}\n\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nexport const METHODS = [\n  \"ACL\",\n  \"BIND\",\n  \"CHECKOUT\",\n  \"CONNECT\",\n  \"COPY\",\n  \"DELETE\",\n  \"GET\",\n  \"HEAD\",\n  \"LINK\",\n  \"LOCK\",\n  \"M-SEARCH\",\n  \"MERGE\",\n  \"MKACTIVITY\",\n  \"MKCALENDAR\",\n  \"MKCOL\",\n  \"MOVE\",\n  \"NOTIFY\",\n  \"OPTIONS\",\n  \"PATCH\",\n  \"POST\",\n  \"PROPFIND\",\n  \"PROPPATCH\",\n  \"PURGE\",\n  \"PUT\",\n  \"REBIND\",\n  \"REPORT\",\n  \"SEARCH\",\n  \"SOURCE\",\n  \"SUBSCRIBE\",\n  \"TRACE\",\n  \"UNBIND\",\n  \"UNLINK\",\n  \"UNLOCK\",\n  \"UNSUBSCRIBE\",\n];\n\nexport const STATUS_CODES = {\n  100: \"Continue\",\n  101: \"Switching Protocols\",\n  102: \"Processing\",\n  103: \"Early Hints\",\n  200: \"OK\",\n  201: \"Created\",\n  202: \"Accepted\",\n  203: \"Non-Authoritative Information\",\n  204: \"No Content\",\n  205: \"Reset Content\",\n  206: \"Partial Content\",\n  207: \"Multi-Status\",\n  208: \"Already Reported\",\n  226: \"IM Used\",\n  300: \"Multiple Choices\",\n  301: \"Moved Permanently\",\n  302: \"Found\",\n  303: \"See Other\",\n  304: \"Not Modified\",\n  305: \"Use Proxy\",\n  307: \"Temporary Redirect\",\n  308: \"Permanent Redirect\",\n  400: \"Bad Request\",\n  401: \"Unauthorized\",\n  402: \"Payment Required\",\n  403: \"Forbidden\",\n  404: \"Not Found\",\n  405: \"Method Not Allowed\",\n  406: \"Not Acceptable\",\n  407: \"Proxy Authentication Required\",\n  408: \"Request Timeout\",\n  409: \"Conflict\",\n  410: \"Gone\",\n  411: \"Length Required\",\n  412: \"Precondition Failed\",\n  413: \"Payload Too Large\",\n  414: \"URI Too Long\",\n  415: \"Unsupported Media Type\",\n  416: \"Range Not Satisfiable\",\n  417: \"Expectation Failed\",\n  418: \"I'm a Teapot\",\n  421: \"Misdirected Request\",\n  422: \"Unprocessable Entity\",\n  423: \"Locked\",\n  424: \"Failed Dependency\",\n  425: \"Too Early\",\n  426: \"Upgrade Required\",\n  428: \"Precondition Required\",\n  429: \"Too Many Requests\",\n  431: \"Request Header Fields Too Large\",\n  451: \"Unavailable For Legal Reasons\",\n  500: \"Internal Server Error\",\n  501: \"Not Implemented\",\n  502: \"Bad Gateway\",\n  503: \"Service Unavailable\",\n  504: \"Gateway Timeout\",\n  505: \"HTTP Version Not Supported\",\n  506: \"Variant Also Negotiates\",\n  507: \"Insufficient Storage\",\n  508: \"Loop Detected\",\n  509: \"Bandwidth Limit Exceeded\",\n  510: \"Not Extended\",\n  511: \"Network Authentication Required\",\n};\n\nfunction _normalizeArgs(args) {\n  let arr;\n\n  if (args.length === 0) {\n    arr = [{}, null];\n    // arr[normalizedArgsSymbol] = true;\n    return arr;\n  }\n\n  const arg0 = args[0];\n  let options = {};\n  if (typeof arg0 === \"object\" && arg0 !== null) {\n    // (options[...][, cb])\n    options = arg0;\n    // } else if (isPipeName(arg0)) {\n    // (path[...][, cb])\n    // options.path = arg0;\n  } else {\n    // ([port][, host][...][, cb])\n    options.port = arg0;\n    if (args.length > 1 && typeof args[1] === \"string\") {\n      options.host = args[1];\n    }\n  }\n\n  const cb = args[args.length - 1];\n  if (typeof cb !== \"function\") arr = [options, null];\n  else arr = [options, cb];\n\n  // arr[normalizedArgsSymbol] = true;\n  return arr;\n}\n\nfunction _writeHead(statusCode, reason, obj, response) {\n  statusCode |= 0;\n  if (statusCode < 100 || statusCode > 999) {\n    throw new Error(\"status code must be between 100 and 999\");\n  }\n\n  if (typeof reason === \"string\") {\n    // writeHead(statusCode, reasonPhrase[, headers])\n    response.statusMessage = reason;\n  } else {\n    // writeHead(statusCode[, headers])\n    if (!response.statusMessage) response.statusMessage = STATUS_CODES[statusCode] || \"unknown\";\n    obj = reason;\n  }\n  response.statusCode = statusCode;\n\n  {\n    // Slow-case: when progressive API and header fields are passed.\n    let k;\n    if (Array.isArray(obj)) {\n      if (obj.length % 2 !== 0) {\n        throw new Error(\"raw headers must have an even number of elements\");\n      }\n\n      for (let n = 0; n < obj.length; n += 2) {\n        k = obj[n + 0];\n        if (k) response.setHeader(k, obj[n + 1]);\n      }\n    } else if (obj) {\n      const keys = Object.keys(obj);\n      // Retain for(;;) loop for performance reasons\n      // Refs: https://github.com/nodejs/node/pull/30958\n      for (let i = 0; i < keys.length; i++) {\n        k = keys[i];\n        if (k) response.setHeader(k, obj[k]);\n      }\n    }\n  }\n}\n\n/**\n * Makes an HTTP request.\n * @param {string | URL} url\n * @param {HTTPRequestOptions} [options]\n * @param {Function} [cb]\n * @returns {ClientRequest}\n */\nexport function request(url, options, cb) {\n  return new ClientRequest(url, options, cb);\n}\n\n/**\n * Makes a `GET` HTTP request.\n * @param {string | URL} url\n * @param {HTTPRequestOptions} [options]\n * @param {Function} [cb]\n * @returns {ClientRequest}\n */\nexport function get(url, options, cb) {\n  const req = request(url, options, cb);\n  req.end();\n  return req;\n}\n\nvar defaultObject = {\n  Agent,\n  Server,\n  METHODS,\n  STATUS_CODES,\n  createServer,\n  ServerResponse,\n  IncomingMessage,\n  request,\n  get,\n  maxHeaderSize: 16384,\n  // validateHeaderName,\n  // validateHeaderValue,\n  setMaxIdleHTTPParsers(max) {\n    debug(`${NODE_HTTP_WARNING}\\n`, \"setMaxIdleHTTPParsers() is a no-op\");\n  },\n  get globalAgent() {\n    return (_globalAgent ??= new Agent());\n  },\n  set globalAgent(agent) {},\n  [Symbol.for(\"CommonJS\")]: 0,\n};\n\nexport default defaultObject;\n",
  "// Hardcoded module \"node:http\"\nconst { EventEmitter } = import.meta.require(\"node:events\");\nconst { isIPv6 } = import.meta.require(\"node:net\");\nconst { Readable, Writable, Duplex } = import.meta.require(\"node:stream\");\nconst { URL } = import.meta.require(\"node:url\");\nconst { newArrayWithSize, String, Object, Array } = import.meta.primordials;\nconst { isTypedArray } = import.meta.require(\"util/types\");\n\nconst globalReportError = globalThis.reportError;\nconst setTimeout = globalThis.setTimeout;\nconst fetch = Bun.fetch;\nconst nop = () => {};\n\nconst __DEBUG__ = process.env.__DEBUG__;\nconst debug = __DEBUG__ ? (...args) => console.log(\"node:http\", ...args) : nop;\n\nconst kEmptyObject = Object.freeze(Object.create(null));\nconst kOutHeaders = Symbol.for(\"kOutHeaders\");\nconst kEndCalled = Symbol.for(\"kEndCalled\");\nconst kAbortController = Symbol.for(\"kAbortController\");\nconst kClearTimeout = Symbol(\"kClearTimeout\");\n\nconst kCorked = Symbol.for(\"kCorked\");\nconst searchParamsSymbol = Symbol.for(\"query\"); // This is the symbol used in Node\n\n// Primordials\nconst StringPrototypeSlice = String.prototype.slice;\nconst StringPrototypeStartsWith = String.prototype.startsWith;\nconst StringPrototypeToUpperCase = String.prototype.toUpperCase;\nconst StringPrototypeIncludes = String.prototype.includes;\nconst StringPrototypeCharCodeAt = String.prototype.charCodeAt;\nconst StringPrototypeIndexOf = String.prototype.indexOf;\nconst ArrayIsArray = Array.isArray;\nconst RegExpPrototypeExec = RegExp.prototype.exec;\nconst ObjectAssign = Object.assign;\nconst ObjectPrototypeHasOwnProperty = Object.prototype.hasOwnProperty;\n\nconst INVALID_PATH_REGEX = /[^\\u0021-\\u00ff]/;\nconst NODE_HTTP_WARNING =\n  \"WARN: Agent is mostly unused in Bun's implementation of http. If you see strange behavior, this is probably the cause.\";\n\nvar _globalAgent;\nvar _defaultHTTPSAgent;\nvar kInternalRequest = Symbol(\"kInternalRequest\");\nvar kInternalSocketData = Symbol.for(\"::bunternal::\");\n\nconst kEmptyBuffer = Buffer.alloc(0);\n\nfunction isValidTLSArray(obj) {\n  if (typeof obj === \"string\" || isTypedArray(obj) || obj instanceof ArrayBuffer || obj instanceof Blob) return true;\n  if (Array.isArray(obj)) {\n    for (var i = 0; i < obj.length; i++) {\n      if (typeof obj !== \"string\" && !isTypedArray(obj) && !(obj instanceof ArrayBuffer) && !(obj instanceof Blob))\n        return false;\n    }\n    return true;\n  }\n}\n\nfunction getHeader(headers, name) {\n  if (!headers) return;\n  const result = headers.get(name);\n  return result == null ? undefined : result;\n}\n\nvar FakeSocket = class Socket extends Duplex {\n  bytesRead = 0;\n  bytesWritten = 0;\n  connecting = false;\n  remoteAddress = null;\n  localAddress = \"127.0.0.1\";\n  remotePort;\n  timeout = 0;\n\n  isServer = false;\n\n  address() {\n    return {\n      address: this.localAddress,\n      family: this.localFamily,\n      port: this.localPort,\n    };\n  }\n\n  get bufferSize() {\n    return this.writableLength;\n  }\n\n  connect(port, host, connectListener) {\n    return this;\n  }\n\n  _destroy(err, callback) {}\n\n  _final(callback) {}\n\n  get localAddress() {\n    return \"127.0.0.1\";\n  }\n\n  get localFamily() {\n    return \"IPv4\";\n  }\n\n  get localPort() {\n    return 80;\n  }\n\n  get pending() {\n    return this.connecting;\n  }\n\n  _read(size) {}\n\n  get readyState() {\n    if (this.connecting) return \"opening\";\n    if (this.readable) {\n      return this.writable ? \"open\" : \"readOnly\";\n    } else {\n      return this.writable ? \"writeOnly\" : \"closed\";\n    }\n  }\n\n  ref() {}\n\n  get remoteFamily() {\n    return \"IPv4\";\n  }\n\n  resetAndDestroy() {}\n\n  setKeepAlive(enable = false, initialDelay = 0) {}\n\n  setNoDelay(noDelay = true) {\n    return this;\n  }\n\n  setTimeout(timeout, callback) {\n    return this;\n  }\n\n  unref() {}\n\n  _write(chunk, encoding, callback) {}\n};\n\nexport function createServer(options, callback) {\n  return new Server(options, callback);\n}\n\nexport class Agent extends EventEmitter {\n  #defaultPort = 80;\n  #protocol = \"http:\";\n  #options;\n  #requests;\n  #sockets;\n  #freeSockets;\n\n  #keepAliveMsecs;\n  #keepAlive;\n  #maxSockets;\n  #maxFreeSockets;\n  #scheduling;\n  #maxTotalSockets;\n  #totalSocketCount;\n\n  #fakeSocket;\n\n  static get globalAgent() {\n    return (_globalAgent ??= new Agent());\n  }\n\n  static get defaultMaxSockets() {\n    return Infinity;\n  }\n\n  constructor(options = kEmptyObject) {\n    super();\n    this.#options = options = { ...options, path: null };\n    if (options.noDelay === undefined) options.noDelay = true;\n\n    // Don't confuse net and make it think that we're connecting to a pipe\n    this.#requests = kEmptyObject;\n    this.#sockets = kEmptyObject;\n    this.#freeSockets = kEmptyObject;\n\n    this.#keepAliveMsecs = options.keepAliveMsecs || 1000;\n    this.#keepAlive = options.keepAlive || false;\n    this.#maxSockets = options.maxSockets || Agent.defaultMaxSockets;\n    this.#maxFreeSockets = options.maxFreeSockets || 256;\n    this.#scheduling = options.scheduling || \"lifo\";\n    this.#maxTotalSockets = options.maxTotalSockets;\n    this.#totalSocketCount = 0;\n    this.#defaultPort = options.defaultPort || 80;\n    this.#protocol = options.protocol || \"http:\";\n  }\n\n  get defaultPort() {\n    return this.#defaultPort;\n  }\n\n  get protocol() {\n    return this.#protocol;\n  }\n\n  get requests() {\n    return this.#requests;\n  }\n\n  get sockets() {\n    return this.#sockets;\n  }\n\n  get freeSockets() {\n    return this.#freeSockets;\n  }\n\n  get options() {\n    return this.#options;\n  }\n\n  get keepAliveMsecs() {\n    return this.#keepAliveMsecs;\n  }\n\n  get keepAlive() {\n    return this.#keepAlive;\n  }\n\n  get maxSockets() {\n    return this.#maxSockets;\n  }\n\n  get maxFreeSockets() {\n    return this.#maxFreeSockets;\n  }\n\n  get scheduling() {\n    return this.#scheduling;\n  }\n\n  get maxTotalSockets() {\n    return this.#maxTotalSockets;\n  }\n\n  get totalSocketCount() {\n    return this.#totalSocketCount;\n  }\n\n  createConnection() {\n    debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: Agent.createConnection is a no-op, returns fake socket\");\n    return (this.#fakeSocket ??= new FakeSocket());\n  }\n\n  getName(options = kEmptyObject) {\n    let name = `http:${options.host || \"localhost\"}:`;\n    if (options.port) name += options.port;\n    name += \":\";\n    if (options.localAddress) name += options.localAddress;\n    // Pacify parallel/test-http-agent-getname by only appending\n    // the ':' when options.family is set.\n    if (options.family === 4 || options.family === 6) name += `:${options.family}`;\n    if (options.socketPath) name += `:${options.socketPath}`;\n    return name;\n  }\n\n  addRequest() {\n    debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: Agent.addRequest is a no-op\");\n  }\n\n  createSocket(req, options, cb) {\n    debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: Agent.createSocket returns fake socket\");\n    cb(null, (this.#fakeSocket ??= new FakeSocket()));\n  }\n\n  removeSocket() {\n    debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: Agent.removeSocket is a no-op\");\n  }\n\n  keepSocketAlive() {\n    debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: Agent.keepSocketAlive is a no-op\");\n\n    return true;\n  }\n\n  reuseSocket() {\n    debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: Agent.reuseSocket is a no-op\");\n  }\n\n  destroy() {\n    debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: Agent.destroy is a no-op\");\n  }\n}\nfunction emitListeningNextTick(self, onListen, err, hostname, port) {\n  if (typeof onListen === \"function\") {\n    try {\n      onListen(err, hostname, port);\n    } catch (err) {\n      self.emit(\"error\", err);\n    }\n  }\n\n  self.listening = !err;\n\n  if (err) {\n    self.emit(\"error\", err);\n  } else {\n    self.emit(\"listening\", hostname, port);\n  }\n}\n\nexport class Server extends EventEmitter {\n  #server;\n  #options;\n  #tls;\n  #is_tls = false;\n  listening = false;\n\n  constructor(options, callback) {\n    super();\n\n    if (typeof options === \"function\") {\n      callback = options;\n      options = {};\n    } else if (options == null || typeof options === \"object\") {\n      options = { ...options };\n      this.#tls = null;\n      let key = options.key;\n      if (key) {\n        if (!isValidTLSArray(key)) {\n          throw new TypeError(\n            \"key argument must be an string, Buffer, TypedArray, BunFile or an array containing string, Buffer, TypedArray or BunFile\",\n          );\n        }\n        this.#is_tls = true;\n      }\n      let cert = options.cert;\n      if (cert) {\n        if (!isValidTLSArray(cert)) {\n          throw new TypeError(\n            \"cert argument must be an string, Buffer, TypedArray, BunFile or an array containing string, Buffer, TypedArray or BunFile\",\n          );\n        }\n        this.#is_tls = true;\n      }\n\n      let ca = options.ca;\n      if (ca) {\n        if (!isValidTLSArray(ca)) {\n          throw new TypeError(\n            \"ca argument must be an string, Buffer, TypedArray, BunFile or an array containing string, Buffer, TypedArray or BunFile\",\n          );\n        }\n        this.#is_tls = true;\n      }\n      let passphrase = options.passphrase;\n      if (passphrase && typeof passphrase !== \"string\") {\n        throw new TypeError(\"passphrase argument must be an string\");\n      }\n\n      let serverName = options.servername;\n      if (serverName && typeof serverName !== \"string\") {\n        throw new TypeError(\"servername argument must be an string\");\n      }\n\n      let secureOptions = options.secureOptions || 0;\n      if (secureOptions && typeof secureOptions !== \"number\") {\n        throw new TypeError(\"secureOptions argument must be an number\");\n      }\n\n      if (this.#is_tls) {\n        this.#tls = {\n          serverName,\n          key: key,\n          cert: cert,\n          ca: ca,\n          passphrase: passphrase,\n          secureOptions: secureOptions,\n        };\n      } else {\n        this.#tls = null;\n      }\n    } else {\n      throw new Error(\"bun-http-polyfill: invalid arguments\");\n    }\n\n    this.#options = options;\n\n    if (callback) this.on(\"request\", callback);\n  }\n\n  closeAllConnections() {\n    const server = this.#server;\n    if (!server) {\n      return;\n    }\n    this.#server = undefined;\n    server.stop(true);\n    this.emit(\"close\");\n  }\n\n  closeIdleConnections() {\n    // not actually implemented\n  }\n\n  close(optionalCallback) {\n    const server = this.#server;\n    if (!server) {\n      if (typeof optionalCallback === \"function\")\n        process.nextTick(optionalCallback, new Error(\"Server is not running\"));\n      return;\n    }\n    this.#server = undefined;\n    if (typeof optionalCallback === \"function\") this.once(\"close\", optionalCallback);\n    server.stop();\n    this.emit(\"close\");\n  }\n\n  address() {\n    if (!this.#server) return null;\n\n    const address = this.#server.hostname;\n    return {\n      address,\n      family: isIPv6(address) ? \"IPv6\" : \"IPv4\",\n      port: this.#server.port,\n    };\n  }\n\n  listen(port, host, backlog, onListen) {\n    const server = this;\n    if (typeof host === \"function\") {\n      onListen = host;\n      host = undefined;\n    }\n\n    if (typeof port === \"function\") {\n      onListen = port;\n    } else if (typeof port === \"object\") {\n      port?.signal?.addEventListener(\"abort\", () => {\n        this.close();\n      });\n\n      host = port?.host;\n      port = port?.port;\n\n      if (typeof port?.callback === \"function\") onListen = port?.callback;\n    }\n\n    if (typeof backlog === \"function\") {\n      onListen = backlog;\n    }\n\n    const ResponseClass = this.#options.ServerResponse || ServerResponse;\n    const RequestClass = this.#options.IncomingMessage || IncomingMessage;\n\n    try {\n      const tls = this.#tls;\n      if (tls) {\n        this.serverName = tls.serverName || host || \"localhost\";\n      }\n      this.#server = Bun.serve({\n        tls,\n        port,\n        hostname: host,\n        // Bindings to be used for WS Server\n        websocket: {\n          open(ws) {\n            ws.data.open(ws);\n          },\n          message(ws, message) {\n            ws.data.message(ws, message);\n          },\n          close(ws, code, reason) {\n            ws.data.close(ws, code, reason);\n          },\n          drain(ws) {\n            ws.data.drain(ws);\n          },\n        },\n        fetch(req, _server) {\n          var pendingResponse;\n          var pendingError;\n          var rejectFunction, resolveFunction;\n          var reject = err => {\n            if (pendingError) return;\n            pendingError = err;\n            if (rejectFunction) rejectFunction(err);\n          };\n\n          var reply = function (resp) {\n            if (pendingResponse) return;\n            pendingResponse = resp;\n            if (resolveFunction) resolveFunction(resp);\n          };\n\n          const http_req = new RequestClass(req);\n          const http_res = new ResponseClass({ reply, req: http_req });\n\n          http_req.once(\"error\", err => reject(err));\n          http_res.once(\"error\", err => reject(err));\n\n          const upgrade = req.headers.get(\"upgrade\");\n          if (upgrade) {\n            const socket = new FakeSocket();\n            socket[kInternalSocketData] = [_server, http_res, req];\n            server.emit(\"upgrade\", http_req, socket, kEmptyBuffer);\n          } else {\n            server.emit(\"request\", http_req, http_res);\n          }\n\n          if (pendingError) {\n            throw pendingError;\n          }\n\n          if (pendingResponse) {\n            return pendingResponse;\n          }\n\n          return new Promise((resolve, reject) => {\n            resolveFunction = resolve;\n            rejectFunction = reject;\n          });\n        },\n      });\n      setTimeout(emitListeningNextTick, 1, this, onListen, null, this.#server.hostname, this.#server.port);\n    } catch (err) {\n      setTimeout(emitListeningNextTick, 1, this, onListen, err);\n    }\n\n    return this;\n  }\n  setTimeout(msecs, callback) {}\n}\n\nfunction assignHeaders(object, req) {\n  var headers = req.headers.toJSON();\n  const rawHeaders = newArrayWithSize(req.headers.count * 2);\n  var i = 0;\n  for (const key in headers) {\n    rawHeaders[i++] = key;\n    rawHeaders[i++] = headers[key];\n  }\n  object.headers = headers;\n  object.rawHeaders = rawHeaders;\n}\nfunction destroyBodyStreamNT(bodyStream) {\n  bodyStream.destroy();\n}\n\nvar defaultIncomingOpts = { type: \"request\" };\n\nfunction getDefaultHTTPSAgent() {\n  return (_defaultHTTPSAgent ??= new Agent({ defaultPort: 443, protocol: \"https:\" }));\n}\n\nexport class IncomingMessage extends Readable {\n  constructor(req, defaultIncomingOpts) {\n    const method = req.method;\n\n    super();\n\n    const url = new URL(req.url);\n\n    var { type = \"request\", [kInternalRequest]: nodeReq } = defaultIncomingOpts || {};\n\n    this.#noBody =\n      type === \"request\" // TODO: Add logic for checking for body on response\n        ? \"GET\" === method ||\n          \"HEAD\" === method ||\n          \"TRACE\" === method ||\n          \"CONNECT\" === method ||\n          \"OPTIONS\" === method ||\n          (parseInt(req.headers.get(\"Content-Length\") || \"\") || 0) === 0\n        : false;\n\n    this.#req = req;\n    this.method = method;\n    this.#type = type;\n    this.complete = !!this.#noBody;\n\n    this.#bodyStream = null;\n    const socket = new FakeSocket();\n    socket.remoteAddress = url.hostname;\n    socket.remotePort = url.port;\n    this.#fakeSocket = socket;\n\n    this.url = url.pathname + url.search;\n    this.#nodeReq = nodeReq;\n    assignHeaders(this, req);\n  }\n\n  headers;\n  rawHeaders;\n  _consuming = false;\n  _dumped = false;\n  #bodyStream = null;\n  #fakeSocket = undefined;\n  #noBody = false;\n  #aborted = false;\n  #req;\n  url;\n  #type;\n  #nodeReq;\n\n  get req() {\n    return this.#nodeReq;\n  }\n\n  _construct(callback) {\n    // TODO: streaming\n    if (this.#type === \"response\" || this.#noBody) {\n      callback();\n      return;\n    }\n\n    const contentLength = this.#req.headers.get(\"content-length\");\n    const length = contentLength ? parseInt(contentLength, 10) : 0;\n    if (length === 0) {\n      this.#noBody = true;\n      callback();\n      return;\n    }\n\n    callback();\n  }\n\n  #closeBodyStream() {\n    debug(\"closeBodyStream()\");\n    var bodyStream = this.#bodyStream;\n    if (bodyStream == null) return;\n    this.complete = true;\n    this.#bodyStream = undefined;\n    this.push(null);\n    // process.nextTick(destroyBodyStreamNT, bodyStream);\n  }\n\n  _read(size) {\n    if (this.#noBody) {\n      this.push(null);\n      this.complete = true;\n    } else if (this.#bodyStream == null) {\n      const contentLength = this.#req.headers.get(\"content-length\");\n      let remaining = contentLength ? parseInt(contentLength, 10) : 0;\n      this.#bodyStream = Readable.fromWeb(this.#req.body, {\n        highWaterMark: Number.isFinite(remaining) ? Math.min(remaining, 16384) : 16384,\n      });\n\n      const isBodySizeKnown = remaining > 0 && Number.isSafeInteger(remaining);\n\n      if (isBodySizeKnown) {\n        this.#bodyStream.on(\"data\", chunk => {\n          debug(\"body size known\", remaining);\n          this.push(chunk);\n          // when we are streaming a known body size, automatically close the stream when we have read enough\n          remaining -= chunk?.byteLength ?? 0;\n          if (remaining <= 0) {\n            this.#closeBodyStream();\n          }\n        });\n      } else {\n        this.#bodyStream.on(\"data\", chunk => {\n          this.push(chunk);\n        });\n      }\n\n      // this can be closed by the time we get here if enough data was synchronously available\n      this.#bodyStream &&\n        this.#bodyStream.on(\"end\", () => {\n          this.#closeBodyStream();\n        });\n    } else {\n      // this.#bodyStream.read(size);\n    }\n  }\n\n  get aborted() {\n    return this.#aborted;\n  }\n\n  abort() {\n    if (this.#aborted) return;\n    this.#aborted = true;\n\n    this.#closeBodyStream();\n  }\n\n  get connection() {\n    return this.#fakeSocket;\n  }\n\n  get statusCode() {\n    return this.#req.status;\n  }\n\n  get statusMessage() {\n    return STATUS_CODES[this.#req.status];\n  }\n\n  get httpVersion() {\n    return \"1.1\";\n  }\n\n  get rawTrailers() {\n    return [];\n  }\n\n  get httpVersionMajor() {\n    return 1;\n  }\n\n  get httpVersionMinor() {\n    return 1;\n  }\n\n  get trailers() {\n    return kEmptyObject;\n  }\n\n  get socket() {\n    return (this.#fakeSocket ??= new FakeSocket());\n  }\n\n  set socket(val) {\n    this.#fakeSocket = val;\n  }\n\n  setTimeout(msecs, callback) {\n    throw new Error(\"not implemented\");\n  }\n}\n\nfunction emitErrorNt(msg, err, callback) {\n  callback(err);\n  if (typeof msg.emit === \"function\" && !msg._closed) {\n    msg.emit(\"error\", err);\n  }\n}\n\nfunction onError(self, err, cb) {\n  process.nextTick(() => emitErrorNt(self, err, cb));\n}\n\nfunction write_(msg, chunk, encoding, callback, fromEnd) {\n  if (typeof callback !== \"function\") callback = nop;\n\n  let len;\n  if (chunk === null) {\n    // throw new ERR_STREAM_NULL_VALUES();\n    throw new Error(\"ERR_STREAM_NULL_VALUES\");\n  } else if (typeof chunk === \"string\") {\n    len = Buffer.byteLength(chunk, encoding);\n  } else {\n    throw new Error(\"Invalid arg type for chunk\");\n    // throw new ERR_INVALID_ARG_TYPE(\n    //   \"chunk\",\n    //   [\"string\", \"Buffer\", \"Uint8Array\"],\n    //   chunk,\n    // );\n  }\n\n  let err;\n  if (msg.finished) {\n    // err = new ERR_STREAM_WRITE_AFTER_END();\n    err = new Error(\"ERR_STREAM_WRITE_AFTER_END\");\n  } else if (msg.destroyed) {\n    // err = new ERR_STREAM_DESTROYED(\"write\");\n    err = new Error(\"ERR_STREAM_DESTROYED\");\n  }\n\n  if (err) {\n    if (!msg.destroyed) {\n      onError(msg, err, callback);\n    } else {\n      process.nextTick(callback, err);\n    }\n    return false;\n  }\n\n  if (!msg._header) {\n    if (fromEnd) {\n      msg._contentLength = len;\n    }\n    // msg._implicitHeader();\n  }\n\n  if (!msg._hasBody) {\n    debug(\"This type of response MUST NOT have a body. \" + \"Ignoring write() calls.\");\n    process.nextTick(callback);\n    return true;\n  }\n\n  // if (!fromEnd && msg.socket && !msg.socket.writableCorked) {\n  //   msg.socket.cork();\n  //   process.nextTick(connectionCorkNT, msg.socket);\n  // }\n\n  return true;\n}\n\nexport class OutgoingMessage extends Writable {\n  #headers;\n  headersSent = false;\n  sendDate = true;\n  req;\n\n  #finished = false;\n  [kEndCalled] = false;\n\n  #fakeSocket;\n  #timeoutTimer = null;\n  [kAbortController] = null;\n\n  // For compat with IncomingRequest\n  get headers() {\n    if (!this.#headers) return kEmptyObject;\n    return this.#headers.toJSON();\n  }\n\n  get shouldKeepAlive() {\n    return true;\n  }\n\n  get chunkedEncoding() {\n    return false;\n  }\n\n  set chunkedEncoding(value) {\n    // throw new Error('not implemented');\n  }\n\n  set shouldKeepAlive(value) {\n    // throw new Error('not implemented');\n  }\n\n  get useChunkedEncodingByDefault() {\n    return true;\n  }\n\n  set useChunkedEncodingByDefault(value) {\n    // throw new Error('not implemented');\n  }\n\n  get socket() {\n    return (this.#fakeSocket ??= new FakeSocket());\n  }\n\n  set socket(val) {\n    this.#fakeSocket = val;\n  }\n\n  get connection() {\n    return this.socket;\n  }\n\n  get finished() {\n    return this.#finished;\n  }\n\n  appendHeader(name, value) {\n    var headers = (this.#headers ??= new Headers());\n    headers.append(name, value);\n  }\n\n  flushHeaders() {}\n\n  getHeader(name) {\n    return getHeader(this.#headers, name);\n  }\n\n  getHeaders() {\n    if (!this.#headers) return kEmptyObject;\n    return this.#headers.toJSON();\n  }\n\n  getHeaderNames() {\n    var headers = this.#headers;\n    if (!headers) return [];\n    return Array.from(headers.keys());\n  }\n\n  removeHeader(name) {\n    if (!this.#headers) return;\n    this.#headers.delete(name);\n  }\n\n  setHeader(name, value) {\n    var headers = (this.#headers ??= new Headers());\n    headers.set(name, value);\n    return this;\n  }\n\n  hasHeader(name) {\n    if (!this.#headers) return false;\n    return this.#headers.has(name);\n  }\n\n  addTrailers(headers) {\n    throw new Error(\"not implemented\");\n  }\n\n  [kClearTimeout]() {\n    if (this.#timeoutTimer) {\n      clearTimeout(this.#timeoutTimer);\n      this.#timeoutTimer = null;\n    }\n  }\n\n  setTimeout(msecs, callback) {\n    if (this.#timeoutTimer) return this;\n    if (callback) {\n      this.on(\"timeout\", callback);\n    }\n\n    this.#timeoutTimer = setTimeout(async () => {\n      this.#timeoutTimer = null;\n      this[kAbortController]?.abort();\n      this.emit(\"timeout\");\n    }, msecs);\n\n    return this;\n  }\n}\n\nexport class ServerResponse extends Writable {\n  constructor({ req, reply }) {\n    super();\n    this.req = req;\n    this._reply = reply;\n    this.sendDate = true;\n    this.statusCode = 200;\n    this.headersSent = false;\n    this.statusMessage = undefined;\n    this.#controller = undefined;\n    this.#firstWrite = undefined;\n    this._writableState.decodeStrings = false;\n    this.#deferred = undefined;\n  }\n\n  req;\n  _reply;\n  sendDate;\n  statusCode;\n  #headers;\n  headersSent = false;\n  statusMessage;\n  #controller;\n  #firstWrite;\n  _sent100 = false;\n  _defaultKeepAlive = false;\n  _removedConnection = false;\n  _removedContLen = false;\n  #deferred = undefined;\n  #finished = false;\n\n  _write(chunk, encoding, callback) {\n    if (!this.#firstWrite && !this.headersSent) {\n      this.#firstWrite = chunk;\n      callback();\n      return;\n    }\n\n    this.#ensureReadableStreamController(controller => {\n      controller.write(chunk);\n      callback();\n    });\n  }\n\n  _writev(chunks, callback) {\n    if (chunks.length === 1 && !this.headersSent && !this.#firstWrite) {\n      this.#firstWrite = chunks[0].chunk;\n      callback();\n      return;\n    }\n\n    this.#ensureReadableStreamController(controller => {\n      for (const chunk of chunks) {\n        controller.write(chunk.chunk);\n      }\n\n      callback();\n    });\n  }\n\n  #ensureReadableStreamController(run) {\n    var thisController = this.#controller;\n    if (thisController) return run(thisController);\n    this.headersSent = true;\n    var firstWrite = this.#firstWrite;\n    this.#firstWrite = undefined;\n    this._reply(\n      new Response(\n        new ReadableStream({\n          type: \"direct\",\n          pull: controller => {\n            this.#controller = controller;\n            if (firstWrite) controller.write(firstWrite);\n            firstWrite = undefined;\n            run(controller);\n            if (!this.#finished) {\n              return new Promise(resolve => {\n                this.#deferred = resolve;\n              });\n            }\n          },\n        }),\n        {\n          headers: this.#headers,\n          status: this.statusCode,\n          statusText: this.statusMessage ?? STATUS_CODES[this.statusCode],\n        },\n      ),\n    );\n  }\n\n  _final(callback) {\n    if (!this.headersSent) {\n      var data = this.#firstWrite || \"\";\n      this.#firstWrite = undefined;\n      this.#finished = true;\n      this._reply(\n        new Response(data, {\n          headers: this.#headers,\n          status: this.statusCode,\n          statusText: this.statusMessage ?? STATUS_CODES[this.statusCode],\n        }),\n      );\n      callback && callback();\n      return;\n    }\n\n    this.#finished = true;\n    this.#ensureReadableStreamController(controller => {\n      controller.end();\n\n      callback();\n      var deferred = this.#deferred;\n      if (deferred) {\n        this.#deferred = undefined;\n        deferred();\n      }\n    });\n  }\n\n  writeProcessing() {\n    throw new Error(\"not implemented\");\n  }\n\n  addTrailers(headers) {\n    throw new Error(\"not implemented\");\n  }\n\n  assignSocket(socket) {\n    throw new Error(\"not implemented\");\n  }\n\n  detachSocket(socket) {\n    throw new Error(\"not implemented\");\n  }\n\n  writeContinue(callback) {\n    throw new Error(\"not implemented\");\n  }\n\n  setTimeout(msecs, callback) {\n    throw new Error(\"not implemented\");\n  }\n\n  get shouldKeepAlive() {\n    return true;\n  }\n\n  get chunkedEncoding() {\n    return false;\n  }\n\n  set chunkedEncoding(value) {\n    // throw new Error('not implemented');\n  }\n\n  set shouldKeepAlive(value) {\n    // throw new Error('not implemented');\n  }\n\n  get useChunkedEncodingByDefault() {\n    return true;\n  }\n\n  set useChunkedEncodingByDefault(value) {\n    // throw new Error('not implemented');\n  }\n\n  appendHeader(name, value) {\n    var headers = (this.#headers ??= new Headers());\n    headers.append(name, value);\n  }\n\n  flushHeaders() {}\n\n  getHeader(name) {\n    return getHeader(this.#headers, name);\n  }\n\n  getHeaders() {\n    var headers = this.#headers;\n    if (!headers) return kEmptyObject;\n    return headers.toJSON();\n  }\n\n  getHeaderNames() {\n    var headers = this.#headers;\n    if (!headers) return [];\n    return Array.from(headers.keys());\n  }\n\n  removeHeader(name) {\n    if (!this.#headers) return;\n    this.#headers.delete(name);\n  }\n\n  setHeader(name, value) {\n    var headers = (this.#headers ??= new Headers());\n    headers.set(name, value);\n    return this;\n  }\n\n  hasHeader(name) {\n    if (!this.#headers) return false;\n    return this.#headers.has(name);\n  }\n\n  writeHead(statusCode, statusMessage, headers) {\n    _writeHead(statusCode, statusMessage, headers, this);\n\n    return this;\n  }\n}\n\nexport class ClientRequest extends OutgoingMessage {\n  #timeout;\n  #res = null;\n  #upgradeOrConnect = false;\n  #parser = null;\n  #maxHeadersCount = null;\n  #reusedSocket = false;\n  #host;\n  #protocol;\n  #method;\n  #port;\n  #useDefaultPort;\n  #joinDuplicateHeaders;\n  #maxHeaderSize;\n  #agent = _globalAgent;\n  #path;\n  #socketPath;\n\n  #body = null;\n  #fetchRequest;\n  #signal = null;\n  [kAbortController] = null;\n  #timeoutTimer = null;\n  #options;\n  #finished;\n\n  get path() {\n    return this.#path;\n  }\n\n  get port() {\n    return this.#port;\n  }\n\n  get method() {\n    return this.#method;\n  }\n\n  get host() {\n    return this.#host;\n  }\n\n  get protocol() {\n    return this.#protocol;\n  }\n\n  _write(chunk, encoding, callback) {\n    var body = this.#body;\n    if (!body) {\n      this.#body = chunk;\n      callback();\n      return;\n    }\n    this.#body = body + chunk;\n    callback();\n  }\n\n  _writev(chunks, callback) {\n    var body = this.#body;\n    if (!body) {\n      this.#body = chunks.join();\n      callback();\n      return;\n    }\n    this.#body = body + chunks.join();\n    callback();\n  }\n\n  _final(callback) {\n    this.#finished = true;\n    this[kAbortController] = new AbortController();\n    this[kAbortController].signal.addEventListener(\"abort\", () => {\n      this[kClearTimeout]();\n    });\n    if (this.#signal?.aborted) {\n      this[kAbortController].abort();\n    }\n\n    var method = this.#method,\n      body = this.#body;\n\n    try {\n      this.#fetchRequest = fetch(\n        `${this.#protocol}//${this.#host}${this.#useDefaultPort ? \"\" : \":\" + this.#port}${this.#path}`,\n        {\n          method,\n          headers: this.getHeaders(),\n          body: body && method !== \"GET\" && method !== \"HEAD\" && method !== \"OPTIONS\" ? body : undefined,\n          redirect: \"manual\",\n          verbose: Boolean(__DEBUG__),\n          signal: this[kAbortController].signal,\n        },\n      )\n        .then(response => {\n          var res = (this.#res = new IncomingMessage(response, {\n            type: \"response\",\n            [kInternalRequest]: this,\n          }));\n          this.emit(\"response\", res);\n        })\n        .catch(err => {\n          if (__DEBUG__) globalReportError(err);\n          this.emit(\"error\", err);\n        })\n        .finally(() => {\n          this.#fetchRequest = null;\n          this[kClearTimeout]();\n        });\n    } catch (err) {\n      if (__DEBUG__) globalReportError(err);\n      this.emit(\"error\", err);\n    } finally {\n      callback();\n    }\n  }\n\n  get aborted() {\n    return this.#signal?.aborted || !!this[kAbortController]?.signal.aborted;\n  }\n\n  abort() {\n    if (this.aborted) return;\n    this[kAbortController].abort();\n    // TODO: Close stream if body streaming\n  }\n\n  constructor(input, options, cb) {\n    super();\n\n    if (typeof input === \"string\") {\n      const urlStr = input;\n      try {\n        var urlObject = new URL(urlStr);\n      } catch (e) {\n        throw new TypeError(`Invalid URL: ${urlStr}`);\n      }\n      input = urlToHttpOptions(urlObject);\n    } else if (input && typeof input === \"object\" && input instanceof URL) {\n      // url.URL instance\n      input = urlToHttpOptions(input);\n    } else {\n      cb = options;\n      options = input;\n      input = null;\n    }\n\n    if (typeof options === \"function\") {\n      cb = options;\n      options = input || kEmptyObject;\n    } else {\n      options = ObjectAssign(input || {}, options);\n    }\n\n    var defaultAgent = options._defaultAgent || Agent.globalAgent;\n\n    let protocol = options.protocol;\n    if (!protocol) {\n      if (options.port === 443) {\n        protocol = \"https:\";\n      } else {\n        protocol = defaultAgent.protocol || \"http:\";\n      }\n      this.#protocol = protocol;\n    }\n\n    switch (this.#agent?.protocol) {\n      case undefined: {\n        break;\n      }\n      case \"http:\": {\n        if (protocol === \"https:\") {\n          defaultAgent = this.#agent = getDefaultHTTPSAgent();\n          break;\n        }\n      }\n      case \"https:\": {\n        if (protocol === \"https\") {\n          defaultAgent = this.#agent = Agent.globalAgent;\n          break;\n        }\n      }\n      default: {\n        break;\n      }\n    }\n\n    if (options.path) {\n      const path = String(options.path);\n      if (RegExpPrototypeExec.call(INVALID_PATH_REGEX, path) !== null) {\n        debug('Path contains unescaped characters: \"%s\"', path);\n        throw new Error(\"Path contains unescaped characters\");\n        // throw new ERR_UNESCAPED_CHARACTERS(\"Request path\");\n      }\n    }\n\n    // Since we don't implement Agent, we don't need this\n    if (protocol !== \"http:\" && protocol !== \"https:\" && protocol) {\n      const expectedProtocol = defaultAgent?.protocol ?? \"http:\";\n      throw new Error(`Protocol mismatch. Expected: ${expectedProtocol}. Got: ${protocol}`);\n      // throw new ERR_INVALID_PROTOCOL(protocol, expectedProtocol);\n    }\n\n    const defaultPort = protocol === \"https:\" ? 443 : 80;\n\n    this.#port = options.port || options.defaultPort || this.#agent?.defaultPort || defaultPort;\n    this.#useDefaultPort = this.#port === defaultPort;\n    const host =\n      (this.#host =\n      options.host =\n        validateHost(options.hostname, \"hostname\") || validateHost(options.host, \"host\") || \"localhost\");\n\n    // const setHost = options.setHost === undefined || Boolean(options.setHost);\n\n    this.#socketPath = options.socketPath;\n\n    if (options.timeout !== undefined) this.setTimeout(options.timeout, null);\n\n    const signal = options.signal;\n    if (signal) {\n      //We still want to control abort function and timeout so signal call our AbortController\n      signal.addEventListener(\"abort\", () => {\n        this[kAbortController]?.abort();\n      });\n      this.#signal = signal;\n    }\n    let method = options.method;\n    const methodIsString = typeof method === \"string\";\n    if (method !== null && method !== undefined && !methodIsString) {\n      // throw new ERR_INVALID_ARG_TYPE(\"options.method\", \"string\", method);\n      throw new Error(\"ERR_INVALID_ARG_TYPE: options.method\");\n    }\n\n    if (methodIsString && method) {\n      if (!checkIsHttpToken(method)) {\n        // throw new ERR_INVALID_HTTP_TOKEN(\"Method\", method);\n        throw new Error(\"ERR_INVALID_HTTP_TOKEN: Method\");\n      }\n      method = this.#method = StringPrototypeToUpperCase.call(method);\n    } else {\n      method = this.#method = \"GET\";\n    }\n\n    const _maxHeaderSize = options.maxHeaderSize;\n    // TODO: Validators\n    // if (maxHeaderSize !== undefined)\n    //   validateInteger(maxHeaderSize, \"maxHeaderSize\", 0);\n    this.#maxHeaderSize = _maxHeaderSize;\n\n    // const insecureHTTPParser = options.insecureHTTPParser;\n    // if (insecureHTTPParser !== undefined) {\n    //   validateBoolean(insecureHTTPParser, 'options.insecureHTTPParser');\n    // }\n\n    // this.insecureHTTPParser = insecureHTTPParser;\n    var _joinDuplicateHeaders = options.joinDuplicateHeaders;\n    if (_joinDuplicateHeaders !== undefined) {\n      // TODO: Validators\n      // validateBoolean(\n      //   options.joinDuplicateHeaders,\n      //   \"options.joinDuplicateHeaders\",\n      // );\n    }\n\n    this.#joinDuplicateHeaders = _joinDuplicateHeaders;\n\n    this.#path = options.path || \"/\";\n    if (cb) {\n      this.once(\"response\", cb);\n    }\n\n    __DEBUG__ &&\n      debug(`new ClientRequest: ${this.#method} ${this.#protocol}//${this.#host}:${this.#port}${this.#path}`);\n\n    // if (\n    //   method === \"GET\" ||\n    //   method === \"HEAD\" ||\n    //   method === \"DELETE\" ||\n    //   method === \"OPTIONS\" ||\n    //   method === \"TRACE\" ||\n    //   method === \"CONNECT\"\n    // ) {\n    //   this.useChunkedEncodingByDefault = false;\n    // } else {\n    //   this.useChunkedEncodingByDefault = true;\n    // }\n\n    this.#finished = false;\n    this.#res = null;\n    this.#upgradeOrConnect = false;\n    this.#parser = null;\n    this.#maxHeadersCount = null;\n    this.#reusedSocket = false;\n    this.#host = host;\n    this.#protocol = protocol;\n    this.#timeoutTimer = null;\n    const headersArray = ArrayIsArray(headers);\n    if (!headersArray) {\n      var headers = options.headers;\n      if (headers) {\n        for (let key in headers) {\n          this.setHeader(key, headers[key]);\n        }\n      }\n\n      // if (host && !this.getHeader(\"host\") && setHost) {\n      //   let hostHeader = host;\n\n      //   // For the Host header, ensure that IPv6 addresses are enclosed\n      //   // in square brackets, as defined by URI formatting\n      //   // https://tools.ietf.org/html/rfc3986#section-3.2.2\n      //   const posColon = StringPrototypeIndexOf.call(hostHeader, \":\");\n      //   if (\n      //     posColon !== -1 &&\n      //     StringPrototypeIncludes(hostHeader, \":\", posColon + 1) &&\n      //     StringPrototypeCharCodeAt(hostHeader, 0) !== 91 /* '[' */\n      //   ) {\n      //     hostHeader = `[${hostHeader}]`;\n      //   }\n\n      //   if (port && +port !== defaultPort) {\n      //     hostHeader += \":\" + port;\n      //   }\n      //   this.setHeader(\"Host\", hostHeader);\n      // }\n\n      var auth = options.auth;\n      if (auth && !this.getHeader(\"Authorization\")) {\n        this.setHeader(\"Authorization\", \"Basic \" + Buffer.from(auth).toString(\"base64\"));\n      }\n\n      //   if (this.getHeader(\"expect\")) {\n      //     if (this._header) {\n      //       throw new ERR_HTTP_HEADERS_SENT(\"render\");\n      //     }\n\n      //     this._storeHeader(\n      //       this.method + \" \" + this.path + \" HTTP/1.1\\r\\n\",\n      //       this[kOutHeaders],\n      //     );\n      //   }\n      // } else {\n      //   this._storeHeader(\n      //     this.method + \" \" + this.path + \" HTTP/1.1\\r\\n\",\n      //     options.headers,\n      //   );\n    }\n\n    // this[kUniqueHeaders] = parseUniqueHeadersOption(options.uniqueHeaders);\n\n    var optsWithoutSignal = options;\n    if (optsWithoutSignal.signal) {\n      optsWithoutSignal = ObjectAssign({}, options);\n      delete optsWithoutSignal.signal;\n    }\n    this.#options = optsWithoutSignal;\n\n    var timeout = options.timeout;\n    if (timeout) {\n      this.setTimeout(timeout);\n    }\n  }\n\n  setSocketKeepAlive(enable = true, initialDelay = 0) {\n    __DEBUG__ && debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: ClientRequest.setSocketKeepAlive is a no-op\");\n  }\n\n  setNoDelay(noDelay = true) {\n    __DEBUG__ && debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: ClientRequest.setNoDelay is a no-op\");\n  }\n  [kClearTimeout]() {\n    if (this.#timeoutTimer) {\n      clearTimeout(this.#timeoutTimer);\n      this.#timeoutTimer = null;\n    }\n  }\n\n  setTimeout(msecs, callback) {\n    if (this.#timeoutTimer) return this;\n    if (callback) {\n      this.on(\"timeout\", callback);\n    }\n\n    this.#timeoutTimer = setTimeout(async () => {\n      this.#timeoutTimer = null;\n      this[kAbortController]?.abort();\n      this.emit(\"timeout\");\n    }, msecs);\n\n    return this;\n  }\n}\n\nfunction urlToHttpOptions(url) {\n  var { protocol, hostname, hash, search, pathname, href, port, username, password } = url;\n  return {\n    protocol,\n    hostname:\n      typeof hostname === \"string\" && StringPrototypeStartsWith.call(hostname, \"[\")\n        ? StringPrototypeSlice.call(hostname, 1, -1)\n        : hostname,\n    hash,\n    search,\n    pathname,\n    path: `${pathname || \"\"}${search || \"\"}`,\n    href,\n    port: port ? Number(port) : protocol === \"https:\" ? 443 : protocol === \"http:\" ? 80 : undefined,\n    auth: username || password ? `${decodeURIComponent(username)}:${decodeURIComponent(password)}` : undefined,\n  };\n}\n\nfunction validateHost(host, name) {\n  if (host !== null && host !== undefined && typeof host !== \"string\") {\n    // throw new ERR_INVALID_ARG_TYPE(\n    //   `options.${name}`,\n    //   [\"string\", \"undefined\", \"null\"],\n    //   host,\n    // );\n    throw new Error(\"Invalid arg type in options\");\n  }\n  return host;\n}\n\nconst tokenRegExp = /^[\\^_`a-zA-Z\\-0-9!#$%&'*+.|~]+$/;\n/**\n * Verifies that the given val is a valid HTTP token\n * per the rules defined in RFC 7230\n * See https://tools.ietf.org/html/rfc7230#section-3.2.6\n */\nfunction checkIsHttpToken(val) {\n  return RegExpPrototypeExec.call(tokenRegExp, val) !== null;\n}\n\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nexport const METHODS = [\n  \"ACL\",\n  \"BIND\",\n  \"CHECKOUT\",\n  \"CONNECT\",\n  \"COPY\",\n  \"DELETE\",\n  \"GET\",\n  \"HEAD\",\n  \"LINK\",\n  \"LOCK\",\n  \"M-SEARCH\",\n  \"MERGE\",\n  \"MKACTIVITY\",\n  \"MKCALENDAR\",\n  \"MKCOL\",\n  \"MOVE\",\n  \"NOTIFY\",\n  \"OPTIONS\",\n  \"PATCH\",\n  \"POST\",\n  \"PROPFIND\",\n  \"PROPPATCH\",\n  \"PURGE\",\n  \"PUT\",\n  \"REBIND\",\n  \"REPORT\",\n  \"SEARCH\",\n  \"SOURCE\",\n  \"SUBSCRIBE\",\n  \"TRACE\",\n  \"UNBIND\",\n  \"UNLINK\",\n  \"UNLOCK\",\n  \"UNSUBSCRIBE\",\n];\n\nexport const STATUS_CODES = {\n  100: \"Continue\",\n  101: \"Switching Protocols\",\n  102: \"Processing\",\n  103: \"Early Hints\",\n  200: \"OK\",\n  201: \"Created\",\n  202: \"Accepted\",\n  203: \"Non-Authoritative Information\",\n  204: \"No Content\",\n  205: \"Reset Content\",\n  206: \"Partial Content\",\n  207: \"Multi-Status\",\n  208: \"Already Reported\",\n  226: \"IM Used\",\n  300: \"Multiple Choices\",\n  301: \"Moved Permanently\",\n  302: \"Found\",\n  303: \"See Other\",\n  304: \"Not Modified\",\n  305: \"Use Proxy\",\n  307: \"Temporary Redirect\",\n  308: \"Permanent Redirect\",\n  400: \"Bad Request\",\n  401: \"Unauthorized\",\n  402: \"Payment Required\",\n  403: \"Forbidden\",\n  404: \"Not Found\",\n  405: \"Method Not Allowed\",\n  406: \"Not Acceptable\",\n  407: \"Proxy Authentication Required\",\n  408: \"Request Timeout\",\n  409: \"Conflict\",\n  410: \"Gone\",\n  411: \"Length Required\",\n  412: \"Precondition Failed\",\n  413: \"Payload Too Large\",\n  414: \"URI Too Long\",\n  415: \"Unsupported Media Type\",\n  416: \"Range Not Satisfiable\",\n  417: \"Expectation Failed\",\n  418: \"I'm a Teapot\",\n  421: \"Misdirected Request\",\n  422: \"Unprocessable Entity\",\n  423: \"Locked\",\n  424: \"Failed Dependency\",\n  425: \"Too Early\",\n  426: \"Upgrade Required\",\n  428: \"Precondition Required\",\n  429: \"Too Many Requests\",\n  431: \"Request Header Fields Too Large\",\n  451: \"Unavailable For Legal Reasons\",\n  500: \"Internal Server Error\",\n  501: \"Not Implemented\",\n  502: \"Bad Gateway\",\n  503: \"Service Unavailable\",\n  504: \"Gateway Timeout\",\n  505: \"HTTP Version Not Supported\",\n  506: \"Variant Also Negotiates\",\n  507: \"Insufficient Storage\",\n  508: \"Loop Detected\",\n  509: \"Bandwidth Limit Exceeded\",\n  510: \"Not Extended\",\n  511: \"Network Authentication Required\",\n};\n\nfunction _normalizeArgs(args) {\n  let arr;\n\n  if (args.length === 0) {\n    arr = [{}, null];\n    // arr[normalizedArgsSymbol] = true;\n    return arr;\n  }\n\n  const arg0 = args[0];\n  let options = {};\n  if (typeof arg0 === \"object\" && arg0 !== null) {\n    // (options[...][, cb])\n    options = arg0;\n    // } else if (isPipeName(arg0)) {\n    // (path[...][, cb])\n    // options.path = arg0;\n  } else {\n    // ([port][, host][...][, cb])\n    options.port = arg0;\n    if (args.length > 1 && typeof args[1] === \"string\") {\n      options.host = args[1];\n    }\n  }\n\n  const cb = args[args.length - 1];\n  if (typeof cb !== \"function\") arr = [options, null];\n  else arr = [options, cb];\n\n  // arr[normalizedArgsSymbol] = true;\n  return arr;\n}\n\nfunction _writeHead(statusCode, reason, obj, response) {\n  statusCode |= 0;\n  if (statusCode < 100 || statusCode > 999) {\n    throw new Error(\"status code must be between 100 and 999\");\n  }\n\n  if (typeof reason === \"string\") {\n    // writeHead(statusCode, reasonPhrase[, headers])\n    response.statusMessage = reason;\n  } else {\n    // writeHead(statusCode[, headers])\n    if (!response.statusMessage) response.statusMessage = STATUS_CODES[statusCode] || \"unknown\";\n    obj = reason;\n  }\n  response.statusCode = statusCode;\n\n  {\n    // Slow-case: when progressive API and header fields are passed.\n    let k;\n    if (Array.isArray(obj)) {\n      if (obj.length % 2 !== 0) {\n        throw new Error(\"raw headers must have an even number of elements\");\n      }\n\n      for (let n = 0; n < obj.length; n += 2) {\n        k = obj[n + 0];\n        if (k) response.setHeader(k, obj[n + 1]);\n      }\n    } else if (obj) {\n      const keys = Object.keys(obj);\n      // Retain for(;;) loop for performance reasons\n      // Refs: https://github.com/nodejs/node/pull/30958\n      for (let i = 0; i < keys.length; i++) {\n        k = keys[i];\n        if (k) response.setHeader(k, obj[k]);\n      }\n    }\n  }\n}\n\n/**\n * Makes an HTTP request.\n * @param {string | URL} url\n * @param {HTTPRequestOptions} [options]\n * @param {Function} [cb]\n * @returns {ClientRequest}\n */\nexport function request(url, options, cb) {\n  return new ClientRequest(url, options, cb);\n}\n\n/**\n * Makes a `GET` HTTP request.\n * @param {string | URL} url\n * @param {HTTPRequestOptions} [options]\n * @param {Function} [cb]\n * @returns {ClientRequest}\n */\nexport function get(url, options, cb) {\n  const req = request(url, options, cb);\n  req.end();\n  return req;\n}\n\nvar defaultObject = {\n  Agent,\n  Server,\n  METHODS,\n  STATUS_CODES,\n  createServer,\n  ServerResponse,\n  IncomingMessage,\n  request,\n  get,\n  maxHeaderSize: 16384,\n  // validateHeaderName,\n  // validateHeaderValue,\n  setMaxIdleHTTPParsers(max) {\n    debug(`${NODE_HTTP_WARNING}\\n`, \"setMaxIdleHTTPParsers() is a no-op\");\n  },\n  get globalAgent() {\n    return (_globalAgent ??= new Agent());\n  },\n  set globalAgent(agent) {},\n  [Symbol.for(\"CommonJS\")]: 0,\n};\n\nexport default defaultObject;\n",
  "// Hardcoded module \"node:http\"\nconst { EventEmitter } = import.meta.require(\"node:events\");\nconst { isIPv6 } = import.meta.require(\"node:net\");\nconst { Readable, Writable, Duplex } = import.meta.require(\"node:stream\");\nconst { URL } = import.meta.require(\"node:url\");\nconst { newArrayWithSize, String, Object, Array } = import.meta.primordials;\nconst { isTypedArray } = import.meta.require(\"util/types\");\n\nconst globalReportError = globalThis.reportError;\nconst setTimeout = globalThis.setTimeout;\nconst fetch = Bun.fetch;\nconst nop = () => {};\n\nconst __DEBUG__ = process.env.__DEBUG__;\nconst debug = __DEBUG__ ? (...args) => console.log(\"node:http\", ...args) : nop;\n\nconst kEmptyObject = Object.freeze(Object.create(null));\nconst kOutHeaders = Symbol.for(\"kOutHeaders\");\nconst kEndCalled = Symbol.for(\"kEndCalled\");\nconst kAbortController = Symbol.for(\"kAbortController\");\nconst kClearTimeout = Symbol(\"kClearTimeout\");\n\nconst kCorked = Symbol.for(\"kCorked\");\nconst searchParamsSymbol = Symbol.for(\"query\"); // This is the symbol used in Node\n\n// Primordials\nconst StringPrototypeSlice = String.prototype.slice;\nconst StringPrototypeStartsWith = String.prototype.startsWith;\nconst StringPrototypeToUpperCase = String.prototype.toUpperCase;\nconst StringPrototypeIncludes = String.prototype.includes;\nconst StringPrototypeCharCodeAt = String.prototype.charCodeAt;\nconst StringPrototypeIndexOf = String.prototype.indexOf;\nconst ArrayIsArray = Array.isArray;\nconst RegExpPrototypeExec = RegExp.prototype.exec;\nconst ObjectAssign = Object.assign;\nconst ObjectPrototypeHasOwnProperty = Object.prototype.hasOwnProperty;\n\nconst INVALID_PATH_REGEX = /[^\\u0021-\\u00ff]/;\nconst NODE_HTTP_WARNING =\n  \"WARN: Agent is mostly unused in Bun's implementation of http. If you see strange behavior, this is probably the cause.\";\n\nvar _globalAgent;\nvar _defaultHTTPSAgent;\nvar kInternalRequest = Symbol(\"kInternalRequest\");\nvar kInternalSocketData = Symbol.for(\"::bunternal::\");\n\nconst kEmptyBuffer = Buffer.alloc(0);\n\nfunction isValidTLSArray(obj) {\n  if (typeof obj === \"string\" || isTypedArray(obj) || obj instanceof ArrayBuffer || obj instanceof Blob) return true;\n  if (Array.isArray(obj)) {\n    for (var i = 0; i < obj.length; i++) {\n      if (typeof obj !== \"string\" && !isTypedArray(obj) && !(obj instanceof ArrayBuffer) && !(obj instanceof Blob))\n        return false;\n    }\n    return true;\n  }\n}\n\nfunction getHeader(headers, name) {\n  if (!headers) return;\n  const result = headers.get(name);\n  return result == null ? undefined : result;\n}\n\nvar FakeSocket = class Socket extends Duplex {\n  bytesRead = 0;\n  bytesWritten = 0;\n  connecting = false;\n  remoteAddress = null;\n  localAddress = \"127.0.0.1\";\n  remotePort;\n  timeout = 0;\n\n  isServer = false;\n\n  address() {\n    return {\n      address: this.localAddress,\n      family: this.localFamily,\n      port: this.localPort,\n    };\n  }\n\n  get bufferSize() {\n    return this.writableLength;\n  }\n\n  connect(port, host, connectListener) {\n    return this;\n  }\n\n  _destroy(err, callback) {}\n\n  _final(callback) {}\n\n  get localAddress() {\n    return \"127.0.0.1\";\n  }\n\n  get localFamily() {\n    return \"IPv4\";\n  }\n\n  get localPort() {\n    return 80;\n  }\n\n  get pending() {\n    return this.connecting;\n  }\n\n  _read(size) {}\n\n  get readyState() {\n    if (this.connecting) return \"opening\";\n    if (this.readable) {\n      return this.writable ? \"open\" : \"readOnly\";\n    } else {\n      return this.writable ? \"writeOnly\" : \"closed\";\n    }\n  }\n\n  ref() {}\n\n  get remoteFamily() {\n    return \"IPv4\";\n  }\n\n  resetAndDestroy() {}\n\n  setKeepAlive(enable = false, initialDelay = 0) {}\n\n  setNoDelay(noDelay = true) {\n    return this;\n  }\n\n  setTimeout(timeout, callback) {\n    return this;\n  }\n\n  unref() {}\n\n  _write(chunk, encoding, callback) {}\n};\n\nexport function createServer(options, callback) {\n  return new Server(options, callback);\n}\n\nexport class Agent extends EventEmitter {\n  #defaultPort = 80;\n  #protocol = \"http:\";\n  #options;\n  #requests;\n  #sockets;\n  #freeSockets;\n\n  #keepAliveMsecs;\n  #keepAlive;\n  #maxSockets;\n  #maxFreeSockets;\n  #scheduling;\n  #maxTotalSockets;\n  #totalSocketCount;\n\n  #fakeSocket;\n\n  static get globalAgent() {\n    return (_globalAgent ??= new Agent());\n  }\n\n  static get defaultMaxSockets() {\n    return Infinity;\n  }\n\n  constructor(options = kEmptyObject) {\n    super();\n    this.#options = options = { ...options, path: null };\n    if (options.noDelay === undefined) options.noDelay = true;\n\n    // Don't confuse net and make it think that we're connecting to a pipe\n    this.#requests = kEmptyObject;\n    this.#sockets = kEmptyObject;\n    this.#freeSockets = kEmptyObject;\n\n    this.#keepAliveMsecs = options.keepAliveMsecs || 1000;\n    this.#keepAlive = options.keepAlive || false;\n    this.#maxSockets = options.maxSockets || Agent.defaultMaxSockets;\n    this.#maxFreeSockets = options.maxFreeSockets || 256;\n    this.#scheduling = options.scheduling || \"lifo\";\n    this.#maxTotalSockets = options.maxTotalSockets;\n    this.#totalSocketCount = 0;\n    this.#defaultPort = options.defaultPort || 80;\n    this.#protocol = options.protocol || \"http:\";\n  }\n\n  get defaultPort() {\n    return this.#defaultPort;\n  }\n\n  get protocol() {\n    return this.#protocol;\n  }\n\n  get requests() {\n    return this.#requests;\n  }\n\n  get sockets() {\n    return this.#sockets;\n  }\n\n  get freeSockets() {\n    return this.#freeSockets;\n  }\n\n  get options() {\n    return this.#options;\n  }\n\n  get keepAliveMsecs() {\n    return this.#keepAliveMsecs;\n  }\n\n  get keepAlive() {\n    return this.#keepAlive;\n  }\n\n  get maxSockets() {\n    return this.#maxSockets;\n  }\n\n  get maxFreeSockets() {\n    return this.#maxFreeSockets;\n  }\n\n  get scheduling() {\n    return this.#scheduling;\n  }\n\n  get maxTotalSockets() {\n    return this.#maxTotalSockets;\n  }\n\n  get totalSocketCount() {\n    return this.#totalSocketCount;\n  }\n\n  createConnection() {\n    debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: Agent.createConnection is a no-op, returns fake socket\");\n    return (this.#fakeSocket ??= new FakeSocket());\n  }\n\n  getName(options = kEmptyObject) {\n    let name = `http:${options.host || \"localhost\"}:`;\n    if (options.port) name += options.port;\n    name += \":\";\n    if (options.localAddress) name += options.localAddress;\n    // Pacify parallel/test-http-agent-getname by only appending\n    // the ':' when options.family is set.\n    if (options.family === 4 || options.family === 6) name += `:${options.family}`;\n    if (options.socketPath) name += `:${options.socketPath}`;\n    return name;\n  }\n\n  addRequest() {\n    debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: Agent.addRequest is a no-op\");\n  }\n\n  createSocket(req, options, cb) {\n    debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: Agent.createSocket returns fake socket\");\n    cb(null, (this.#fakeSocket ??= new FakeSocket()));\n  }\n\n  removeSocket() {\n    debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: Agent.removeSocket is a no-op\");\n  }\n\n  keepSocketAlive() {\n    debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: Agent.keepSocketAlive is a no-op\");\n\n    return true;\n  }\n\n  reuseSocket() {\n    debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: Agent.reuseSocket is a no-op\");\n  }\n\n  destroy() {\n    debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: Agent.destroy is a no-op\");\n  }\n}\nfunction emitListeningNextTick(self, onListen, err, hostname, port) {\n  if (typeof onListen === \"function\") {\n    try {\n      onListen(err, hostname, port);\n    } catch (err) {\n      self.emit(\"error\", err);\n    }\n  }\n\n  self.listening = !err;\n\n  if (err) {\n    self.emit(\"error\", err);\n  } else {\n    self.emit(\"listening\", hostname, port);\n  }\n}\n\nexport class Server extends EventEmitter {\n  #server;\n  #options;\n  #tls;\n  #is_tls = false;\n  listening = false;\n\n  constructor(options, callback) {\n    super();\n\n    if (typeof options === \"function\") {\n      callback = options;\n      options = {};\n    } else if (options == null || typeof options === \"object\") {\n      options = { ...options };\n      this.#tls = null;\n      let key = options.key;\n      if (key) {\n        if (!isValidTLSArray(key)) {\n          throw new TypeError(\n            \"key argument must be an string, Buffer, TypedArray, BunFile or an array containing string, Buffer, TypedArray or BunFile\",\n          );\n        }\n        this.#is_tls = true;\n      }\n      let cert = options.cert;\n      if (cert) {\n        if (!isValidTLSArray(cert)) {\n          throw new TypeError(\n            \"cert argument must be an string, Buffer, TypedArray, BunFile or an array containing string, Buffer, TypedArray or BunFile\",\n          );\n        }\n        this.#is_tls = true;\n      }\n\n      let ca = options.ca;\n      if (ca) {\n        if (!isValidTLSArray(ca)) {\n          throw new TypeError(\n            \"ca argument must be an string, Buffer, TypedArray, BunFile or an array containing string, Buffer, TypedArray or BunFile\",\n          );\n        }\n        this.#is_tls = true;\n      }\n      let passphrase = options.passphrase;\n      if (passphrase && typeof passphrase !== \"string\") {\n        throw new TypeError(\"passphrase argument must be an string\");\n      }\n\n      let serverName = options.servername;\n      if (serverName && typeof serverName !== \"string\") {\n        throw new TypeError(\"servername argument must be an string\");\n      }\n\n      let secureOptions = options.secureOptions || 0;\n      if (secureOptions && typeof secureOptions !== \"number\") {\n        throw new TypeError(\"secureOptions argument must be an number\");\n      }\n\n      if (this.#is_tls) {\n        this.#tls = {\n          serverName,\n          key: key,\n          cert: cert,\n          ca: ca,\n          passphrase: passphrase,\n          secureOptions: secureOptions,\n        };\n      } else {\n        this.#tls = null;\n      }\n    } else {\n      throw new Error(\"bun-http-polyfill: invalid arguments\");\n    }\n\n    this.#options = options;\n\n    if (callback) this.on(\"request\", callback);\n  }\n\n  closeAllConnections() {\n    const server = this.#server;\n    if (!server) {\n      return;\n    }\n    this.#server = undefined;\n    server.stop(true);\n    this.emit(\"close\");\n  }\n\n  closeIdleConnections() {\n    // not actually implemented\n  }\n\n  close(optionalCallback) {\n    const server = this.#server;\n    if (!server) {\n      if (typeof optionalCallback === \"function\")\n        process.nextTick(optionalCallback, new Error(\"Server is not running\"));\n      return;\n    }\n    this.#server = undefined;\n    if (typeof optionalCallback === \"function\") this.once(\"close\", optionalCallback);\n    server.stop();\n    this.emit(\"close\");\n  }\n\n  address() {\n    if (!this.#server) return null;\n\n    const address = this.#server.hostname;\n    return {\n      address,\n      family: isIPv6(address) ? \"IPv6\" : \"IPv4\",\n      port: this.#server.port,\n    };\n  }\n\n  listen(port, host, backlog, onListen) {\n    const server = this;\n    if (typeof host === \"function\") {\n      onListen = host;\n      host = undefined;\n    }\n\n    if (typeof port === \"function\") {\n      onListen = port;\n    } else if (typeof port === \"object\") {\n      port?.signal?.addEventListener(\"abort\", () => {\n        this.close();\n      });\n\n      host = port?.host;\n      port = port?.port;\n\n      if (typeof port?.callback === \"function\") onListen = port?.callback;\n    }\n\n    if (typeof backlog === \"function\") {\n      onListen = backlog;\n    }\n\n    const ResponseClass = this.#options.ServerResponse || ServerResponse;\n    const RequestClass = this.#options.IncomingMessage || IncomingMessage;\n\n    try {\n      const tls = this.#tls;\n      if (tls) {\n        this.serverName = tls.serverName || host || \"localhost\";\n      }\n      this.#server = Bun.serve({\n        tls,\n        port,\n        hostname: host,\n        // Bindings to be used for WS Server\n        websocket: {\n          open(ws) {\n            ws.data.open(ws);\n          },\n          message(ws, message) {\n            ws.data.message(ws, message);\n          },\n          close(ws, code, reason) {\n            ws.data.close(ws, code, reason);\n          },\n          drain(ws) {\n            ws.data.drain(ws);\n          },\n        },\n        fetch(req, _server) {\n          var pendingResponse;\n          var pendingError;\n          var rejectFunction, resolveFunction;\n          var reject = err => {\n            if (pendingError) return;\n            pendingError = err;\n            if (rejectFunction) rejectFunction(err);\n          };\n\n          var reply = function (resp) {\n            if (pendingResponse) return;\n            pendingResponse = resp;\n            if (resolveFunction) resolveFunction(resp);\n          };\n\n          const http_req = new RequestClass(req);\n          const http_res = new ResponseClass({ reply, req: http_req });\n\n          http_req.once(\"error\", err => reject(err));\n          http_res.once(\"error\", err => reject(err));\n\n          const upgrade = req.headers.get(\"upgrade\");\n          if (upgrade) {\n            const socket = new FakeSocket();\n            socket[kInternalSocketData] = [_server, http_res, req];\n            server.emit(\"upgrade\", http_req, socket, kEmptyBuffer);\n          } else {\n            server.emit(\"request\", http_req, http_res);\n          }\n\n          if (pendingError) {\n            throw pendingError;\n          }\n\n          if (pendingResponse) {\n            return pendingResponse;\n          }\n\n          return new Promise((resolve, reject) => {\n            resolveFunction = resolve;\n            rejectFunction = reject;\n          });\n        },\n      });\n      setTimeout(emitListeningNextTick, 1, this, onListen, null, this.#server.hostname, this.#server.port);\n    } catch (err) {\n      setTimeout(emitListeningNextTick, 1, this, onListen, err);\n    }\n\n    return this;\n  }\n  setTimeout(msecs, callback) {}\n}\n\nfunction assignHeaders(object, req) {\n  var headers = req.headers.toJSON();\n  const rawHeaders = newArrayWithSize(req.headers.count * 2);\n  var i = 0;\n  for (const key in headers) {\n    rawHeaders[i++] = key;\n    rawHeaders[i++] = headers[key];\n  }\n  object.headers = headers;\n  object.rawHeaders = rawHeaders;\n}\nfunction destroyBodyStreamNT(bodyStream) {\n  bodyStream.destroy();\n}\n\nvar defaultIncomingOpts = { type: \"request\" };\n\nfunction getDefaultHTTPSAgent() {\n  return (_defaultHTTPSAgent ??= new Agent({ defaultPort: 443, protocol: \"https:\" }));\n}\n\nexport class IncomingMessage extends Readable {\n  constructor(req, defaultIncomingOpts) {\n    const method = req.method;\n\n    super();\n\n    const url = new URL(req.url);\n\n    var { type = \"request\", [kInternalRequest]: nodeReq } = defaultIncomingOpts || {};\n\n    this.#noBody =\n      type === \"request\" // TODO: Add logic for checking for body on response\n        ? \"GET\" === method ||\n          \"HEAD\" === method ||\n          \"TRACE\" === method ||\n          \"CONNECT\" === method ||\n          \"OPTIONS\" === method ||\n          (parseInt(req.headers.get(\"Content-Length\") || \"\") || 0) === 0\n        : false;\n\n    this.#req = req;\n    this.method = method;\n    this.#type = type;\n    this.complete = !!this.#noBody;\n\n    this.#bodyStream = null;\n    const socket = new FakeSocket();\n    socket.remoteAddress = url.hostname;\n    socket.remotePort = url.port;\n    this.#fakeSocket = socket;\n\n    this.url = url.pathname + url.search;\n    this.#nodeReq = nodeReq;\n    assignHeaders(this, req);\n  }\n\n  headers;\n  rawHeaders;\n  _consuming = false;\n  _dumped = false;\n  #bodyStream = null;\n  #fakeSocket = undefined;\n  #noBody = false;\n  #aborted = false;\n  #req;\n  url;\n  #type;\n  #nodeReq;\n\n  get req() {\n    return this.#nodeReq;\n  }\n\n  _construct(callback) {\n    // TODO: streaming\n    if (this.#type === \"response\" || this.#noBody) {\n      callback();\n      return;\n    }\n\n    const contentLength = this.#req.headers.get(\"content-length\");\n    const length = contentLength ? parseInt(contentLength, 10) : 0;\n    if (length === 0) {\n      this.#noBody = true;\n      callback();\n      return;\n    }\n\n    callback();\n  }\n\n  #closeBodyStream() {\n    debug(\"closeBodyStream()\");\n    var bodyStream = this.#bodyStream;\n    if (bodyStream == null) return;\n    this.complete = true;\n    this.#bodyStream = undefined;\n    this.push(null);\n    // process.nextTick(destroyBodyStreamNT, bodyStream);\n  }\n\n  _read(size) {\n    if (this.#noBody) {\n      this.push(null);\n      this.complete = true;\n    } else if (this.#bodyStream == null) {\n      const contentLength = this.#req.headers.get(\"content-length\");\n      let remaining = contentLength ? parseInt(contentLength, 10) : 0;\n      this.#bodyStream = Readable.fromWeb(this.#req.body, {\n        highWaterMark: Number.isFinite(remaining) ? Math.min(remaining, 16384) : 16384,\n      });\n\n      const isBodySizeKnown = remaining > 0 && Number.isSafeInteger(remaining);\n\n      if (isBodySizeKnown) {\n        this.#bodyStream.on(\"data\", chunk => {\n          debug(\"body size known\", remaining);\n          this.push(chunk);\n          // when we are streaming a known body size, automatically close the stream when we have read enough\n          remaining -= chunk?.byteLength ?? 0;\n          if (remaining <= 0) {\n            this.#closeBodyStream();\n          }\n        });\n      } else {\n        this.#bodyStream.on(\"data\", chunk => {\n          this.push(chunk);\n        });\n      }\n\n      // this can be closed by the time we get here if enough data was synchronously available\n      this.#bodyStream &&\n        this.#bodyStream.on(\"end\", () => {\n          this.#closeBodyStream();\n        });\n    } else {\n      // this.#bodyStream.read(size);\n    }\n  }\n\n  get aborted() {\n    return this.#aborted;\n  }\n\n  abort() {\n    if (this.#aborted) return;\n    this.#aborted = true;\n\n    this.#closeBodyStream();\n  }\n\n  get connection() {\n    return this.#fakeSocket;\n  }\n\n  get statusCode() {\n    return this.#req.status;\n  }\n\n  get statusMessage() {\n    return STATUS_CODES[this.#req.status];\n  }\n\n  get httpVersion() {\n    return \"1.1\";\n  }\n\n  get rawTrailers() {\n    return [];\n  }\n\n  get httpVersionMajor() {\n    return 1;\n  }\n\n  get httpVersionMinor() {\n    return 1;\n  }\n\n  get trailers() {\n    return kEmptyObject;\n  }\n\n  get socket() {\n    return (this.#fakeSocket ??= new FakeSocket());\n  }\n\n  set socket(val) {\n    this.#fakeSocket = val;\n  }\n\n  setTimeout(msecs, callback) {\n    throw new Error(\"not implemented\");\n  }\n}\n\nfunction emitErrorNt(msg, err, callback) {\n  callback(err);\n  if (typeof msg.emit === \"function\" && !msg._closed) {\n    msg.emit(\"error\", err);\n  }\n}\n\nfunction onError(self, err, cb) {\n  process.nextTick(() => emitErrorNt(self, err, cb));\n}\n\nfunction write_(msg, chunk, encoding, callback, fromEnd) {\n  if (typeof callback !== \"function\") callback = nop;\n\n  let len;\n  if (chunk === null) {\n    // throw new ERR_STREAM_NULL_VALUES();\n    throw new Error(\"ERR_STREAM_NULL_VALUES\");\n  } else if (typeof chunk === \"string\") {\n    len = Buffer.byteLength(chunk, encoding);\n  } else {\n    throw new Error(\"Invalid arg type for chunk\");\n    // throw new ERR_INVALID_ARG_TYPE(\n    //   \"chunk\",\n    //   [\"string\", \"Buffer\", \"Uint8Array\"],\n    //   chunk,\n    // );\n  }\n\n  let err;\n  if (msg.finished) {\n    // err = new ERR_STREAM_WRITE_AFTER_END();\n    err = new Error(\"ERR_STREAM_WRITE_AFTER_END\");\n  } else if (msg.destroyed) {\n    // err = new ERR_STREAM_DESTROYED(\"write\");\n    err = new Error(\"ERR_STREAM_DESTROYED\");\n  }\n\n  if (err) {\n    if (!msg.destroyed) {\n      onError(msg, err, callback);\n    } else {\n      process.nextTick(callback, err);\n    }\n    return false;\n  }\n\n  if (!msg._header) {\n    if (fromEnd) {\n      msg._contentLength = len;\n    }\n    // msg._implicitHeader();\n  }\n\n  if (!msg._hasBody) {\n    debug(\"This type of response MUST NOT have a body. \" + \"Ignoring write() calls.\");\n    process.nextTick(callback);\n    return true;\n  }\n\n  // if (!fromEnd && msg.socket && !msg.socket.writableCorked) {\n  //   msg.socket.cork();\n  //   process.nextTick(connectionCorkNT, msg.socket);\n  // }\n\n  return true;\n}\n\nexport class OutgoingMessage extends Writable {\n  #headers;\n  headersSent = false;\n  sendDate = true;\n  req;\n\n  #finished = false;\n  [kEndCalled] = false;\n\n  #fakeSocket;\n  #timeoutTimer = null;\n  [kAbortController] = null;\n\n  // For compat with IncomingRequest\n  get headers() {\n    if (!this.#headers) return kEmptyObject;\n    return this.#headers.toJSON();\n  }\n\n  get shouldKeepAlive() {\n    return true;\n  }\n\n  get chunkedEncoding() {\n    return false;\n  }\n\n  set chunkedEncoding(value) {\n    // throw new Error('not implemented');\n  }\n\n  set shouldKeepAlive(value) {\n    // throw new Error('not implemented');\n  }\n\n  get useChunkedEncodingByDefault() {\n    return true;\n  }\n\n  set useChunkedEncodingByDefault(value) {\n    // throw new Error('not implemented');\n  }\n\n  get socket() {\n    return (this.#fakeSocket ??= new FakeSocket());\n  }\n\n  set socket(val) {\n    this.#fakeSocket = val;\n  }\n\n  get connection() {\n    return this.socket;\n  }\n\n  get finished() {\n    return this.#finished;\n  }\n\n  appendHeader(name, value) {\n    var headers = (this.#headers ??= new Headers());\n    headers.append(name, value);\n  }\n\n  flushHeaders() {}\n\n  getHeader(name) {\n    return getHeader(this.#headers, name);\n  }\n\n  getHeaders() {\n    if (!this.#headers) return kEmptyObject;\n    return this.#headers.toJSON();\n  }\n\n  getHeaderNames() {\n    var headers = this.#headers;\n    if (!headers) return [];\n    return Array.from(headers.keys());\n  }\n\n  removeHeader(name) {\n    if (!this.#headers) return;\n    this.#headers.delete(name);\n  }\n\n  setHeader(name, value) {\n    var headers = (this.#headers ??= new Headers());\n    headers.set(name, value);\n    return this;\n  }\n\n  hasHeader(name) {\n    if (!this.#headers) return false;\n    return this.#headers.has(name);\n  }\n\n  addTrailers(headers) {\n    throw new Error(\"not implemented\");\n  }\n\n  [kClearTimeout]() {\n    if (this.#timeoutTimer) {\n      clearTimeout(this.#timeoutTimer);\n      this.#timeoutTimer = null;\n    }\n  }\n\n  setTimeout(msecs, callback) {\n    if (this.#timeoutTimer) return this;\n    if (callback) {\n      this.on(\"timeout\", callback);\n    }\n\n    this.#timeoutTimer = setTimeout(async () => {\n      this.#timeoutTimer = null;\n      this[kAbortController]?.abort();\n      this.emit(\"timeout\");\n    }, msecs);\n\n    return this;\n  }\n}\n\nexport class ServerResponse extends Writable {\n  constructor({ req, reply }) {\n    super();\n    this.req = req;\n    this._reply = reply;\n    this.sendDate = true;\n    this.statusCode = 200;\n    this.headersSent = false;\n    this.statusMessage = undefined;\n    this.#controller = undefined;\n    this.#firstWrite = undefined;\n    this._writableState.decodeStrings = false;\n    this.#deferred = undefined;\n  }\n\n  req;\n  _reply;\n  sendDate;\n  statusCode;\n  #headers;\n  headersSent = false;\n  statusMessage;\n  #controller;\n  #firstWrite;\n  _sent100 = false;\n  _defaultKeepAlive = false;\n  _removedConnection = false;\n  _removedContLen = false;\n  #deferred = undefined;\n  #finished = false;\n\n  _write(chunk, encoding, callback) {\n    if (!this.#firstWrite && !this.headersSent) {\n      this.#firstWrite = chunk;\n      callback();\n      return;\n    }\n\n    this.#ensureReadableStreamController(controller => {\n      controller.write(chunk);\n      callback();\n    });\n  }\n\n  _writev(chunks, callback) {\n    if (chunks.length === 1 && !this.headersSent && !this.#firstWrite) {\n      this.#firstWrite = chunks[0].chunk;\n      callback();\n      return;\n    }\n\n    this.#ensureReadableStreamController(controller => {\n      for (const chunk of chunks) {\n        controller.write(chunk.chunk);\n      }\n\n      callback();\n    });\n  }\n\n  #ensureReadableStreamController(run) {\n    var thisController = this.#controller;\n    if (thisController) return run(thisController);\n    this.headersSent = true;\n    var firstWrite = this.#firstWrite;\n    this.#firstWrite = undefined;\n    this._reply(\n      new Response(\n        new ReadableStream({\n          type: \"direct\",\n          pull: controller => {\n            this.#controller = controller;\n            if (firstWrite) controller.write(firstWrite);\n            firstWrite = undefined;\n            run(controller);\n            if (!this.#finished) {\n              return new Promise(resolve => {\n                this.#deferred = resolve;\n              });\n            }\n          },\n        }),\n        {\n          headers: this.#headers,\n          status: this.statusCode,\n          statusText: this.statusMessage ?? STATUS_CODES[this.statusCode],\n        },\n      ),\n    );\n  }\n\n  _final(callback) {\n    if (!this.headersSent) {\n      var data = this.#firstWrite || \"\";\n      this.#firstWrite = undefined;\n      this.#finished = true;\n      this._reply(\n        new Response(data, {\n          headers: this.#headers,\n          status: this.statusCode,\n          statusText: this.statusMessage ?? STATUS_CODES[this.statusCode],\n        }),\n      );\n      callback && callback();\n      return;\n    }\n\n    this.#finished = true;\n    this.#ensureReadableStreamController(controller => {\n      controller.end();\n\n      callback();\n      var deferred = this.#deferred;\n      if (deferred) {\n        this.#deferred = undefined;\n        deferred();\n      }\n    });\n  }\n\n  writeProcessing() {\n    throw new Error(\"not implemented\");\n  }\n\n  addTrailers(headers) {\n    throw new Error(\"not implemented\");\n  }\n\n  assignSocket(socket) {\n    throw new Error(\"not implemented\");\n  }\n\n  detachSocket(socket) {\n    throw new Error(\"not implemented\");\n  }\n\n  writeContinue(callback) {\n    throw new Error(\"not implemented\");\n  }\n\n  setTimeout(msecs, callback) {\n    throw new Error(\"not implemented\");\n  }\n\n  get shouldKeepAlive() {\n    return true;\n  }\n\n  get chunkedEncoding() {\n    return false;\n  }\n\n  set chunkedEncoding(value) {\n    // throw new Error('not implemented');\n  }\n\n  set shouldKeepAlive(value) {\n    // throw new Error('not implemented');\n  }\n\n  get useChunkedEncodingByDefault() {\n    return true;\n  }\n\n  set useChunkedEncodingByDefault(value) {\n    // throw new Error('not implemented');\n  }\n\n  appendHeader(name, value) {\n    var headers = (this.#headers ??= new Headers());\n    headers.append(name, value);\n  }\n\n  flushHeaders() {}\n\n  getHeader(name) {\n    return getHeader(this.#headers, name);\n  }\n\n  getHeaders() {\n    var headers = this.#headers;\n    if (!headers) return kEmptyObject;\n    return headers.toJSON();\n  }\n\n  getHeaderNames() {\n    var headers = this.#headers;\n    if (!headers) return [];\n    return Array.from(headers.keys());\n  }\n\n  removeHeader(name) {\n    if (!this.#headers) return;\n    this.#headers.delete(name);\n  }\n\n  setHeader(name, value) {\n    var headers = (this.#headers ??= new Headers());\n    headers.set(name, value);\n    return this;\n  }\n\n  hasHeader(name) {\n    if (!this.#headers) return false;\n    return this.#headers.has(name);\n  }\n\n  writeHead(statusCode, statusMessage, headers) {\n    _writeHead(statusCode, statusMessage, headers, this);\n\n    return this;\n  }\n}\n\nexport class ClientRequest extends OutgoingMessage {\n  #timeout;\n  #res = null;\n  #upgradeOrConnect = false;\n  #parser = null;\n  #maxHeadersCount = null;\n  #reusedSocket = false;\n  #host;\n  #protocol;\n  #method;\n  #port;\n  #useDefaultPort;\n  #joinDuplicateHeaders;\n  #maxHeaderSize;\n  #agent = _globalAgent;\n  #path;\n  #socketPath;\n\n  #body = null;\n  #fetchRequest;\n  #signal = null;\n  [kAbortController] = null;\n  #timeoutTimer = null;\n  #options;\n  #finished;\n\n  get path() {\n    return this.#path;\n  }\n\n  get port() {\n    return this.#port;\n  }\n\n  get method() {\n    return this.#method;\n  }\n\n  get host() {\n    return this.#host;\n  }\n\n  get protocol() {\n    return this.#protocol;\n  }\n\n  _write(chunk, encoding, callback) {\n    var body = this.#body;\n    if (!body) {\n      this.#body = chunk;\n      callback();\n      return;\n    }\n    this.#body = body + chunk;\n    callback();\n  }\n\n  _writev(chunks, callback) {\n    var body = this.#body;\n    if (!body) {\n      this.#body = chunks.join();\n      callback();\n      return;\n    }\n    this.#body = body + chunks.join();\n    callback();\n  }\n\n  _final(callback) {\n    this.#finished = true;\n    this[kAbortController] = new AbortController();\n    this[kAbortController].signal.addEventListener(\"abort\", () => {\n      this[kClearTimeout]();\n    });\n    if (this.#signal?.aborted) {\n      this[kAbortController].abort();\n    }\n\n    var method = this.#method,\n      body = this.#body;\n\n    try {\n      this.#fetchRequest = fetch(\n        `${this.#protocol}//${this.#host}${this.#useDefaultPort ? \"\" : \":\" + this.#port}${this.#path}`,\n        {\n          method,\n          headers: this.getHeaders(),\n          body: body && method !== \"GET\" && method !== \"HEAD\" && method !== \"OPTIONS\" ? body : undefined,\n          redirect: \"manual\",\n          verbose: Boolean(__DEBUG__),\n          signal: this[kAbortController].signal,\n        },\n      )\n        .then(response => {\n          var res = (this.#res = new IncomingMessage(response, {\n            type: \"response\",\n            [kInternalRequest]: this,\n          }));\n          this.emit(\"response\", res);\n        })\n        .catch(err => {\n          if (__DEBUG__) globalReportError(err);\n          this.emit(\"error\", err);\n        })\n        .finally(() => {\n          this.#fetchRequest = null;\n          this[kClearTimeout]();\n        });\n    } catch (err) {\n      if (__DEBUG__) globalReportError(err);\n      this.emit(\"error\", err);\n    } finally {\n      callback();\n    }\n  }\n\n  get aborted() {\n    return this.#signal?.aborted || !!this[kAbortController]?.signal.aborted;\n  }\n\n  abort() {\n    if (this.aborted) return;\n    this[kAbortController].abort();\n    // TODO: Close stream if body streaming\n  }\n\n  constructor(input, options, cb) {\n    super();\n\n    if (typeof input === \"string\") {\n      const urlStr = input;\n      try {\n        var urlObject = new URL(urlStr);\n      } catch (e) {\n        throw new TypeError(`Invalid URL: ${urlStr}`);\n      }\n      input = urlToHttpOptions(urlObject);\n    } else if (input && typeof input === \"object\" && input instanceof URL) {\n      // url.URL instance\n      input = urlToHttpOptions(input);\n    } else {\n      cb = options;\n      options = input;\n      input = null;\n    }\n\n    if (typeof options === \"function\") {\n      cb = options;\n      options = input || kEmptyObject;\n    } else {\n      options = ObjectAssign(input || {}, options);\n    }\n\n    var defaultAgent = options._defaultAgent || Agent.globalAgent;\n\n    let protocol = options.protocol;\n    if (!protocol) {\n      if (options.port === 443) {\n        protocol = \"https:\";\n      } else {\n        protocol = defaultAgent.protocol || \"http:\";\n      }\n      this.#protocol = protocol;\n    }\n\n    switch (this.#agent?.protocol) {\n      case undefined: {\n        break;\n      }\n      case \"http:\": {\n        if (protocol === \"https:\") {\n          defaultAgent = this.#agent = getDefaultHTTPSAgent();\n          break;\n        }\n      }\n      case \"https:\": {\n        if (protocol === \"https\") {\n          defaultAgent = this.#agent = Agent.globalAgent;\n          break;\n        }\n      }\n      default: {\n        break;\n      }\n    }\n\n    if (options.path) {\n      const path = String(options.path);\n      if (RegExpPrototypeExec.call(INVALID_PATH_REGEX, path) !== null) {\n        debug('Path contains unescaped characters: \"%s\"', path);\n        throw new Error(\"Path contains unescaped characters\");\n        // throw new ERR_UNESCAPED_CHARACTERS(\"Request path\");\n      }\n    }\n\n    // Since we don't implement Agent, we don't need this\n    if (protocol !== \"http:\" && protocol !== \"https:\" && protocol) {\n      const expectedProtocol = defaultAgent?.protocol ?? \"http:\";\n      throw new Error(`Protocol mismatch. Expected: ${expectedProtocol}. Got: ${protocol}`);\n      // throw new ERR_INVALID_PROTOCOL(protocol, expectedProtocol);\n    }\n\n    const defaultPort = protocol === \"https:\" ? 443 : 80;\n\n    this.#port = options.port || options.defaultPort || this.#agent?.defaultPort || defaultPort;\n    this.#useDefaultPort = this.#port === defaultPort;\n    const host =\n      (this.#host =\n      options.host =\n        validateHost(options.hostname, \"hostname\") || validateHost(options.host, \"host\") || \"localhost\");\n\n    // const setHost = options.setHost === undefined || Boolean(options.setHost);\n\n    this.#socketPath = options.socketPath;\n\n    if (options.timeout !== undefined) this.setTimeout(options.timeout, null);\n\n    const signal = options.signal;\n    if (signal) {\n      //We still want to control abort function and timeout so signal call our AbortController\n      signal.addEventListener(\"abort\", () => {\n        this[kAbortController]?.abort();\n      });\n      this.#signal = signal;\n    }\n    let method = options.method;\n    const methodIsString = typeof method === \"string\";\n    if (method !== null && method !== undefined && !methodIsString) {\n      // throw new ERR_INVALID_ARG_TYPE(\"options.method\", \"string\", method);\n      throw new Error(\"ERR_INVALID_ARG_TYPE: options.method\");\n    }\n\n    if (methodIsString && method) {\n      if (!checkIsHttpToken(method)) {\n        // throw new ERR_INVALID_HTTP_TOKEN(\"Method\", method);\n        throw new Error(\"ERR_INVALID_HTTP_TOKEN: Method\");\n      }\n      method = this.#method = StringPrototypeToUpperCase.call(method);\n    } else {\n      method = this.#method = \"GET\";\n    }\n\n    const _maxHeaderSize = options.maxHeaderSize;\n    // TODO: Validators\n    // if (maxHeaderSize !== undefined)\n    //   validateInteger(maxHeaderSize, \"maxHeaderSize\", 0);\n    this.#maxHeaderSize = _maxHeaderSize;\n\n    // const insecureHTTPParser = options.insecureHTTPParser;\n    // if (insecureHTTPParser !== undefined) {\n    //   validateBoolean(insecureHTTPParser, 'options.insecureHTTPParser');\n    // }\n\n    // this.insecureHTTPParser = insecureHTTPParser;\n    var _joinDuplicateHeaders = options.joinDuplicateHeaders;\n    if (_joinDuplicateHeaders !== undefined) {\n      // TODO: Validators\n      // validateBoolean(\n      //   options.joinDuplicateHeaders,\n      //   \"options.joinDuplicateHeaders\",\n      // );\n    }\n\n    this.#joinDuplicateHeaders = _joinDuplicateHeaders;\n\n    this.#path = options.path || \"/\";\n    if (cb) {\n      this.once(\"response\", cb);\n    }\n\n    __DEBUG__ &&\n      debug(`new ClientRequest: ${this.#method} ${this.#protocol}//${this.#host}:${this.#port}${this.#path}`);\n\n    // if (\n    //   method === \"GET\" ||\n    //   method === \"HEAD\" ||\n    //   method === \"DELETE\" ||\n    //   method === \"OPTIONS\" ||\n    //   method === \"TRACE\" ||\n    //   method === \"CONNECT\"\n    // ) {\n    //   this.useChunkedEncodingByDefault = false;\n    // } else {\n    //   this.useChunkedEncodingByDefault = true;\n    // }\n\n    this.#finished = false;\n    this.#res = null;\n    this.#upgradeOrConnect = false;\n    this.#parser = null;\n    this.#maxHeadersCount = null;\n    this.#reusedSocket = false;\n    this.#host = host;\n    this.#protocol = protocol;\n    this.#timeoutTimer = null;\n    const headersArray = ArrayIsArray(headers);\n    if (!headersArray) {\n      var headers = options.headers;\n      if (headers) {\n        for (let key in headers) {\n          this.setHeader(key, headers[key]);\n        }\n      }\n\n      // if (host && !this.getHeader(\"host\") && setHost) {\n      //   let hostHeader = host;\n\n      //   // For the Host header, ensure that IPv6 addresses are enclosed\n      //   // in square brackets, as defined by URI formatting\n      //   // https://tools.ietf.org/html/rfc3986#section-3.2.2\n      //   const posColon = StringPrototypeIndexOf.call(hostHeader, \":\");\n      //   if (\n      //     posColon !== -1 &&\n      //     StringPrototypeIncludes(hostHeader, \":\", posColon + 1) &&\n      //     StringPrototypeCharCodeAt(hostHeader, 0) !== 91 /* '[' */\n      //   ) {\n      //     hostHeader = `[${hostHeader}]`;\n      //   }\n\n      //   if (port && +port !== defaultPort) {\n      //     hostHeader += \":\" + port;\n      //   }\n      //   this.setHeader(\"Host\", hostHeader);\n      // }\n\n      var auth = options.auth;\n      if (auth && !this.getHeader(\"Authorization\")) {\n        this.setHeader(\"Authorization\", \"Basic \" + Buffer.from(auth).toString(\"base64\"));\n      }\n\n      //   if (this.getHeader(\"expect\")) {\n      //     if (this._header) {\n      //       throw new ERR_HTTP_HEADERS_SENT(\"render\");\n      //     }\n\n      //     this._storeHeader(\n      //       this.method + \" \" + this.path + \" HTTP/1.1\\r\\n\",\n      //       this[kOutHeaders],\n      //     );\n      //   }\n      // } else {\n      //   this._storeHeader(\n      //     this.method + \" \" + this.path + \" HTTP/1.1\\r\\n\",\n      //     options.headers,\n      //   );\n    }\n\n    // this[kUniqueHeaders] = parseUniqueHeadersOption(options.uniqueHeaders);\n\n    var optsWithoutSignal = options;\n    if (optsWithoutSignal.signal) {\n      optsWithoutSignal = ObjectAssign({}, options);\n      delete optsWithoutSignal.signal;\n    }\n    this.#options = optsWithoutSignal;\n\n    var timeout = options.timeout;\n    if (timeout) {\n      this.setTimeout(timeout);\n    }\n  }\n\n  setSocketKeepAlive(enable = true, initialDelay = 0) {\n    __DEBUG__ && debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: ClientRequest.setSocketKeepAlive is a no-op\");\n  }\n\n  setNoDelay(noDelay = true) {\n    __DEBUG__ && debug(`${NODE_HTTP_WARNING}\\n`, \"WARN: ClientRequest.setNoDelay is a no-op\");\n  }\n  [kClearTimeout]() {\n    if (this.#timeoutTimer) {\n      clearTimeout(this.#timeoutTimer);\n      this.#timeoutTimer = null;\n    }\n  }\n\n  setTimeout(msecs, callback) {\n    if (this.#timeoutTimer) return this;\n    if (callback) {\n      this.on(\"timeout\", callback);\n    }\n\n    this.#timeoutTimer = setTimeout(async () => {\n      this.#timeoutTimer = null;\n      this[kAbortController]?.abort();\n      this.emit(\"timeout\");\n    }, msecs);\n\n    return this;\n  }\n}\n\nfunction urlToHttpOptions(url) {\n  var { protocol, hostname, hash, search, pathname, href, port, username, password } = url;\n  return {\n    protocol,\n    hostname:\n      typeof hostname === \"string\" && StringPrototypeStartsWith.call(hostname, \"[\")\n        ? StringPrototypeSlice.call(hostname, 1, -1)\n        : hostname,\n    hash,\n    search,\n    pathname,\n    path: `${pathname || \"\"}${search || \"\"}`,\n    href,\n    port: port ? Number(port) : protocol === \"https:\" ? 443 : protocol === \"http:\" ? 80 : undefined,\n    auth: username || password ? `${decodeURIComponent(username)}:${decodeURIComponent(password)}` : undefined,\n  };\n}\n\nfunction validateHost(host, name) {\n  if (host !== null && host !== undefined && typeof host !== \"string\") {\n    // throw new ERR_INVALID_ARG_TYPE(\n    //   `options.${name}`,\n    //   [\"string\", \"undefined\", \"null\"],\n    //   host,\n    // );\n    throw new Error(\"Invalid arg type in options\");\n  }\n  return host;\n}\n\nconst tokenRegExp = /^[\\^_`a-zA-Z\\-0-9!#$%&'*+.|~]+$/;\n/**\n * Verifies that the given val is a valid HTTP token\n * per the rules defined in RFC 7230\n * See https://tools.ietf.org/html/rfc7230#section-3.2.6\n */\nfunction checkIsHttpToken(val) {\n  return RegExpPrototypeExec.call(tokenRegExp, val) !== null;\n}\n\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nexport const METHODS = [\n  \"ACL\",\n  \"BIND\",\n  \"CHECKOUT\",\n  \"CONNECT\",\n  \"COPY\",\n  \"DELETE\",\n  \"GET\",\n  \"HEAD\",\n  \"LINK\",\n  \"LOCK\",\n  \"M-SEARCH\",\n  \"MERGE\",\n  \"MKACTIVITY\",\n  \"MKCALENDAR\",\n  \"MKCOL\",\n  \"MOVE\",\n  \"NOTIFY\",\n  \"OPTIONS\",\n  \"PATCH\",\n  \"POST\",\n  \"PROPFIND\",\n  \"PROPPATCH\",\n  \"PURGE\",\n  \"PUT\",\n  \"REBIND\",\n  \"REPORT\",\n  \"SEARCH\",\n  \"SOURCE\",\n  \"SUBSCRIBE\",\n  \"TRACE\",\n  \"UNBIND\",\n  \"UNLINK\",\n  \"UNLOCK\",\n  \"UNSUBSCRIBE\",\n];\n\nexport const STATUS_CODES = {\n  100: \"Continue\",\n  101: \"Switching Protocols\",\n  102: \"Processing\",\n  103: \"Early Hints\",\n  200: \"OK\",\n  201: \"Created\",\n  202: \"Accepted\",\n  203: \"Non-Authoritative Information\",\n  204: \"No Content\",\n  205: \"Reset Content\",\n  206: \"Partial Content\",\n  207: \"Multi-Status\",\n  208: \"Already Reported\",\n  226: \"IM Used\",\n  300: \"Multiple Choices\",\n  301: \"Moved Permanently\",\n  302: \"Found\",\n  303: \"See Other\",\n  304: \"Not Modified\",\n  305: \"Use Proxy\",\n  307: \"Temporary Redirect\",\n  308: \"Permanent Redirect\",\n  400: \"Bad Request\",\n  401: \"Unauthorized\",\n  402: \"Payment Required\",\n  403: \"Forbidden\",\n  404: \"Not Found\",\n  405: \"Method Not Allowed\",\n  406: \"Not Acceptable\",\n  407: \"Proxy Authentication Required\",\n  408: \"Request Timeout\",\n  409: \"Conflict\",\n  410: \"Gone\",\n  411: \"Length Required\",\n  412: \"Precondition Failed\",\n  413: \"Payload Too Large\",\n  414: \"URI Too Long\",\n  415: \"Unsupported Media Type\",\n  416: \"Range Not Satisfiable\",\n  417: \"Expectation Failed\",\n  418: \"I'm a Teapot\",\n  421: \"Misdirected Request\",\n  422: \"Unprocessable Entity\",\n  423: \"Locked\",\n  424: \"Failed Dependency\",\n  425: \"Too Early\",\n  426: \"Upgrade Required\",\n  428: \"Precondition Required\",\n  429: \"Too Many Requests\",\n  431: \"Request Header Fields Too Large\",\n  451: \"Unavailable For Legal Reasons\",\n  500: \"Internal Server Error\",\n  501: \"Not Implemented\",\n  502: \"Bad Gateway\",\n  503: \"Service Unavailable\",\n  504: \"Gateway Timeout\",\n  505: \"HTTP Version Not Supported\",\n  506: \"Variant Also Negotiates\",\n  507: \"Insufficient Storage\",\n  508: \"Loop Detected\",\n  509: \"Bandwidth Limit Exceeded\",\n  510: \"Not Extended\",\n  511: \"Network Authentication Required\",\n};\n\nfunction _normalizeArgs(args) {\n  let arr;\n\n  if (args.length === 0) {\n    arr = [{}, null];\n    // arr[normalizedArgsSymbol] = true;\n    return arr;\n  }\n\n  const arg0 = args[0];\n  let options = {};\n  if (typeof arg0 === \"object\" && arg0 !== null) {\n    // (options[...][, cb])\n    options = arg0;\n    // } else if (isPipeName(arg0)) {\n    // (path[...][, cb])\n    // options.path = arg0;\n  } else {\n    // ([port][, host][...][, cb])\n    options.port = arg0;\n    if (args.length > 1 && typeof args[1] === \"string\") {\n      options.host = args[1];\n    }\n  }\n\n  const cb = args[args.length - 1];\n  if (typeof cb !== \"function\") arr = [options, null];\n  else arr = [options, cb];\n\n  // arr[normalizedArgsSymbol] = true;\n  return arr;\n}\n\nfunction _writeHead(statusCode, reason, obj, response) {\n  statusCode |= 0;\n  if (statusCode < 100 || statusCode > 999) {\n    throw new Error(\"status code must be between 100 and 999\");\n  }\n\n  if (typeof reason === \"string\") {\n    // writeHead(statusCode, reasonPhrase[, headers])\n    response.statusMessage = reason;\n  } else {\n    // writeHead(statusCode[, headers])\n    if (!response.statusMessage) response.statusMessage = STATUS_CODES[statusCode] || \"unknown\";\n    obj = reason;\n  }\n  response.statusCode = statusCode;\n\n  {\n    // Slow-case: when progressive API and header fields are passed.\n    let k;\n    if (Array.isArray(obj)) {\n      if (obj.length % 2 !== 0) {\n        throw new Error(\"raw headers must have an even number of elements\");\n      }\n\n      for (let n = 0; n < obj.length; n += 2) {\n        k = obj[n + 0];\n        if (k) response.setHeader(k, obj[n + 1]);\n      }\n    } else if (obj) {\n      const keys = Object.keys(obj);\n      // Retain for(;;) loop for performance reasons\n      // Refs: https://github.com/nodejs/node/pull/30958\n      for (let i = 0; i < keys.length; i++) {\n        k = keys[i];\n        if (k) response.setHeader(k, obj[k]);\n      }\n    }\n  }\n}\n\n/**\n * Makes an HTTP request.\n * @param {string | URL} url\n * @param {HTTPRequestOptions} [options]\n * @param {Function} [cb]\n * @returns {ClientRequest}\n */\nexport function request(url, options, cb) {\n  return new ClientRequest(url, options, cb);\n}\n\n/**\n * Makes a `GET` HTTP request.\n * @param {string | URL} url\n * @param {HTTPRequestOptions} [options]\n * @param {Function} [cb]\n * @returns {ClientRequest}\n */\nexport function get(url, options, cb) {\n  const req = request(url, options, cb);\n  req.end();\n  return req;\n}\n\nvar defaultObject = {\n  Agent,\n  Server,\n  METHODS,\n  STATUS_CODES,\n  createServer,\n  ServerResponse,\n  IncomingMessage,\n  request,\n  get,\n  maxHeaderSize: 16384,\n  // validateHeaderName,\n  // validateHeaderValue,\n  setMaxIdleHTTPParsers(max) {\n    debug(`${NODE_HTTP_WARNING}\\n`, \"setMaxIdleHTTPParsers() is a no-op\");\n  },\n  get globalAgent() {\n    return (_globalAgent ??= new Agent());\n  },\n  set globalAgent(agent) {},\n  [Symbol.for(\"CommonJS\")]: 0,\n};\n\nexport default defaultObject;\n"
  ],
  "mappings": ";;A//////DAgDA,IAAS,0BAAe,CAAC,KAAK;AAC5B,aAAW,QAAQ,YAAY,aAAa,GAAG,KAAK,eAAe,eAAe,eAAe;AAAM,WAAO;AAC9G,MAAI,MAAM,QAAQ,GAAG,GAAG;AACtB,aAAS,IAAI,EAAG,IAAI,IAAI,QAAQ;AAC9B,iBAAW,QAAQ,aAAa,aAAa,GAAG,OAAO,eAAe,kBAAkB,eAAe;AACrG,eAAO;AAEX,WAAO;AAAA;AAAA,GAIF,oBAAS,CAAC,SAAS,MAAM;AAChC,OAAK;AAAS;AACd,QAAM,SAAS,QAAQ,IAAI,IAAI;AAC/B,SAAO,UAAU,OAAO,SAAY;AAAA;AAoF/B,SAAS,YAAY,CAAC,SAAS,UAAU;AAC9C,SAAO,IAAI,OAAO,SAAS,QAAQ;AAAA;AAkJrC,IAAS,gCAAqB,CAAC,MAAM,UAAU,KAAK,UAAU,MAAM;AAClE,aAAW,aAAa;AACtB,QAAI;AACF,eAAS,KAAK,UAAU,IAAI;AAAA,aACrB,MAAP;AACA,WAAK,KAAK,SAAS,IAAG;AAAA;AAM1B,MAFA,KAAK,aAAa,KAEd;AACF,SAAK,KAAK,SAAS,GAAG;AAAA;AAEtB,SAAK,KAAK,aAAa,UAAU,IAAI;AAAA,GAoOhC,wBAAa,CAAC,QAAQ,KAAK;AAClC,MAAI,UAAU,IAAI,QAAQ,OAAO;AACjC,QAAM,aAAa,iBAAiB,IAAI,QAAQ,QAAQ,CAAC;AACzD,MAAI,IAAI;AACR,WAAW,OAAO;AAChB,eAAW,OAAO,KAClB,WAAW,OAAO,QAAQ;AAE5B,SAAO,UAAU,SACjB,OAAO,aAAa;AAAA;",
  "debugId": "BB02ECF6CBA5ED8A64756e2164756e21",
  "names": []
}