mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-04 07:44:06 +00:00
fix(proxy): cap connect tunnel timeouts
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { EventEmitter } from "node:events";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { MAX_TIMER_TIMEOUT_MS } from "../../shared/number-coercion.js";
|
||||
|
||||
class FakeSocket extends EventEmitter {
|
||||
public readonly writes: string[] = [];
|
||||
@@ -349,4 +350,27 @@ describe("openHttpConnectTunnel", () => {
|
||||
await rejected;
|
||||
expect(proxySocket.destroyed).toBe(true);
|
||||
});
|
||||
|
||||
it("caps oversized CONNECT timeouts before arming the watchdog", async () => {
|
||||
vi.useFakeTimers();
|
||||
const proxySocket = new FakeSocket();
|
||||
setNextNetSocket(proxySocket);
|
||||
const { openHttpConnectTunnel } = await import("./http-connect-tunnel.js");
|
||||
|
||||
const tunnel = openHttpConnectTunnel({
|
||||
proxyUrl: new URL("http://proxy.example:8080"),
|
||||
targetHost: "api.push.apple.com",
|
||||
targetPort: 443,
|
||||
timeoutMs: Number.MAX_SAFE_INTEGER,
|
||||
});
|
||||
|
||||
await vi.advanceTimersByTimeAsync(1);
|
||||
expect(proxySocket.destroyed).toBe(false);
|
||||
|
||||
await vi.advanceTimersByTimeAsync(MAX_TIMER_TIMEOUT_MS - 1);
|
||||
await expect(tunnel).rejects.toThrow(
|
||||
`Proxy CONNECT failed via http://proxy.example:8080: Proxy CONNECT timed out after ${MAX_TIMER_TIMEOUT_MS}ms`,
|
||||
);
|
||||
expect(proxySocket.destroyed).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import * as net from "node:net";
|
||||
import * as tls from "node:tls";
|
||||
import { resolveTimerTimeoutMs } from "../../shared/number-coercion.js";
|
||||
import type { ManagedProxyTlsOptions } from "./proxy/proxy-tls.js";
|
||||
|
||||
export type HttpConnectTunnelParams = {
|
||||
@@ -11,6 +12,7 @@ export type HttpConnectTunnelParams = {
|
||||
};
|
||||
|
||||
const MAX_CONNECT_RESPONSE_HEADER_BYTES = 16 * 1024;
|
||||
const MIN_CONNECT_TIMEOUT_MS = 1;
|
||||
|
||||
type ProxySocket = net.Socket | tls.TLSSocket;
|
||||
type ConnectResponseBuffer = Buffer;
|
||||
@@ -159,11 +161,14 @@ class HttpConnectTunnelAttempt {
|
||||
}
|
||||
|
||||
private startTimeout(): void {
|
||||
const timeoutMs = this.params.timeoutMs;
|
||||
if (timeoutMs && Number.isFinite(timeoutMs) && timeoutMs > 0) {
|
||||
const timeoutMs =
|
||||
this.params.timeoutMs === undefined || this.params.timeoutMs <= 0
|
||||
? undefined
|
||||
: resolveTimerTimeoutMs(this.params.timeoutMs, MIN_CONNECT_TIMEOUT_MS);
|
||||
if (timeoutMs !== undefined) {
|
||||
this.timeout = setTimeout(() => {
|
||||
this.fail(new Error(`Proxy CONNECT timed out after ${Math.trunc(timeoutMs)}ms`));
|
||||
}, Math.trunc(timeoutMs));
|
||||
this.fail(new Error(`Proxy CONNECT timed out after ${timeoutMs}ms`));
|
||||
}, timeoutMs);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user