import { type IncomingHttpHeaders, type IncomingMessage, type OutgoingHttpHeaders, type ServerResponse } from 'node:http'; import type { Duplex } from 'node:stream'; import { TERMINAL_VIEW_FORWARD_HEADER } from '../core/terminal-control-grant.js'; import type { TerminalControlManager, TerminalDashboardActor } from './terminal-control.js'; export declare const TERMINAL_CONTROL_HEADER = "x-botmux-terminal-control"; export { TERMINAL_VIEW_FORWARD_HEADER }; /** Covers daemon wake-up (up to 10s) plus a bounded worker handshake. Cleared * as soon as response/upgrade headers arrive, so live streams stay unbounded. */ export declare const TERMINAL_UPSTREAM_RESPONSE_TIMEOUT_MS = 30000; /** * P1-2:upgrade 请求收到非 101 回应 = 一次拒绝,不是长连接。清掉唯一那道计时器 * 之后,一个不结束 body 的上游能把上游 socket 与浏览器 socket 一起挂死,没有任 * 何东西会回收它们。所以这条路保留总时限 + idle 时限(只有 idle 时限时,每 N 秒 * 滴一个字节就能永久续命),并给拒绝体加一个上限——预览那一跳早就有了。 */ export declare const TERMINAL_UPGRADE_REJECTION_TIMEOUT_MS = 15000; export declare const TERMINAL_UPGRADE_REJECTION_IDLE_TIMEOUT_MS = 10000; export declare const MAX_TERMINAL_UPGRADE_REJECTION_BYTES: number; export interface TerminalFrontProxyOptions { resolvePort(sessionId: string): number | undefined; resolveActor(req: IncomingMessage): TerminalDashboardActor | null; control: TerminalControlManager; /** P1-5: resolve which auth session a bound `?viewToken=` read capability * belongs to (null for anything that is not a valid bound capability for * this session). Lets the proxy refuse revoked capabilities and index the * bridged socket for logout-time closing. */ viewCapabilityAuthSession?(sessionId: string, viewToken: string): string | null; /** P1-5: liveness of the auth session behind a bound capability. `false` * means logout/expiry already revoked it — the request is refused even * though the worker's stateless check would still accept the signature. */ isAuthSessionLive?(authSessionId: string): boolean; /** P1-5: countersign an accepted view capability for the loopback hop. Only * emitted after liveness passed, so the header IS the statement "the * component holding the revocation state let this one through". Without it * the worker refuses the capability, which is what makes a raw view URL * aimed at the worker port or the daemon's own `/s/` proxy fail closed. */ viewCapabilityForwardProof?(viewToken: string): string | undefined; } export declare function parseTerminalFrontPath(pathname: string): { sessionId: string; } | null; /** * Authenticated Dashboard requests are converted to one signed loopback grant. * Client-supplied cookies/role/grant headers are removed first. Token/viewToken * query capabilities remain supported for legacy direct links and are handled * independently by the worker. */ export declare function terminalForwardHeaders(headers: IncomingHttpHeaders, grant: string | undefined, options?: { stripBrowserCredentials?: boolean; }): OutgoingHttpHeaders; export declare function createTerminalFrontProxy(options: TerminalFrontProxyOptions): { handleHttp(req: IncomingMessage, res: ServerResponse, url: URL): boolean; handleUpgrade(req: IncomingMessage, socket: Duplex, head: Buffer): boolean; }; //# sourceMappingURL=terminal-front-proxy.d.ts.map