- Add full Telegram bot functionality with Z.AI API integration
- Implement 4 tools: Bash, FileEdit, WebSearch, Git
- Add 3 agents: Code Reviewer, Architect, DevOps Engineer
- Add 6 skills for common coding tasks
- Add systemd service file for 24/7 operation
- Add nginx configuration for HTTPS webhook
- Add comprehensive documentation
- Implement WebSocket server for real-time updates
- Add logging system with Winston
- Add environment validation
🤖 zCode CLI X - Agentic coder with Z.AI + Telegram integration
117 lines
5.1 KiB
TypeScript
117 lines
5.1 KiB
TypeScript
/**
|
|
* Parent/upstream HTTP proxy support.
|
|
*
|
|
* When SRT runs in an environment that requires an HTTP proxy for outbound
|
|
* internet access (e.g. inside a VM on a host behind a corporate proxy),
|
|
* SRT's own proxies must chain through that upstream rather than connecting
|
|
* directly.
|
|
*
|
|
* This module provides:
|
|
* - config resolution (explicit config -> HTTP_PROXY/HTTPS_PROXY/NO_PROXY env)
|
|
* - NO_PROXY matching (hostname suffix + CIDR via net.BlockList). Follows
|
|
* golang.org/x/net/http/httpproxy semantics for suffix matching. Note:
|
|
* port-specific NO_PROXY entries (e.g. `host:8080`) are matched by host
|
|
* only; the port is ignored.
|
|
* - a generic CONNECT-tunnel helper that works over Unix socket, TCP, or TLS
|
|
*/
|
|
import type { Socket } from 'node:net';
|
|
import type { IncomingHttpHeaders } from 'node:http';
|
|
import { BlockList } from 'node:net';
|
|
import { URL } from 'node:url';
|
|
import type { ParentProxyConfig } from './sandbox-config.js';
|
|
export interface ResolvedParentProxy {
|
|
httpUrl?: URL;
|
|
httpsUrl?: URL;
|
|
noProxy: NoProxyRules;
|
|
}
|
|
interface NoProxyRules {
|
|
all: boolean;
|
|
suffixes: string[];
|
|
cidr: BlockList;
|
|
}
|
|
/**
|
|
* Resolve the parent proxy config, falling back to the SRT process's own
|
|
* environment. Note: SRT later overwrites HTTP_PROXY etc. in the *sandboxed
|
|
* child's* environment to point at itself — but process.env here reflects the
|
|
* environment SRT itself was launched with, which is what we want.
|
|
*/
|
|
export declare function resolveParentProxy(cfg?: ParentProxyConfig): ResolvedParentProxy | undefined;
|
|
/**
|
|
* Returns true if the given host should bypass the parent proxy and connect
|
|
* directly. Always bypasses loopback.
|
|
*
|
|
* NB: the port is not consulted. NO_PROXY entries of the form `host:port` are
|
|
* matched by host only (the port suffix is stripped during parsing).
|
|
*/
|
|
export declare function shouldBypassParentProxy(resolved: ResolvedParentProxy, host: string): boolean;
|
|
/**
|
|
* Pick which parent proxy URL to use for a given destination.
|
|
*/
|
|
export declare function selectParentProxyUrl(resolved: ResolvedParentProxy, opts: {
|
|
isHttps: boolean;
|
|
}): URL | undefined;
|
|
export interface ConnectTunnelOptions {
|
|
/** Establish the transport to the proxy. */
|
|
dial(): Socket;
|
|
/** Fired when the transport is ready to write (e.g. 'connect'/'secureConnect'). */
|
|
readyEvent: 'connect' | 'secureConnect';
|
|
destHost: string;
|
|
destPort: number;
|
|
authHeader?: string;
|
|
timeoutMs?: number;
|
|
}
|
|
/**
|
|
* Generic CONNECT-tunnel: dial a proxy transport (unix/tcp/tls), send
|
|
* `CONNECT host:port`, wait for a 2xx, and resolve with the tunnelled socket.
|
|
* Validates destHost to prevent CRLF injection from untrusted callers.
|
|
*/
|
|
export declare function openConnectTunnel(opts: ConnectTunnelOptions): Promise<Socket>;
|
|
/**
|
|
* Open a CONNECT tunnel through a parent HTTP(S) proxy specified by URL.
|
|
* Thin wrapper around openConnectTunnel that dials TCP or TLS based on the
|
|
* proxy URL scheme.
|
|
*/
|
|
export declare function connectViaParentProxy(proxyUrl: URL, destHost: string, destPort: number): Promise<Socket>;
|
|
export declare function proxyAuthHeader(proxyUrl: URL): string | undefined;
|
|
/**
|
|
* Strip hop-by-hop and proxy-specific headers before forwarding upstream.
|
|
* Also strips any headers named in the incoming `Connection` header, per
|
|
* RFC 7230 §6.1.
|
|
*/
|
|
export declare function stripHopByHop(h: IncomingHttpHeaders): IncomingHttpHeaders;
|
|
/** Remove surrounding square brackets from an IPv6 literal. */
|
|
export declare function stripBrackets(host: string): string;
|
|
/** Redact userinfo from a URL for safe logging. */
|
|
export declare function redactUrl(u: URL | undefined): string;
|
|
/**
|
|
* Hostname validation: accepts DNS names and IP literals (without zone IDs).
|
|
* Primary purpose is to block control characters (CRLF injection, null-byte
|
|
* DNS truncation) and zone-identifier allowlist bypasses from reaching the
|
|
* wire or the allowlist matcher.
|
|
*
|
|
* IPv6 zone IDs (`fe80::1%eth0`) are rejected because `isIP` accepts a very
|
|
* permissive zone charset including dots — `::ffff:1.2.3.4%x.allowed.com`
|
|
* would pass `isIP`, pass a `.endsWith('.allowed.com')` wildcard check, and
|
|
* then connect to 1.2.3.4 when the OS discards the bogus scope.
|
|
*/
|
|
export declare function isValidHost(h: string): boolean;
|
|
/**
|
|
* Canonicalize a host string via the WHATWG URL parser so that string
|
|
* comparisons in the allowlist agree with what `net.connect()`/`getaddrinfo()`
|
|
* will actually dial. This normalizes:
|
|
* - inet_aton shorthand (`127.1` → `127.0.0.1`, `2130706433` → `127.0.0.1`)
|
|
* - hex/octal octets (`0x7f.0.0.1` → `127.0.0.1`)
|
|
* - IPv6 compression (`0:0:0:0:0:0:0:1` → `::1`)
|
|
* - trailing dots, case, brackets
|
|
*
|
|
* Returns undefined if the input is not a valid URL host.
|
|
*/
|
|
export declare function canonicalizeHost(h: string): string | undefined;
|
|
/**
|
|
* Dial `host:port` directly with a bounded timeout. Shared by the HTTP and
|
|
* SOCKS direct-connect paths so they get the same timeout behaviour as the
|
|
* CONNECT-tunnelled paths.
|
|
*/
|
|
export declare function dialDirect(host: string, port: number, timeoutMs?: number): Promise<Socket>;
|
|
export {};
|
|
//# sourceMappingURL=parent-proxy.d.ts.map
|