fix(embeddings): strip stale Content-Encoding headers from upstream response (#2477)

Integrated into release/v3.8.2
This commit is contained in:
Leonid Bondarenko
2026-05-21 21:52:34 +03:00
committed by GitHub
parent 8d43cbd53c
commit 731e766136
2 changed files with 75 additions and 2 deletions

View File

@@ -23,6 +23,7 @@ import { createRequestLogger } from "../utils/requestLogger.ts";
import { isDetailedLoggingEnabled } from "@/lib/db/detailedLogs";
import { getCallLogPipelineCaptureStreamChunks } from "@/lib/logEnv";
import { toJsonErrorPayload } from "@/shared/utils/upstreamError";
import { stripStaleEncodingHeaders } from "../utils/upstreamResponseHeaders.ts";
interface ClientRawRequest {
endpoint: string;
@@ -215,7 +216,7 @@ export async function handleEmbedding({
success: false,
status: response.status,
error: errorText,
headers: response.headers,
headers: stripStaleEncodingHeaders(response.headers),
};
}
@@ -266,7 +267,7 @@ export async function handleEmbedding({
return {
success: true,
data: normalizedResponse,
headers: response.headers,
headers: stripStaleEncodingHeaders(response.headers),
};
} catch (err) {
if (log) {

View File

@@ -215,3 +215,75 @@ test("handleEmbedding surfaces upstream failures", async () => {
globalThis.fetch = originalFetch;
}
});
test("handleEmbedding strips content-encoding header on success path", async () => {
const originalFetch = globalThis.fetch;
globalThis.fetch = async () =>
new Response(
JSON.stringify({
data: [{ object: "embedding", embedding: [0.1, 0.2], index: 0 }],
usage: { prompt_tokens: 5, total_tokens: 5 },
}),
{
status: 200,
headers: {
"content-type": "application/json",
"content-encoding": "gzip",
"content-length": "512",
"transfer-encoding": "chunked",
"x-request-id": "abc123",
},
}
);
try {
const result = await handleEmbedding({
body: { model: "openai/text-embedding-3-small", input: "test" },
credentials: { apiKey: "openai-key" },
log: null,
});
assert.equal(result.success, true);
assert.strictEqual(result.headers.get("content-encoding"), null);
assert.strictEqual(result.headers.get("content-length"), null);
assert.strictEqual(result.headers.get("transfer-encoding"), null);
assert.strictEqual(result.headers.get("x-request-id"), "abc123");
assert.strictEqual(result.headers.get("content-type"), "application/json");
} finally {
globalThis.fetch = originalFetch;
}
});
test("handleEmbedding strips content-encoding header on error path", async () => {
const originalFetch = globalThis.fetch;
globalThis.fetch = async () =>
new Response("upstream error", {
status: 502,
headers: {
"content-type": "text/plain",
"content-encoding": "gzip",
"content-length": "42",
"transfer-encoding": "chunked",
"x-trace-id": "trace-456",
},
});
try {
const result = await handleEmbedding({
body: { model: "openai/text-embedding-3-small", input: "test" },
credentials: { apiKey: "openai-key" },
log: null,
});
assert.equal(result.success, false);
assert.equal(result.status, 502);
assert.strictEqual(result.headers.get("content-encoding"), null);
assert.strictEqual(result.headers.get("content-length"), null);
assert.strictEqual(result.headers.get("transfer-encoding"), null);
assert.strictEqual(result.headers.get("x-trace-id"), "trace-456");
} finally {
globalThis.fetch = originalFetch;
}
});