mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 15:30:47 +00:00
fix: preserve nested proxy handles
This commit is contained in:
@@ -6,16 +6,23 @@ export type ActiveManagedProxyRegistration = {
|
||||
};
|
||||
|
||||
let activeProxyUrl: ActiveManagedProxyUrl | undefined;
|
||||
let activeProxyRegistrationCount = 0;
|
||||
|
||||
export function registerActiveManagedProxyUrl(proxyUrl: URL): ActiveManagedProxyRegistration {
|
||||
const normalizedProxyUrl = new URL(proxyUrl.href);
|
||||
if (activeProxyUrl !== undefined) {
|
||||
throw new Error(
|
||||
"proxy: cannot activate a managed proxy while another proxy is active; " +
|
||||
"stop the current proxy before changing proxy.proxyUrl.",
|
||||
);
|
||||
if (activeProxyUrl.href !== normalizedProxyUrl.href) {
|
||||
throw new Error(
|
||||
"proxy: cannot activate a managed proxy while another proxy is active; " +
|
||||
"stop the current proxy before changing proxy.proxyUrl.",
|
||||
);
|
||||
}
|
||||
activeProxyRegistrationCount += 1;
|
||||
return { proxyUrl: activeProxyUrl, stopped: false };
|
||||
}
|
||||
|
||||
activeProxyUrl = new URL(proxyUrl.href);
|
||||
activeProxyUrl = normalizedProxyUrl;
|
||||
activeProxyRegistrationCount = 1;
|
||||
return { proxyUrl: activeProxyUrl, stopped: false };
|
||||
}
|
||||
|
||||
@@ -26,7 +33,11 @@ export function stopActiveManagedProxyRegistration(
|
||||
return;
|
||||
}
|
||||
registration.stopped = true;
|
||||
if (activeProxyUrl?.href === registration.proxyUrl.href) {
|
||||
if (activeProxyUrl?.href !== registration.proxyUrl.href) {
|
||||
return;
|
||||
}
|
||||
activeProxyRegistrationCount = Math.max(0, activeProxyRegistrationCount - 1);
|
||||
if (activeProxyRegistrationCount === 0) {
|
||||
activeProxyUrl = undefined;
|
||||
}
|
||||
}
|
||||
@@ -37,4 +48,5 @@ export function getActiveManagedProxyUrl(): ActiveManagedProxyUrl | undefined {
|
||||
|
||||
export function _resetActiveManagedProxyStateForTests(): void {
|
||||
activeProxyUrl = undefined;
|
||||
activeProxyRegistrationCount = 0;
|
||||
}
|
||||
|
||||
@@ -291,7 +291,7 @@ describe("startProxy", () => {
|
||||
expect((global as Record<string, unknown>)["GLOBAL_AGENT"]).toBeUndefined();
|
||||
});
|
||||
|
||||
it("rejects overlapping handles with the same managed proxy URL", async () => {
|
||||
it("keeps same-url overlapping handles active until the final stop", async () => {
|
||||
const patchedHttpRequest = vi.fn() as unknown as typeof http.request;
|
||||
const patchedHttpGet = vi.fn() as unknown as typeof http.get;
|
||||
const patchedHttpsRequest = vi.fn() as unknown as typeof https.request;
|
||||
@@ -311,13 +311,19 @@ describe("startProxy", () => {
|
||||
enabled: true,
|
||||
proxyUrl: "http://127.0.0.1:3128",
|
||||
});
|
||||
const secondHandle = await startProxy({
|
||||
enabled: true,
|
||||
proxyUrl: "http://127.0.0.1:3128",
|
||||
});
|
||||
|
||||
await expect(
|
||||
startProxy({
|
||||
enabled: true,
|
||||
proxyUrl: "http://127.0.0.1:3128",
|
||||
}),
|
||||
).rejects.toThrow("cannot activate a managed proxy");
|
||||
expect(mockForceResetGlobalDispatcher).toHaveBeenCalledOnce();
|
||||
expect(mockBootstrapGlobalAgent).toHaveBeenCalledOnce();
|
||||
expect(http.request).toBe(patchedHttpRequest);
|
||||
expect(https.request).toBe(patchedHttpsRequest);
|
||||
expect(process.env["HTTP_PROXY"]).toBe("http://127.0.0.1:3128");
|
||||
expect(process.env["OPENCLAW_PROXY_ACTIVE"]).toBe("1");
|
||||
|
||||
await stopProxy(secondHandle);
|
||||
|
||||
expect(http.request).toBe(patchedHttpRequest);
|
||||
expect(https.request).toBe(patchedHttpsRequest);
|
||||
|
||||
@@ -343,6 +343,9 @@ function stopActiveProxyRegistration(registration: ActiveManagedProxyRegistratio
|
||||
return;
|
||||
}
|
||||
stopActiveManagedProxyRegistration(registration);
|
||||
if (getActiveManagedProxyUrl()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const restoreSnapshot = baseProxyEnvSnapshot ?? captureProxyEnv();
|
||||
baseProxyEnvSnapshot = null;
|
||||
@@ -390,11 +393,21 @@ export async function startProxy(config: ProxyConfig | undefined): Promise<Proxy
|
||||
}
|
||||
|
||||
const proxyUrl = resolveProxyUrl(config);
|
||||
if (getActiveManagedProxyUrl()) {
|
||||
throw new Error(
|
||||
"proxy: cannot activate a managed proxy while another proxy is active; " +
|
||||
"stop the current proxy before changing proxy.proxyUrl.",
|
||||
);
|
||||
const activeProxyUrl = getActiveManagedProxyUrl();
|
||||
if (activeProxyUrl) {
|
||||
const registration = registerActiveManagedProxyUrl(new URL(proxyUrl));
|
||||
const handle: ProxyHandle = {
|
||||
proxyUrl,
|
||||
injectedProxyUrl: proxyUrl,
|
||||
envSnapshot: baseProxyEnvSnapshot ?? captureProxyEnv(),
|
||||
stop: async () => {
|
||||
stopActiveProxyRegistration(registration);
|
||||
},
|
||||
kill: () => {
|
||||
stopActiveProxyRegistration(registration);
|
||||
},
|
||||
};
|
||||
return handle;
|
||||
}
|
||||
baseProxyEnvSnapshot ??= captureProxyEnv();
|
||||
const lifecycleBaseEnvSnapshot = baseProxyEnvSnapshot;
|
||||
|
||||
Reference in New Issue
Block a user