{"version":3,"file":"index.cjs","sources":["../src/connection-pool.ts","../src/logger.ts","../src/request-queue.ts","../src/http2-proxy-enhanced.ts"],"sourcesContent":["import type { ClientHttp2Session } from \"node:http2\";\nimport { connect } from \"node:http2\";\nimport type * as tls from \"node:tls\";\nimport type { Logger } from \"./logger\";\n\nexport interface ConnectionPoolOptions {\n  secure?: boolean;\n  auth?: string;\n}\n\nexport interface Http2ConnectionPoolConfig {\n  maxSessions?: number;\n  sessionMaxAge?: number;\n  connectionTimeout?: number;\n}\n\nexport interface Http2Session {\n  session: ClientHttp2Session;\n  origin: string;\n  lastUsed: number;\n  activeStreams: number;\n  maxConcurrentStreams: number;\n}\n\nexport class Http2ConnectionPool {\n  private sessions: Map<string, Http2Session> = new Map();\n  private maxAge: number;\n  private maxSessions: number;\n  private connectionTimeout: number;\n  private logger?: Logger;\n\n  constructor(logger?: Logger, config: Http2ConnectionPoolConfig = {}) {\n    this.logger = logger;\n    this.maxSessions = config.maxSessions ?? 256;\n    this.maxAge = config.sessionMaxAge ?? 5 * 60 * 1000; // 5 minutes default\n    this.connectionTimeout = config.connectionTimeout ?? 10000; // 10 seconds default\n  }\n\n  getSession(\n    origin: string,\n    options: ConnectionPoolOptions,\n  ): ClientHttp2Session {\n    const existing = this.sessions.get(origin);\n\n    if (existing && !existing.session.closed && !existing.session.destroyed) {\n      existing.lastUsed = Date.now();\n      return existing.session;\n    }\n\n    // Connection options\n    const connectOptions: tls.ConnectionOptions & { auth?: string } = {\n      rejectUnauthorized: options.secure !== false,\n    };\n\n    // Add authentication if provided\n    if (options.auth) {\n      const authParts = options.auth.split(\":\");\n      if (authParts.length !== 2) {\n        throw new Error(\n          `Invalid auth format. Expected \"username:password\", got \"${options.auth}\"`,\n        );\n      }\n      const [username, password] = authParts;\n      if (!username || !password) {\n        throw new Error(\"Auth username and password cannot be empty\");\n      }\n      connectOptions.auth = `${username}:${password}`;\n    }\n\n    const session = connect(origin, connectOptions);\n\n    // Set up connection timeout\n    const connectionTimeout = setTimeout(() => {\n      session.close();\n      throw new Error(`HTTP/2 connection timeout for ${origin}`);\n    }, this.connectionTimeout);\n\n    // Default max concurrent streams - will be updated by remoteSettings\n    let maxConcurrentStreams = 100;\n\n    // Wait for connection to be established\n    session.once(\"connect\", () => {\n      clearTimeout(connectionTimeout);\n      this.logger?.debug(`HTTP/2 session connected to ${origin}`);\n    });\n\n    // Listen for remote settings to get actual max concurrent streams\n    session.on(\"remoteSettings\", (settings) => {\n      if (settings.maxConcurrentStreams !== undefined) {\n        maxConcurrentStreams = settings.maxConcurrentStreams;\n        const sessionData = this.sessions.get(origin);\n        if (sessionData) {\n          sessionData.maxConcurrentStreams = maxConcurrentStreams;\n        }\n        this.logger?.debug(\n          `HTTP/2 session ${origin} maxConcurrentStreams: ${maxConcurrentStreams}`,\n        );\n      }\n    });\n\n    session.on(\"error\", (err) => {\n      clearTimeout(connectionTimeout);\n      this.logger?.error(`HTTP/2 session error for ${origin}`, err);\n      this.sessions.delete(origin);\n    });\n\n    session.on(\"close\", () => {\n      clearTimeout(connectionTimeout);\n      this.logger?.debug(`HTTP/2 session closed for ${origin}`);\n      this.sessions.delete(origin);\n    });\n\n    // Implement connection limit\n    if (this.sessions.size >= this.maxSessions) {\n      this.evictOldest();\n    }\n\n    this.sessions.set(origin, {\n      session,\n      origin,\n      lastUsed: Date.now(),\n      activeStreams: 0,\n      maxConcurrentStreams,\n    });\n\n    // Cleanup old sessions periodically\n    this.cleanup();\n\n    return session;\n  }\n\n  canAcceptStream(origin: string): boolean {\n    const sess = this.sessions.get(origin);\n    if (!sess || sess.session.closed || sess.session.destroyed) {\n      return false;\n    }\n    return sess.activeStreams < sess.maxConcurrentStreams;\n  }\n\n  incrementActiveStreams(origin: string): void {\n    const sess = this.sessions.get(origin);\n    if (sess) {\n      sess.activeStreams++;\n      this.logger?.debug(\n        `Session ${origin} active streams: ${sess.activeStreams}/${sess.maxConcurrentStreams}`,\n      );\n    }\n  }\n\n  decrementActiveStreams(origin: string): void {\n    const sess = this.sessions.get(origin);\n    if (sess && sess.activeStreams > 0) {\n      sess.activeStreams--;\n      this.logger?.debug(\n        `Session ${origin} active streams: ${sess.activeStreams}/${sess.maxConcurrentStreams}`,\n      );\n    }\n  }\n\n  getAvailableSession(\n    origin: string,\n    options: ConnectionPoolOptions,\n  ): ClientHttp2Session | null {\n    const existing = this.sessions.get(origin);\n\n    // If we have an existing session that can accept streams, use it\n    if (existing && !existing.session.closed && !existing.session.destroyed) {\n      if (existing.activeStreams < existing.maxConcurrentStreams) {\n        existing.lastUsed = Date.now();\n        return existing.session;\n      }\n    }\n\n    // If we can create a new session (haven't hit maxSessions), do so\n    if (this.sessions.size < this.maxSessions || !existing) {\n      return this.getSession(origin, options);\n    }\n\n    // No available capacity\n    return null;\n  }\n\n  private evictOldest() {\n    let oldest: [string, Http2Session] | null = null;\n    for (const entry of this.sessions.entries()) {\n      if (!oldest || entry[1].lastUsed < oldest[1].lastUsed) {\n        oldest = entry;\n      }\n    }\n    if (oldest) {\n      oldest[1].session.close();\n      this.sessions.delete(oldest[0]);\n    }\n  }\n\n  private cleanup() {\n    const now = Date.now();\n    for (const [origin, sess] of this.sessions) {\n      if (now - sess.lastUsed > this.maxAge) {\n        sess.session.close();\n        this.sessions.delete(origin);\n      }\n    }\n  }\n\n  close() {\n    for (const sess of this.sessions.values()) {\n      sess.session.close();\n    }\n    this.sessions.clear();\n  }\n\n  // Exposed for testing\n  getSessionCount(): number {\n    return this.sessions.size;\n  }\n\n  // Exposed for testing\n  hasSession(origin: string): boolean {\n    const session = this.sessions.get(origin);\n    return !!(session && !session.session.closed && !session.session.destroyed);\n  }\n\n  /* ============================================================\n   * TEST-ONLY METHODS - DO NOT USE IN PRODUCTION CODE\n   * These methods are exposed solely for testing purposes to\n   * avoid using type assertions. They should never be used\n   * outside of test files.\n   * ============================================================ */\n\n  _setMaxSessions(max: number): void {\n    this.maxSessions = max;\n  }\n\n  _setMaxAge(age: number): void {\n    this.maxAge = age;\n  }\n\n  _getSessionLastUsed(origin: string): number | undefined {\n    return this.sessions.get(origin)?.lastUsed;\n  }\n\n  /* ============================================================\n   * END TEST-ONLY METHODS\n   * ============================================================ */\n}\n","import { debuglog } from \"node:util\";\nimport type { ResolvedConfig } from \"vite\";\n\nexport interface Logger {\n  debug: (msg: string, ...args: unknown[]) => void;\n  info: (msg: string, ...args: unknown[]) => void;\n  warn: (msg: string, ...args: unknown[]) => void;\n  error: (msg: string, ...args: unknown[]) => void;\n}\n\nexport function createLogger(\n  namespace: string,\n  viteConfig?: ResolvedConfig,\n): Logger {\n  const debug = debuglog(namespace);\n  const viteLogger = viteConfig?.logger;\n\n  return {\n    debug: (msg: string, ...args: unknown[]) => {\n      if (\n        process.env.DEBUG?.includes(namespace) ||\n        process.env.LOG_LEVEL === \"debug\"\n      ) {\n        debug(msg, ...args);\n      }\n    },\n    info: (msg: string, ...args: unknown[]) => {\n      if (viteLogger) {\n        viteLogger.info(`[${namespace}] ${msg}`, { timestamp: true });\n      } else {\n        console.info(`[${namespace}] ${msg}`, ...args);\n      }\n    },\n    warn: (msg: string, ...args: unknown[]) => {\n      if (viteLogger) {\n        viteLogger.warn(`[${namespace}] ${msg}`, { timestamp: true });\n      } else {\n        console.warn(`[${namespace}] ${msg}`, ...args);\n      }\n    },\n    error: (msg: string, ...args: unknown[]) => {\n      if (viteLogger) {\n        // Type guard to check if first arg is an Error\n        const error = args[0] instanceof Error ? args[0] : undefined;\n        viteLogger.error(`[${namespace}] ${msg}`, {\n          timestamp: true,\n          error,\n        });\n      } else {\n        console.error(`[${namespace}] ${msg}`, ...args);\n      }\n    },\n  };\n}\n\nexport function logProxyRequest(\n  logger: Logger,\n  method: string,\n  url: string,\n  target: string,\n  status?: number,\n  duration?: number,\n): void {\n  const parts = [\n    `${method} ${url}`,\n    `-> ${target}`,\n    status && `[${status}]`,\n    duration && `(${duration}ms)`,\n  ]\n    .filter(Boolean)\n    .join(\" \");\n\n  if (status && status >= 500) {\n    logger.error(parts);\n  } else if (status && status >= 400) {\n    logger.warn(parts);\n  } else {\n    logger.info(parts);\n  }\n}\n","import type { IncomingMessage, ServerResponse } from \"node:http\";\nimport type { Logger } from \"./logger\";\n\nexport interface QueuedRequest {\n  req: IncomingMessage;\n  res: ServerResponse;\n  origin: string;\n  callback: () => void;\n  timeoutHandle?: NodeJS.Timeout;\n  queuedAt: number;\n}\n\nexport interface RequestQueueOptions {\n  maxQueueSize?: number;\n  queueTimeout?: number;\n}\n\nexport class RequestQueue {\n  private queue: Map<string, QueuedRequest[]> = new Map();\n  private maxQueueSize: number;\n  private queueTimeout: number;\n  private logger?: Logger;\n  private totalQueued = 0;\n\n  constructor(logger?: Logger, options: RequestQueueOptions = {}) {\n    this.logger = logger;\n    this.maxQueueSize = options.maxQueueSize || 512;\n    this.queueTimeout = options.queueTimeout || 30000; // 30 seconds default\n  }\n\n  enqueue(\n    origin: string,\n    req: IncomingMessage,\n    res: ServerResponse,\n    callback: () => void,\n  ): boolean {\n    if (this.totalQueued >= this.maxQueueSize) {\n      this.logger?.warn(\n        `Request queue full (${this.totalQueued}/${this.maxQueueSize}), rejecting request`,\n      );\n      return false;\n    }\n\n    const queuedRequest: QueuedRequest = {\n      req,\n      res,\n      origin,\n      callback,\n      queuedAt: Date.now(),\n    };\n\n    // Set timeout for queued request\n    queuedRequest.timeoutHandle = setTimeout(() => {\n      this.removeRequest(origin, queuedRequest);\n      if (!res.headersSent) {\n        res.writeHead(503, { \"Content-Type\": \"text/plain\" });\n        res.end(\"Service Unavailable: Request queue timeout\");\n      }\n      this.logger?.warn(\n        `Request timed out in queue after ${this.queueTimeout}ms for ${origin}`,\n      );\n    }, this.queueTimeout);\n\n    // Add to queue for this origin\n    const originQueue = this.queue.get(origin) || [];\n    originQueue.push(queuedRequest);\n    this.queue.set(origin, originQueue);\n    this.totalQueued++;\n\n    this.logger?.debug(\n      `Queued request for ${origin}. Queue depth: ${originQueue.length}, Total queued: ${this.totalQueued}`,\n    );\n\n    return true;\n  }\n\n  dequeue(origin: string): QueuedRequest | null {\n    const originQueue = this.queue.get(origin);\n    if (!originQueue || originQueue.length === 0) {\n      return null;\n    }\n\n    const request = originQueue.shift();\n    if (request) {\n      // Clear timeout\n      if (request.timeoutHandle) {\n        clearTimeout(request.timeoutHandle);\n      }\n\n      // Clean up empty queues\n      if (originQueue.length === 0) {\n        this.queue.delete(origin);\n      }\n\n      this.totalQueued--;\n      const waitTime = Date.now() - request.queuedAt;\n      this.logger?.debug(\n        `Dequeued request for ${origin} after ${waitTime}ms. Remaining in queue: ${originQueue.length}`,\n      );\n    }\n\n    return request || null;\n  }\n\n  private removeRequest(origin: string, request: QueuedRequest): void {\n    const originQueue = this.queue.get(origin);\n    if (!originQueue) return;\n\n    const index = originQueue.indexOf(request);\n    if (index > -1) {\n      originQueue.splice(index, 1);\n      this.totalQueued--;\n\n      if (originQueue.length === 0) {\n        this.queue.delete(origin);\n      }\n    }\n  }\n\n  getQueueDepth(origin?: string): number {\n    if (origin) {\n      return this.queue.get(origin)?.length || 0;\n    }\n    return this.totalQueued;\n  }\n\n  clear(): void {\n    // Clear all timeouts and respond with 503\n    for (const [, requests] of this.queue) {\n      for (const request of requests) {\n        if (request.timeoutHandle) {\n          clearTimeout(request.timeoutHandle);\n        }\n        if (!request.res.headersSent) {\n          request.res.writeHead(503, { \"Content-Type\": \"text/plain\" });\n          request.res.end(\"Service Unavailable: Server shutting down\");\n        }\n      }\n    }\n    this.queue.clear();\n    this.totalQueued = 0;\n  }\n}\n","import type { IncomingMessage, ServerResponse } from \"node:http\";\nimport type {\n  ClientHttp2Session,\n  ClientHttp2Stream,\n  IncomingHttpHeaders,\n  OutgoingHttpHeaders,\n} from \"node:http2\";\nimport { connect, constants } from \"node:http2\";\nimport * as net from \"node:net\";\nimport type { TLSSocket } from \"node:tls\";\nimport * as tls from \"node:tls\";\nimport type { Plugin, ProxyOptions, ResolvedConfig } from \"vite\";\nimport { Http2ConnectionPool } from \"./connection-pool\";\nimport { createLogger, type Logger, logProxyRequest } from \"./logger\";\nimport { RequestQueue } from \"./request-queue\";\n\nlet logger: Logger;\n\nconst {\n  HTTP2_HEADER_METHOD,\n  HTTP2_HEADER_PATH,\n  HTTP2_HEADER_AUTHORITY,\n  HTTP2_HEADER_SCHEME,\n  HTTP2_HEADER_STATUS,\n  HTTP2_HEADER_LOCATION,\n} = constants;\n\n// Type guard to check if a socket is a TLSSocket\nfunction isTLSSocket(socket: net.Socket | undefined): socket is TLSSocket {\n  return (\n    socket !== undefined &&\n    \"encrypted\" in socket &&\n    (socket as TLSSocket).encrypted === true\n  );\n}\n\n// Extended proxy options to match Vite's full feature set\ninterface Http2ProxyOptions extends Omit<ProxyOptions, \"configure\" | \"bypass\"> {\n  // Cookie rewriting\n  cookieDomainRewrite?: string | { [domain: string]: string } | false;\n  cookiePathRewrite?: string | { [path: string]: string } | false;\n\n  // Headers\n  headers?: Record<string, string>;\n  xfwd?: boolean;\n  preserveHeaderKeyCase?: boolean;\n\n  // Security\n  secure?: boolean;\n  auth?: string;\n\n  // Advanced routing\n  router?: string | ((req: IncomingMessage) => string);\n\n  // Timeouts\n  timeout?: number;\n  proxyTimeout?: number;\n\n  // Override configure with HTTP/2 stream type\n  configure?: (stream: ClientHttp2Stream, options: Http2ProxyOptions) => void;\n\n  // Override bypass with our options type\n  bypass?: (\n    req: IncomingMessage,\n    res: ServerResponse,\n    options: Http2ProxyOptions,\n    // biome-ignore lint/suspicious/noConfusingVoidType: Matching Vite's bypass API which includes void\n  ) => null | undefined | false | string | void;\n\n  // Response handling\n  selfHandleResponse?: boolean;\n  followRedirects?: boolean;\n\n  // SSE support\n  sse?: boolean;\n\n  // Protocol options\n  forceHttp1?: boolean; // Force HTTP/1.1 for this proxy\n  autoDetectProtocol?: boolean; // Auto-detect server protocol support\n}\n\ninterface NormalizedProxyOptions extends Http2ProxyOptions {\n  target: string;\n  changeOrigin: boolean;\n}\n\nlet connectionPool: Http2ConnectionPool;\nlet requestQueue: RequestQueue;\n\n// Map to track which origins support HTTP/2\nconst http2SupportMap = new Map<string, boolean>();\n\n// Cache compiled regular expressions to avoid recompiling on every request\nconst regexpCache = new Map<string, RegExp>();\n\n// Get or create a cached regular expression\nfunction getCachedRegExp(pattern: string): RegExp {\n  let regexp = regexpCache.get(pattern);\n  if (!regexp) {\n    regexp = new RegExp(pattern);\n    regexpCache.set(pattern, regexp);\n  }\n  return regexp;\n}\n\n// Check if an origin supports HTTP/2\nasync function supportsHttp2(\n  origin: string,\n  secure: boolean,\n): Promise<boolean> {\n  // Check cache first\n  if (http2SupportMap.has(origin)) {\n    return http2SupportMap.get(origin) ?? false;\n  }\n\n  return new Promise((resolve) => {\n    const testSession = connect(origin, {\n      rejectUnauthorized: secure !== false,\n    });\n\n    const timeout = setTimeout(() => {\n      testSession.close();\n      // Timeout likely means HTTP/1.1 only\n      http2SupportMap.set(origin, false);\n      resolve(false);\n    }, 2000);\n\n    testSession.on(\"connect\", () => {\n      clearTimeout(timeout);\n      testSession.close();\n      // Successful connection means HTTP/2 is supported\n      http2SupportMap.set(origin, true);\n      resolve(true);\n    });\n\n    testSession.on(\"error\", () => {\n      clearTimeout(timeout);\n      // Error likely means HTTP/1.1 only\n      http2SupportMap.set(origin, false);\n      resolve(false);\n    });\n  });\n}\n\nfunction normalizeProxyOptions(\n  options: string | Http2ProxyOptions | ProxyOptions,\n  globalDefaults?: {\n    defaultTimeout?: number;\n    defaultProxyTimeout?: number;\n  },\n): NormalizedProxyOptions {\n  if (typeof options === \"string\") {\n    return {\n      target: options,\n      changeOrigin: true,\n      xfwd: true,\n      timeout: globalDefaults?.defaultTimeout,\n      proxyTimeout: globalDefaults?.defaultProxyTimeout,\n    };\n  }\n\n  if (!options.target) {\n    throw new Error(\"Proxy target is required\");\n  }\n\n  // Handle different target types\n  let targetUrl: string;\n  if (typeof options.target === \"string\") {\n    targetUrl = options.target;\n  } else if (\"href\" in options.target && options.target.href) {\n    targetUrl = options.target.href;\n  } else if (\"protocol\" in options.target && \"host\" in options.target) {\n    // ProxyTargetDetailed type\n    const { protocol, host, port } = options.target;\n    targetUrl = `${protocol}//${host}${port ? `:${port}` : \"\"}`;\n  } else {\n    throw new Error(\"Invalid proxy target\");\n  }\n\n  // Create base normalized options\n  const baseOptions = {\n    changeOrigin: true,\n    xfwd: true,\n    secure: true,\n    target: targetUrl,\n    // Apply global defaults if not specified in proxy options\n    timeout: options.timeout ?? globalDefaults?.defaultTimeout,\n    proxyTimeout: options.proxyTimeout ?? globalDefaults?.defaultProxyTimeout,\n  };\n\n  // Handle ProxyOptions that need to be converted to Http2ProxyOptions\n  const { configure, bypass, target: _, ...restOptions } = options;\n\n  const normalizedOptions: NormalizedProxyOptions = {\n    ...baseOptions,\n    ...restOptions,\n  };\n\n  // Add configure and bypass with proper typing if they exist\n  if (configure) {\n    normalizedOptions.configure = configure as Http2ProxyOptions[\"configure\"];\n  }\n\n  if (bypass) {\n    normalizedOptions.bypass = bypass as Http2ProxyOptions[\"bypass\"];\n  }\n\n  return normalizedOptions;\n}\n\nfunction rewriteCookie(\n  cookie: string,\n  domainRewrite: string | { [domain: string]: string } | false,\n  pathRewrite: string | { [path: string]: string } | false,\n): string {\n  if (!domainRewrite && !pathRewrite) return cookie;\n\n  let rewritten = cookie;\n\n  // Domain rewriting\n  if (domainRewrite) {\n    const domainMatch = /domain=([^;]+)/i.exec(cookie);\n    if (domainMatch) {\n      const oldDomain = domainMatch[1];\n      let newDomain: string | undefined;\n\n      if (typeof domainRewrite === \"string\") {\n        newDomain = domainRewrite;\n      } else if (typeof domainRewrite === \"object\") {\n        newDomain = domainRewrite[oldDomain];\n      }\n\n      if (newDomain !== undefined) {\n        rewritten = rewritten.replace(domainMatch[0], `Domain=${newDomain}`);\n      }\n    }\n  }\n\n  // Path rewriting\n  if (pathRewrite) {\n    const pathMatch = /path=([^;]+)/i.exec(cookie);\n    if (pathMatch) {\n      const oldPath = pathMatch[1];\n      let newPath: string | undefined;\n\n      if (typeof pathRewrite === \"string\") {\n        newPath = pathRewrite;\n      } else if (typeof pathRewrite === \"object\") {\n        newPath = pathRewrite[oldPath];\n      }\n\n      if (newPath !== undefined) {\n        rewritten = rewritten.replace(pathMatch[0], `Path=${newPath}`);\n      }\n    }\n  }\n\n  return rewritten;\n}\n\nfunction createHttp2Headers(\n  req: IncomingMessage,\n  target: URL,\n  options: NormalizedProxyOptions,\n): OutgoingHttpHeaders {\n  const headers: OutgoingHttpHeaders = {\n    [HTTP2_HEADER_METHOD]: req.method || \"GET\",\n    [HTTP2_HEADER_SCHEME]: target.protocol.slice(0, -1),\n    [HTTP2_HEADER_AUTHORITY]: target.host,\n  };\n\n  // HTTP/2 forbidden headers that must be filtered out\n  const forbiddenHeaders = [\n    \"connection\",\n    \"upgrade\",\n    \"keep-alive\",\n    \"transfer-encoding\",\n    \"proxy-connection\",\n  ];\n\n  // Copy headers from incoming request\n  for (const [key, value] of Object.entries(req.headers)) {\n    if (key.startsWith(\":\")) continue; // Skip pseudo-headers\n    if (key === \"host\" && options.changeOrigin) {\n      continue; // Skip host header when changeOrigin is true\n    }\n    if (forbiddenHeaders.includes(key.toLowerCase())) {\n      continue; // Skip forbidden HTTP/2 headers\n    }\n    if (options.preserveHeaderKeyCase) {\n      // Find the original case-sensitive key\n      const originalKey = Object.keys(req.headers).find(\n        (k) => k.toLowerCase() === key,\n      );\n      headers[originalKey || key] = value;\n    } else {\n      headers[key] = value;\n    }\n  }\n\n  // Set host header if changeOrigin is true\n  if (options.changeOrigin) {\n    headers.host = target.host;\n  }\n\n  // Add custom headers\n  if (options.headers) {\n    Object.assign(headers, options.headers);\n  }\n\n  // Add X-Forwarded headers if xfwd is true\n  if (options.xfwd) {\n    const forwarded = req.socket.remoteAddress;\n    headers[\"x-forwarded-for\"] = forwarded;\n    // Check if socket is a TLSSocket (encrypted connection)\n    headers[\"x-forwarded-proto\"] = isTLSSocket(req.socket) ? \"https\" : \"http\";\n    headers[\"x-forwarded-host\"] = req.headers.host || \"\";\n    headers[\"x-forwarded-port\"] = String(req.socket.localPort);\n  }\n\n  // Add authentication header if auth option is provided\n  if (options.auth && !headers.authorization) {\n    const authString = Buffer.from(options.auth).toString(\"base64\");\n    headers.authorization = `Basic ${authString}`;\n    logger?.debug(`Added auth header: Basic ${authString.substring(0, 10)}...`);\n  }\n\n  return headers;\n}\n\nasync function getTargetUrl(\n  req: IncomingMessage,\n  options: NormalizedProxyOptions,\n): Promise<string> {\n  // Handle router function\n  if (options.router) {\n    if (typeof options.router === \"function\") {\n      const target = await options.router(req);\n      // Validate router returned URL\n      try {\n        new URL(target);\n        return target;\n      } catch (_err) {\n        throw new Error(`Router returned invalid URL: ${target}`);\n      }\n    } else {\n      return options.router;\n    }\n  }\n  return options.target;\n}\n\nasync function handleBypass(\n  req: IncomingMessage,\n  res: ServerResponse,\n  options: NormalizedProxyOptions,\n  next: () => void,\n): Promise<boolean> {\n  if (!options.bypass) return false;\n\n  const result = await options.bypass(req, res, options);\n\n  if (typeof result === \"string\") {\n    // Rewrite the URL and pass to next middleware\n    req.url = result;\n    next();\n    return true;\n  }\n\n  if (result === false) {\n    // Continue with proxy\n    return false;\n  }\n\n  // If result is truthy (but not a string), skip proxy\n  if (result) {\n    next();\n    return true;\n  }\n\n  return false;\n}\n\n// HTTP/1.1 proxy handler for WebSocket and other HTTP/1.1 requests\nasync function proxyHttp1Request(\n  req: IncomingMessage,\n  res: ServerResponse,\n  options: NormalizedProxyOptions,\n  _next: () => void,\n): Promise<void> {\n  const startTime = Date.now();\n  logger?.debug(`Starting HTTP/1.1 proxy for ${req.method} ${req.url}`);\n\n  // Debug log headers for WebSocket\n  if (options.ws && logger) {\n    logger.debug(`HTTP/1.1 proxy headers for WebSocket request:`);\n    logger.debug(`  Upgrade: ${req.headers.upgrade}`);\n    logger.debug(`  Connection: ${req.headers.connection}`);\n    logger.debug(`  Sec-WebSocket-Key: ${req.headers[\"sec-websocket-key\"]}`);\n    logger.debug(`  All headers: ${JSON.stringify(Object.keys(req.headers))}`);\n  }\n\n  // Get target URL\n  let targetBase: string;\n  try {\n    targetBase = await getTargetUrl(req, options);\n  } catch (err) {\n    logger?.error(\"Failed to get target URL for HTTP/1.1 request\", err);\n    res.statusCode = 500;\n    res.end(\"Internal Server Error: Invalid proxy target\");\n    return;\n  }\n\n  if (!req.url) {\n    res.statusCode = 400;\n    res.end(\"Bad Request: Missing URL\");\n    return;\n  }\n\n  let targetUrl: URL;\n  try {\n    targetUrl = new URL(req.url, targetBase);\n  } catch (err) {\n    logger?.error(\n      `Invalid URL construction: ${req.url} with base ${targetBase}`,\n      err,\n    );\n    res.statusCode = 400;\n    res.end(\"Bad Request: Invalid URL\");\n    return;\n  }\n\n  // Apply path rewrite if provided\n  if (options.rewrite) {\n    const rewritten = options.rewrite(targetUrl.pathname);\n    targetUrl.pathname = rewritten;\n  }\n\n  const isSecure = targetUrl.protocol === \"https:\";\n  const port = targetUrl.port || (isSecure ? 443 : 80);\n\n  // Create HTTP/1.1 connection\n  const http = isSecure\n    ? await import(\"node:https\")\n    : await import(\"node:http\");\n\n  // Filter out HTTP/2 pseudo-headers and connection-specific headers\n  const filteredHeaders: Record<string, string | string[]> = {};\n  const forbiddenHeaders = [\n    \"keep-alive\",\n    \"transfer-encoding\",\n    \"proxy-connection\",\n    \"te\",\n    \"trailer\",\n  ];\n\n  // For WebSocket requests, preserve upgrade and connection headers\n  const isWebSocketRequest =\n    options.ws || req.headers.upgrade?.toLowerCase() === \"websocket\";\n\n  if (!isWebSocketRequest) {\n    forbiddenHeaders.push(\"connection\", \"upgrade\");\n  }\n\n  for (const [key, value] of Object.entries(req.headers)) {\n    // Skip HTTP/2 pseudo-headers (start with :)\n    if (key.startsWith(\":\")) continue;\n    // Skip forbidden headers\n    if (forbiddenHeaders.includes(key.toLowerCase())) continue;\n\n    if (value) {\n      filteredHeaders[key] = value;\n    }\n  }\n\n  const proxyReqOptions = {\n    hostname: targetUrl.hostname,\n    port: Number(port),\n    path: targetUrl.pathname + targetUrl.search,\n    method: req.method,\n    headers: filteredHeaders,\n    rejectUnauthorized: options.secure !== false,\n  };\n\n  // Update headers\n  if (options.changeOrigin) {\n    proxyReqOptions.headers.host = targetUrl.host;\n  }\n\n  if (options.headers) {\n    Object.assign(proxyReqOptions.headers, options.headers);\n  }\n\n  if (options.xfwd) {\n    if (req.socket.remoteAddress) {\n      proxyReqOptions.headers[\"x-forwarded-for\"] = req.socket.remoteAddress;\n    }\n    proxyReqOptions.headers[\"x-forwarded-proto\"] = isTLSSocket(req.socket)\n      ? \"https\"\n      : \"http\";\n    proxyReqOptions.headers[\"x-forwarded-host\"] = req.headers.host || \"\";\n    proxyReqOptions.headers[\"x-forwarded-port\"] = String(req.socket.localPort);\n  }\n\n  if (options.auth && !proxyReqOptions.headers.authorization) {\n    const authString = Buffer.from(options.auth).toString(\"base64\");\n    proxyReqOptions.headers.authorization = `Basic ${authString}`;\n  }\n\n  const proxyReq = http.request(proxyReqOptions, (proxyRes) => {\n    const endTime = Date.now();\n    const duration = endTime - startTime;\n\n    logProxyRequest(\n      logger,\n      req.method || \"GET\",\n      req.url || \"\",\n      targetUrl.href,\n      proxyRes.statusCode || 0,\n      duration,\n    );\n\n    // Handle cookie rewriting\n    if (options.cookieDomainRewrite || options.cookiePathRewrite) {\n      const setCookieHeader = proxyRes.headers[\"set-cookie\"];\n      if (setCookieHeader) {\n        const cookies = Array.isArray(setCookieHeader)\n          ? setCookieHeader\n          : [setCookieHeader];\n        proxyRes.headers[\"set-cookie\"] = cookies.map((cookie) =>\n          rewriteCookie(\n            String(cookie),\n            options.cookieDomainRewrite || false,\n            options.cookiePathRewrite || false,\n          ),\n        );\n      }\n    }\n\n    // Copy status and headers\n    res.writeHead(proxyRes.statusCode || 200, proxyRes.headers);\n\n    // Pipe the response\n    proxyRes.pipe(res);\n  });\n\n  proxyReq.on(\"error\", (err) => {\n    const endTime = Date.now();\n    const duration = endTime - startTime;\n\n    logger?.error(`HTTP/1.1 proxy error: ${err.message}`, err);\n    logProxyRequest(\n      logger,\n      req.method || \"GET\",\n      req.url || \"\",\n      targetUrl.href,\n      502,\n      duration,\n    );\n\n    if (!res.headersSent) {\n      res.writeHead(502, { \"Content-Type\": \"text/plain\" });\n      res.end(\"Bad Gateway\");\n    }\n  });\n\n  // Handle timeout\n  if (options.timeout || options.proxyTimeout) {\n    const timeout = options.proxyTimeout || options.timeout || 120000;\n    proxyReq.setTimeout(timeout, () => {\n      proxyReq.destroy();\n      if (!res.headersSent) {\n        res.writeHead(504, { \"Content-Type\": \"text/plain\" });\n        res.end(\"Gateway Timeout\");\n      }\n    });\n  }\n\n  // Forward request body if present\n  if (req.method !== \"GET\" && req.method !== \"HEAD\") {\n    req.pipe(proxyReq);\n  } else {\n    proxyReq.end();\n  }\n}\n\nasync function proxyHttp2Request(\n  req: IncomingMessage,\n  res: ServerResponse,\n  options: NormalizedProxyOptions,\n  next: () => void,\n): Promise<void> {\n  const startTime = Date.now();\n\n  // Check bypass\n  if (await handleBypass(req, res, options, next)) {\n    return;\n  }\n\n  // Debug log headers for WebSocket routes\n  if (options.ws && logger) {\n    logger.debug(`Request to WebSocket route ${req.url}:`);\n    logger.debug(`  Method: ${req.method}`);\n    logger.debug(`  Upgrade: ${req.headers.upgrade}`);\n    logger.debug(`  Connection: ${req.headers.connection}`);\n    logger.debug(`  Sec-WebSocket-Key: ${req.headers[\"sec-websocket-key\"]}`);\n    logger.debug(\n      `  Sec-WebSocket-Version: ${req.headers[\"sec-websocket-version\"]}`,\n    );\n  }\n\n  // Check if this is a WebSocket upgrade request\n  // Note: Some WebSocket clients first send a POST request before upgrading\n  const isWebSocketRequest =\n    req.headers.upgrade?.toLowerCase() === \"websocket\" ||\n    (req.headers.connection?.toLowerCase().includes(\"upgrade\") &&\n      req.headers[\"sec-websocket-key\"]) ||\n    req.headers[\"sec-websocket-version\"];\n\n  // For WebSocket-enabled routes, always use HTTP/1.1 as WebSocket requires it\n  if (options.ws) {\n    logger?.info(`Using HTTP/1.1 for WebSocket-enabled route ${req.url}`);\n    return proxyHttp1Request(req, res, options, next);\n  }\n\n  if (isWebSocketRequest) {\n    // This shouldn't happen if ws:true is set, but handle it anyway\n    logger?.warn(`WebSocket upgrade detected but ws:false for ${req.url}`);\n    return proxyHttp1Request(req, res, options, next);\n  }\n\n  // Get target URL (may be dynamic via router)\n  let targetBase: string;\n  try {\n    targetBase = await getTargetUrl(req, options);\n  } catch (err) {\n    logger?.error(\"Failed to get target URL\", err);\n    res.statusCode = 500;\n    res.end(\"Internal Server Error: Invalid proxy target\");\n    return;\n  }\n\n  // Check if we should force HTTP/1.1 or auto-detect\n  if (options.forceHttp1) {\n    logger?.info(`Using HTTP/1.1 for ${req.url} (forceHttp1 enabled)`);\n    return proxyHttp1Request(req, res, options, next);\n  }\n\n  if (options.autoDetectProtocol) {\n    const targetUrl = new URL(targetBase);\n    const origin = `${targetUrl.protocol}//${targetUrl.host}`;\n    const useHttp2 = await supportsHttp2(origin, options.secure !== false);\n\n    if (!useHttp2) {\n      logger?.info(\n        `Using HTTP/1.1 for ${req.url} - origin ${origin} does not support HTTP/2`,\n      );\n      return proxyHttp1Request(req, res, options, next);\n    }\n    logger?.debug(\n      `Using HTTP/2 for ${req.url} - origin ${origin} supports HTTP/2`,\n    );\n  } else {\n    logger?.debug(`Using HTTP/2 for ${req.url} (default protocol)`);\n  }\n\n  if (!req.url) {\n    res.statusCode = 400;\n    res.end(\"Bad Request: Missing URL\");\n    return;\n  }\n\n  let targetUrl: URL;\n  try {\n    targetUrl = new URL(req.url, targetBase);\n  } catch (err) {\n    logger?.error(\n      `Invalid URL construction: ${req.url} with base ${targetBase}`,\n      err,\n    );\n    res.statusCode = 400;\n    res.end(\"Bad Request: Invalid URL\");\n    return;\n  }\n\n  // Apply path rewrite if provided\n  if (options.rewrite) {\n    const rewritten = options.rewrite(targetUrl.pathname);\n    targetUrl.pathname = rewritten;\n  }\n\n  const origin = `${targetUrl.protocol}//${targetUrl.host}`;\n\n  // Helper function to actually create and handle the stream\n  const createAndHandleStream = () => {\n    const session = connectionPool.getAvailableSession(origin, options);\n    if (!session) {\n      // No available session capacity, queue the request\n      const queued = requestQueue.enqueue(origin, req, res, () => {\n        processProxiedRequest(req, res, options, targetUrl, origin, startTime);\n      });\n\n      if (!queued) {\n        res.statusCode = 503;\n        res.end(\"Service Unavailable: Request queue full\");\n      }\n      return;\n    }\n\n    processProxiedRequest(\n      req,\n      res,\n      options,\n      targetUrl,\n      origin,\n      startTime,\n      session,\n    );\n  };\n\n  createAndHandleStream();\n}\n\n// Separate function to process the proxied request\nfunction processProxiedRequest(\n  req: IncomingMessage,\n  res: ServerResponse,\n  options: NormalizedProxyOptions,\n  targetUrl: URL,\n  origin: string,\n  startTime: number,\n  session?: ClientHttp2Session,\n): void {\n  if (!session) {\n    // Try to get a session again (for queued requests)\n    try {\n      session = connectionPool.getSession(origin, options);\n    } catch (err) {\n      logger?.error(`Failed to get HTTP/2 session for ${origin}`, err);\n      res.statusCode = 502;\n      res.end(\"Bad Gateway: Failed to establish HTTP/2 connection\");\n      return;\n    }\n  }\n\n  const headers = createHttp2Headers(req, targetUrl, options);\n  headers[HTTP2_HEADER_PATH] = targetUrl.pathname + targetUrl.search;\n\n  // Set timeout if specified\n  const timeout = options.proxyTimeout || options.timeout || 120000;\n\n  // Track stream creation\n  connectionPool.incrementActiveStreams(origin);\n\n  let stream: ClientHttp2Stream;\n  try {\n    stream = session.request(headers, {\n      endStream: req.method === \"GET\" || req.method === \"HEAD\",\n    });\n  } catch (err) {\n    connectionPool.decrementActiveStreams(origin);\n\n    // Check if this is a stream limit error\n    if (\n      err instanceof Error &&\n      err.message?.includes(\"ERR_HTTP2_OUT_OF_STREAMS\")\n    ) {\n      // Queue the request\n      const queued = requestQueue.enqueue(origin, req, res, () => {\n        processProxiedRequest(req, res, options, targetUrl, origin, startTime);\n      });\n\n      if (!queued) {\n        res.statusCode = 503;\n        res.end(\"Service Unavailable: Request queue full\");\n      }\n      return;\n    }\n\n    logger?.error(`Failed to create HTTP/2 stream for ${origin}`, err);\n    res.statusCode = 502;\n    res.end(\"Bad Gateway: Failed to create HTTP/2 stream\");\n    return;\n  }\n\n  // Handle timeout\n  const timeoutHandle = setTimeout(() => {\n    stream.close(constants.NGHTTP2_CANCEL);\n    if (!res.headersSent) {\n      res.writeHead(504, { \"Content-Type\": \"text/plain\" });\n      res.end(\"Gateway Timeout\");\n    }\n  }, timeout);\n\n  stream.on(\"error\", (err) => {\n    clearTimeout(timeoutHandle);\n    const endTime = Date.now();\n    const duration = endTime - startTime;\n    logger.error(`HTTP/2 stream error: ${err.message}`, err);\n    logProxyRequest(\n      logger,\n      req.method || \"GET\",\n      req.url || \"\",\n      targetUrl.href,\n      502,\n      duration,\n    );\n    if (!res.headersSent) {\n      res.writeHead(502, { \"Content-Type\": \"text/plain\" });\n      res.end(\"Bad Gateway\");\n    }\n\n    // Decrement active streams on error\n    connectionPool.decrementActiveStreams(origin);\n\n    // Process next queued request if any\n    const nextRequest = requestQueue.dequeue(origin);\n    if (nextRequest) {\n      nextRequest.callback();\n    }\n  });\n\n  stream.on(\"response\", (responseHeaders: IncomingHttpHeaders) => {\n    clearTimeout(timeoutHandle);\n    const endTime = Date.now();\n    const duration = endTime - startTime;\n\n    const status = Number(responseHeaders[HTTP2_HEADER_STATUS]) || 200;\n    logProxyRequest(\n      logger,\n      req.method || \"GET\",\n      req.url || \"\",\n      targetUrl.href,\n      status,\n      duration,\n    );\n\n    // Handle redirects\n    if (options.followRedirects && status >= 300 && status < 400) {\n      const location = responseHeaders[HTTP2_HEADER_LOCATION];\n      if (location) {\n        // Rewrite location header if needed\n        const locationUrl = new URL(location as string, targetUrl);\n        const rewrittenLocation = locationUrl.href.replace(\n          targetUrl.origin,\n          \"\",\n        );\n        responseHeaders[HTTP2_HEADER_LOCATION] = rewrittenLocation;\n      }\n    }\n\n    // Filter out HTTP/2 pseudo-headers\n    const cleanHeaders: OutgoingHttpHeaders = {};\n    for (const [key, value] of Object.entries(responseHeaders)) {\n      if (!key.startsWith(\":\")) {\n        // Handle cookie rewriting\n        if (\n          key === \"set-cookie\" &&\n          (options.cookieDomainRewrite || options.cookiePathRewrite)\n        ) {\n          const cookies = Array.isArray(value) ? value : [value];\n          cleanHeaders[key] = cookies.map((cookie) =>\n            rewriteCookie(\n              String(cookie),\n              options.cookieDomainRewrite || false,\n              options.cookiePathRewrite || false,\n            ),\n          );\n        } else {\n          cleanHeaders[key] = value;\n        }\n      }\n    }\n\n    // Handle Server-Sent Events\n    if (\n      options.sse &&\n      cleanHeaders[\"content-type\"]?.includes(\"text/event-stream\")\n    ) {\n      cleanHeaders[\"cache-control\"] = \"no-cache\";\n      cleanHeaders.connection = \"keep-alive\";\n      cleanHeaders[\"x-accel-buffering\"] = \"no\"; // Disable Nginx buffering\n    }\n\n    // Custom response handling\n    if (options.selfHandleResponse) {\n      // Let the user handle the response\n      if (options.configure) {\n        options.configure(stream, options);\n      }\n      return;\n    }\n\n    res.writeHead(status, cleanHeaders);\n    stream.pipe(res);\n  });\n\n  stream.on(\"close\", () => {\n    clearTimeout(timeoutHandle);\n\n    // Decrement active streams and process queued requests\n    connectionPool.decrementActiveStreams(origin);\n\n    // Process next queued request if any\n    const nextRequest = requestQueue.dequeue(origin);\n    if (nextRequest) {\n      // Process the queued request\n      nextRequest.callback();\n    }\n  });\n\n  // Forward request body if present\n  if (req.method !== \"GET\" && req.method !== \"HEAD\") {\n    req.pipe(stream);\n  } else {\n    stream.end();\n  }\n}\n\n// WebSocket support\nasync function handleWebSocketUpgrade(\n  req: IncomingMessage,\n  socket: net.Socket,\n  head: Buffer,\n  options: NormalizedProxyOptions,\n): Promise<void> {\n  const socketId = `${req.socket.remoteAddress}:${req.socket.remotePort}`;\n  logger?.debug(`[WS ${socketId}] Starting WebSocket upgrade for ${req.url}`);\n\n  // Get target URL asynchronously without blocking\n  getTargetUrl(req, options)\n    .then((targetBase) => {\n      if (!req.url) {\n        socket.end(\"HTTP/1.1 400 Bad Request\\r\\n\\r\\n\");\n        return;\n      }\n\n      let targetUrl: URL;\n      try {\n        targetUrl = new URL(req.url, targetBase);\n      } catch (err) {\n        logger?.error(\n          `Invalid WebSocket URL: ${req.url} with base ${targetBase}`,\n          err,\n        );\n        socket.end(\"HTTP/1.1 400 Bad Request\\r\\n\\r\\n\");\n        return;\n      }\n\n      // Continue with the WebSocket upgrade\n      performWebSocketUpgrade(req, socket, head, options, targetUrl, socketId);\n    })\n    .catch((err) => {\n      logger?.error(\n        `[WS ${socketId}] Failed to get target URL for WebSocket`,\n        err,\n      );\n      socket.end(\"HTTP/1.1 500 Internal Server Error\\r\\n\\r\\n\");\n    });\n}\n\n// Separate function to perform the actual WebSocket upgrade\nfunction performWebSocketUpgrade(\n  req: IncomingMessage,\n  socket: net.Socket,\n  head: Buffer,\n  options: NormalizedProxyOptions,\n  targetUrl: URL,\n  socketId: string,\n): void {\n  const isSecure =\n    targetUrl.protocol === \"https:\" || targetUrl.protocol === \"wss:\";\n  const port = targetUrl.port || (isSecure ? 443 : 80);\n\n  const proxySocket = isSecure\n    ? tls.connect({\n        port: Number(port),\n        host: targetUrl.hostname,\n        rejectUnauthorized: options.secure !== false,\n      })\n    : net.connect({\n        port: Number(port),\n        host: targetUrl.hostname,\n      });\n\n  // Build WebSocket upgrade request more efficiently\n  // Pre-calculate header count to avoid array resizing\n  const headerEntries = Object.entries(req.headers);\n  const headerCount = headerEntries.length + 3; // +3 for GET, Host, and empty lines\n  const headers = new Array(headerCount);\n\n  // Add required headers\n  headers[0] = `GET ${targetUrl.pathname}${targetUrl.search} HTTP/1.1`;\n  headers[1] = `Host: ${targetUrl.host}`;\n\n  // Forward original headers (skip host)\n  let headerIndex = 2;\n  for (const [key, value] of headerEntries) {\n    if (key.toLowerCase() !== \"host\") {\n      headers[headerIndex++] = `${key}: ${value}`;\n    }\n  }\n\n  // Add empty lines to end headers\n  headers[headerIndex++] = \"\";\n  headers[headerIndex] = \"\";\n\n  proxySocket.on(\"connect\", () => {\n    logger?.debug(`[WS ${socketId}] Connected to target ${targetUrl.host}`);\n    proxySocket.write(headers.join(\"\\r\\n\"));\n    if (head?.length) proxySocket.write(head);\n  });\n\n  proxySocket.on(\"data\", (data) => {\n    socket.write(data);\n  });\n\n  socket.on(\"data\", (data) => {\n    proxySocket.write(data);\n  });\n\n  proxySocket.on(\"error\", (err) => {\n    logger?.error(\n      `[WS ${socketId}] WebSocket proxy error: ${err.message}`,\n      err,\n    );\n    socket.destroy();\n  });\n\n  socket.on(\"error\", (err) => {\n    logger?.error(`[WS ${socketId}] Client socket error: ${err.message}`);\n    proxySocket.destroy();\n  });\n\n  proxySocket.on(\"close\", () => {\n    logger?.debug(`[WS ${socketId}] Target connection closed`);\n    socket.end();\n  });\n\n  socket.on(\"close\", () => {\n    logger?.debug(`[WS ${socketId}] Client connection closed`);\n    proxySocket.end();\n  });\n}\n\nexport interface Http2ProxyPluginOptions {\n  proxy?: Record<string, string | ProxyOptions>;\n\n  // Global connection pool settings\n  maxSessions?: number; // Maximum number of HTTP/2 sessions (default: 100)\n  sessionMaxAge?: number; // Session idle timeout in ms (default: 300000 - 5 minutes)\n  connectionTimeout?: number; // Initial connection timeout in ms (default: 10000)\n\n  // Global request queue settings\n  maxQueueSize?: number; // Maximum queued requests across all origins (default: 100)\n  queueTimeout?: number; // Queue timeout in ms (default: 30000)\n\n  // Global timeout defaults\n  defaultTimeout?: number; // Default timeout for all proxies in ms (default: 120000)\n  defaultProxyTimeout?: number; // Default proxy-specific timeout in ms\n}\n\nexport function http2ProxyPlugin(\n  options: Http2ProxyPluginOptions = {},\n): Plugin {\n  let config: ResolvedConfig;\n  let savedProxyConfig: Record<string, string | ProxyOptions> = {};\n\n  // Extract global defaults for timeout settings\n  const globalDefaults = {\n    defaultTimeout: options.defaultTimeout,\n    defaultProxyTimeout: options.defaultProxyTimeout,\n  };\n\n  // Use plugin options proxy config if provided\n  if (options.proxy) {\n    savedProxyConfig = { ...options.proxy };\n    console.log(\n      `[vite-plugin-http2-proxy] Using plugin proxy config for ${Object.keys(savedProxyConfig).length} routes`,\n    );\n  }\n\n  return {\n    name: \"vite-plugin-http2-proxy\",\n    enforce: \"pre\", // Run before other plugins\n\n    config(userConfig) {\n      // Only intercept Vite proxy config if we don't have plugin-level config\n      if (!options.proxy && userConfig.server?.proxy) {\n        savedProxyConfig = { ...userConfig.server.proxy };\n        userConfig.server.proxy = {};\n        console.log(\n          `[vite-plugin-http2-proxy] Intercepted Vite proxy config for ${Object.keys(savedProxyConfig).length} routes`,\n        );\n      } else if (userConfig.server?.proxy) {\n        // Clear Vite's proxy config to prevent HTTP/1.1 downgrade\n        userConfig.server.proxy = {};\n        console.log(\n          `[vite-plugin-http2-proxy] Cleared Vite proxy config to prevent HTTP/1.1 downgrade`,\n        );\n      }\n    },\n\n    configResolved(resolvedConfig) {\n      config = resolvedConfig;\n      logger = createLogger(\"vite:http2-proxy\", config);\n\n      // Initialize connection pool with global settings\n      connectionPool = new Http2ConnectionPool(logger, {\n        maxSessions: options.maxSessions,\n        sessionMaxAge: options.sessionMaxAge,\n        connectionTimeout: options.connectionTimeout,\n      });\n\n      // Initialize request queue with global settings\n      requestQueue = new RequestQueue(logger, {\n        maxQueueSize: options.maxQueueSize,\n        queueTimeout: options.queueTimeout,\n      });\n    },\n\n    configureServer(server) {\n      if (Object.keys(savedProxyConfig).length === 0) {\n        return;\n      }\n\n      logger?.info(\n        `HTTP/2 proxy plugin setting up ${Object.keys(savedProxyConfig).length} proxy routes`,\n      );\n      logger?.debug(\n        `Proxy routes: ${Object.keys(savedProxyConfig).join(\", \")}`,\n      );\n\n      // Handle WebSocket upgrades\n      server.httpServer?.on(\"upgrade\", (req, socket, head) => {\n        logger?.debug(\n          `WebSocket upgrade request: ${req.url} from ${req.socket.remoteAddress}`,\n        );\n\n        for (const [context, proxyOptions] of Object.entries(\n          savedProxyConfig,\n        )) {\n          const opts = normalizeProxyOptions(proxyOptions, globalDefaults);\n\n          if (!opts.ws) continue;\n\n          let shouldProxy = false;\n\n          // Check if request matches the context\n          if (context.startsWith(\"^\")) {\n            // RegExp pattern - use cached version\n            const pattern = getCachedRegExp(context);\n            shouldProxy = req.url ? pattern.test(req.url) : false;\n          } else {\n            // String prefix\n            shouldProxy = req.url?.startsWith(context);\n          }\n\n          if (shouldProxy) {\n            logger?.info(\n              `WebSocket upgrade matched route ${context} for ${req.url}`,\n            );\n\n            // Handle the WebSocket upgrade without blocking the event loop\n            handleWebSocketUpgrade(req, socket, head, opts).catch((err) => {\n              logger?.error(`WebSocket proxy error for ${req.url}:`, err);\n              socket.destroy();\n            });\n\n            break;\n          }\n        }\n\n        // If no route matched, log it\n        const routeMatched = Object.entries(savedProxyConfig).some(\n          ([context, opts]) => {\n            if (!req.url) return false;\n            const normalized = normalizeProxyOptions(opts, globalDefaults);\n            return (\n              normalized.ws &&\n              (context.startsWith(\"^\")\n                ? getCachedRegExp(context).test(req.url)\n                : req.url.startsWith(context))\n            );\n          },\n        );\n\n        if (!req.url || !routeMatched) {\n          logger?.debug(\n            `No WebSocket route matched for upgrade request: ${req.url}`,\n          );\n        }\n      });\n\n      // Process each proxy configuration\n      for (const [context, proxyOptions] of Object.entries(savedProxyConfig)) {\n        const opts = normalizeProxyOptions(proxyOptions, globalDefaults);\n\n        // Create middleware for this proxy context\n        server.middlewares.use(async (req, res, next) => {\n          if (!req.url) return next();\n\n          let shouldProxy = false;\n\n          // Check if request matches the context\n          if (context.startsWith(\"^\")) {\n            // RegExp pattern - use cached version\n            const pattern = getCachedRegExp(context);\n            shouldProxy = pattern.test(req.url);\n          } else {\n            // String prefix\n            shouldProxy = req.url.startsWith(context);\n          }\n\n          if (!shouldProxy) {\n            return next();\n          }\n\n          try {\n            await proxyHttp2Request(req, res, opts, next);\n          } catch (err) {\n            config.logger.error(`HTTP/2 proxy error: ${err}`);\n            if (!res.headersSent) {\n              res.writeHead(500, { \"Content-Type\": \"text/plain\" });\n              res.end(\"Internal Server Error\");\n            }\n          }\n        });\n      }\n\n      // Clean up HTTP/2 sessions when dev server closes\n      server.httpServer?.on(\"close\", () => {\n        logger?.info(\"Dev server closing, cleaning up HTTP/2 sessions\");\n        requestQueue.clear();\n        connectionPool.close();\n        http2SupportMap.clear();\n      });\n\n      // Also handle SIGINT/SIGTERM for graceful shutdown\n      const cleanup = () => {\n        logger?.info(\"Received shutdown signal, cleaning up HTTP/2 sessions\");\n        requestQueue.clear();\n        connectionPool.close();\n        http2SupportMap.clear();\n      };\n\n      process.once(\"SIGINT\", cleanup);\n      process.once(\"SIGTERM\", cleanup);\n    },\n\n    buildEnd() {\n      // Clean up HTTP/2 sessions and request queue\n      requestQueue.clear();\n      connectionPool.close();\n      // Clear protocol detection cache\n      http2SupportMap.clear();\n    },\n  };\n}\n\nexport default http2ProxyPlugin;\n"],"names":["logger","connect","debuglog","_a","constants","targetUrl","origin","tls","net"],"mappings":"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"}