






















@@ -76,6 +76,67 @@ describe("buildGuardedModelFetch", () => {
7676);
7777});
787879+it("scopes fake-IP DNS exemptions to the configured provider host", async () => {
80+const { buildGuardedModelFetch } = await import("./provider-transport-fetch.js");
81+const model = {
82+id: "gpt-5.4",
83+provider: "openai",
84+api: "openai-responses",
85+baseUrl: "https://api.openai.com/v1",
86+} as unknown as Model<"openai-responses">;
87+88+const fetcher = buildGuardedModelFetch(model);
89+await fetcher("https://api.openai.com/v1/responses", { method: "POST" });
90+91+const policy = fetchWithSsrFGuardMock.mock.calls[0]?.[0]?.policy;
92+expect(policy).toEqual({
93+allowRfc2544BenchmarkRange: true,
94+allowIpv6UniqueLocalRange: true,
95+hostnameAllowlist: ["api.openai.com"],
96+});
97+expect(policy?.allowedHostnames).toBeUndefined();
98+expect(policy?.allowPrivateNetwork).toBeUndefined();
99+expect(policy?.dangerouslyAllowPrivateNetwork).toBeUndefined();
100+});
101+102+it("does not apply fake-IP exemptions to non-provider hosts", async () => {
103+const { buildGuardedModelFetch } = await import("./provider-transport-fetch.js");
104+const model = {
105+id: "gpt-5.4",
106+provider: "openai",
107+api: "openai-responses",
108+baseUrl: "https://api.openai.com/v1",
109+} as unknown as Model<"openai-responses">;
110+111+const fetcher = buildGuardedModelFetch(model);
112+await fetcher("https://uploads.openai.com/v1/files", { method: "POST" });
113+114+const policy = fetchWithSsrFGuardMock.mock.calls[0]?.[0]?.policy;
115+expect(policy).toBeUndefined();
116+});
117+118+it("merges explicit private-network opt-in into the provider-host fake-IP policy", async () => {
119+resolveProviderRequestPolicyConfigMock.mockReturnValueOnce({ allowPrivateNetwork: true });
120+const { buildGuardedModelFetch } = await import("./provider-transport-fetch.js");
121+const model = {
122+id: "qwen3:32b",
123+provider: "ollama",
124+api: "ollama",
125+baseUrl: "http://10.0.0.5:11434",
126+} as unknown as Model<"ollama">;
127+128+const fetcher = buildGuardedModelFetch(model);
129+await fetcher("http://10.0.0.5:11434/api/chat", { method: "POST" });
130+131+const policy = fetchWithSsrFGuardMock.mock.calls[0]?.[0]?.policy;
132+expect(policy).toEqual({
133+allowRfc2544BenchmarkRange: true,
134+allowIpv6UniqueLocalRange: true,
135+hostnameAllowlist: ["10.0.0.5"],
136+allowPrivateNetwork: true,
137+});
138+});
139+79140it("threads explicit transport timeouts into the shared guarded fetch seam", async () => {
80141const { buildGuardedModelFetch } = await import("./provider-transport-fetch.js");
81142const model = {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。