Skip to content

Commit d94d57a

Browse files
committed
[SEA-NodeJS] feat(kernel): support the explicit proxy ConnectionOption on the kernel backend
Map the public Thrift-shaped `ConnectionOptions.proxy` (`{protocol, host, port, auth}`) onto the kernel napi binding's `proxy?: string`, so the SAME proxy connection option that works on the Thrift backend now also routes kernel/SEA traffic through a proxy. `buildKernelProxyOptions` composes `protocol://[user:pass@]host:port`, percent-encoding any `auth.{username,password}` into the URL userinfo so credentials with reserved characters survive; the kernel parses the userinfo off and applies it as proxy basic-auth. Wired into `buildKernelConnectionOptions` alongside the TLS / HTTP option builders. The regenerated napi contract (`native/kernel/index.d.ts`) carries the new `proxy?: string` and `socketTimeoutMs?: number` fields exposed by the kernel PR (databricks/databricks-sql-kernel#129). Note: env-var proxying (`HTTPS_PROXY` / `HTTP_PROXY` / `NO_PROXY`) already worked on the kernel backend (reqwest honours it natively); this adds the *programmatic* path for callers who cannot set process env vars. Verified end-to-end via mitmproxy against a live serverless warehouse: explicit `proxy` option (no env var) routes all SEA calls through the proxy; a dead proxy port fails the connection (proving the proxy is used). Co-authored-by: Isaac Signed-off-by: Madhavendra Rathore <madhavendra.rathore@databricks.com>
1 parent 3358a61 commit d94d57a

2 files changed

Lines changed: 53 additions & 30 deletions

File tree

lib/kernel/KernelAuth.ts

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,9 +192,22 @@ export interface KernelHttpOptions {
192192
customHeaders?: Array<{ name: string; value: string }>;
193193
}
194194

195+
/**
196+
* HTTP(S) proxy forwarded to the napi binding's `ConnectionOptions.proxy`
197+
* (kernel `ProxyConfig.url`). The public `ConnectionOptions.proxy` is the
198+
* Thrift-shaped `{protocol, host, port, auth}`; `buildKernelProxyOptions`
199+
* composes a single proxy URL string (with any basic-auth credentials
200+
* percent-encoded into the `userinfo`) so the SAME connection option works
201+
* on both backends. The napi contract takes a flat `proxy?: string`.
202+
*/
203+
export interface KernelProxyOptions {
204+
proxy?: string;
205+
}
206+
195207
export type KernelNativeConnectionOptions = KernelSessionDefaults &
196208
KernelTlsOptions &
197209
KernelHttpOptions &
210+
KernelProxyOptions &
198211
(
199212
| {
200213
hostName: string;
@@ -514,6 +527,29 @@ export function buildKernelRetryOptions(config: {
514527
return out;
515528
}
516529

530+
/**
531+
* Map the public `ConnectionOptions.proxy` (`{protocol, host, port, auth}` —
532+
* the same shape the Thrift backend accepts) onto the kernel's napi
533+
* `proxy?: string`. Composes `protocol://[user:pass@]host:port`, percent-
534+
* encoding any `auth.{username,password}` into the URL `userinfo` so
535+
* credentials containing reserved characters (`@`, `:`, `/`) survive intact —
536+
* the kernel parses the userinfo off and applies it as basic-auth. The kernel
537+
* accepts only `http://` / `https://`; a SOCKS protocol surfaces a clear
538+
* kernel error at connect (reqwest SOCKS support is not compiled in).
539+
*/
540+
export function buildKernelProxyOptions(options: ConnectionOptions): KernelProxyOptions {
541+
const { proxy } = options;
542+
if (!proxy) {
543+
return {};
544+
}
545+
const { username, password } = proxy.auth ?? {};
546+
const userinfo =
547+
username !== undefined ? `${encodeURIComponent(username)}:${encodeURIComponent(password ?? '')}@` : '';
548+
return {
549+
proxy: `${proxy.protocol}://${userinfo}${proxy.host}:${proxy.port}`,
550+
};
551+
}
552+
517553
export function buildKernelConnectionOptions(options: ConnectionOptions): KernelNativeConnectionOptions {
518554
const { authType } = options as { authType?: string };
519555

@@ -523,7 +559,8 @@ export function buildKernelConnectionOptions(options: ConnectionOptions): Kernel
523559
intervalsAsString: boolean;
524560
maxConnections?: number;
525561
} & KernelTlsOptions &
526-
KernelHttpOptions = {
562+
KernelHttpOptions &
563+
KernelProxyOptions = {
527564
hostName: options.host,
528565
httpPath: prependSlash(options.path),
529566
// Match the NodeJS Thrift driver, which surfaces INTERVAL columns as
@@ -539,6 +576,8 @@ export function buildKernelConnectionOptions(options: ConnectionOptions): Kernel
539576
...buildKernelTlsOptions(options),
540577
// HTTP headers (caller `customHeaders` + composed `User-Agent`).
541578
...buildKernelHttpOptions(options),
579+
// HTTP(S) proxy — the same `ConnectionOptions.proxy` the Thrift path uses.
580+
...buildKernelProxyOptions(options),
542581
};
543582

544583
// kernel-only pool sizing; read via cast to match how this function reads the

native/kernel/index.d.ts

Lines changed: 13 additions & 29 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)