
























11// Google tests cover media understanding provider.video plugin behavior.
2+import { createServer, type Server } from "node:http";
23import {
34createRequestCaptureJsonFetch,
45installPinnedHostnameTestHooks,
@@ -10,6 +11,49 @@ import { resolveGoogleGenerativeAiHttpRequestConfig } from "./runtime-api.js";
10111112installPinnedHostnameTestHooks();
121314+const LOOPBACK_RESPONSE_BYTES = 18 * 1024 * 1024;
15+16+async function listenLoopbackServer(server: Server): Promise<number> {
17+return await new Promise((resolve, reject) => {
18+server.once("error", reject);
19+server.listen(0, "127.0.0.1", () => {
20+server.off("error", reject);
21+const address = server.address();
22+if (!address || typeof address === "string") {
23+reject(new Error("expected loopback TCP address"));
24+return;
25+}
26+resolve(address.port);
27+});
28+});
29+}
30+31+function createOversizedJsonServer(): { server: Server; closed: Promise<number> } {
32+let resolveClosed: (sentBytes: number) => void = () => {};
33+const closed = new Promise<number>((resolve) => {
34+resolveClosed = resolve;
35+});
36+const server = createServer((_req, res) => {
37+let sentBytes = 0;
38+const chunk = Buffer.alloc(64 * 1024, 0x20);
39+res.writeHead(200, { "content-type": "application/json" });
40+const timer = setInterval(() => {
41+if (sentBytes >= LOOPBACK_RESPONSE_BYTES) {
42+clearInterval(timer);
43+res.end();
44+return;
45+}
46+sentBytes += chunk.length;
47+res.write(chunk);
48+}, 1);
49+res.on("close", () => {
50+clearInterval(timer);
51+resolveClosed(sentBytes);
52+});
53+});
54+return { server, closed };
55+}
56+1357describe("describeGeminiVideo", () => {
1458it("respects case-insensitive x-goog-api-key overrides", async () => {
1559let seenKey: string | null = null;
@@ -114,6 +158,29 @@ describe("describeGeminiVideo", () => {
114158);
115159});
116160161+it("bounds oversized video JSON responses and closes the stream early", async () => {
162+const { server, closed } = createOversizedJsonServer();
163+const port = await listenLoopbackServer(server);
164+const fetchFn = withFetchPreconnect(async () =>
165+fetch(`http://127.0.0.1:${port}/google-video-json`),
166+);
167+168+try {
169+await expect(
170+describeGeminiVideo({
171+buffer: Buffer.from("video-bytes"),
172+fileName: "clip.mp4",
173+apiKey: "test-key",
174+timeoutMs: 1500,
175+ fetchFn,
176+}),
177+).rejects.toThrow(/JSON response exceeds 16777216 bytes/u);
178+await expect(closed).resolves.toBeLessThan(LOOPBACK_RESPONSE_BYTES);
179+} finally {
180+server.close();
181+}
182+});
183+117184it("rejects non-Google video base URLs before sending authenticated requests", async () => {
118185await expect(
119186describeGeminiVideo({
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。