From 1932b2ca61f084629654941efdd09fd1b971efed Mon Sep 17 00:00:00 2001 From: Tam Nhu Tran Date: Wed, 13 May 2026 09:13:28 -0400 Subject: [PATCH] fix(proxy): strip stale encoding from upstream error responses --- .../transformers/sse-stream-transformer.ts | 1 + .../proxy/messages-edge-cases.test.ts | 31 +++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/proxy/transformers/sse-stream-transformer.ts b/src/proxy/transformers/sse-stream-transformer.ts index dff2b7ce..1f15b8cb 100644 --- a/src/proxy/transformers/sse-stream-transformer.ts +++ b/src/proxy/transformers/sse-stream-transformer.ts @@ -50,6 +50,7 @@ export function createAnthropicErrorResponse( ): Response { const responseHeaders = new Headers(headers); responseHeaders.set('Content-Type', 'application/json'); + responseHeaders.delete('Content-Encoding'); responseHeaders.delete('Content-Length'); return new Response(JSON.stringify(createAnthropicErrorPayload(type, message)), { diff --git a/tests/integration/proxy/messages-edge-cases.test.ts b/tests/integration/proxy/messages-edge-cases.test.ts index faefb833..5e63d90d 100644 --- a/tests/integration/proxy/messages-edge-cases.test.ts +++ b/tests/integration/proxy/messages-edge-cases.test.ts @@ -3,6 +3,7 @@ import * as fs from 'fs'; import * as http from 'http'; import * as os from 'os'; import * as path from 'path'; +import * as zlib from 'zlib'; import { startOpenAICompatProxyServer } from '../../../src/proxy/server/proxy-server'; import type { OpenAICompatProfileConfig } from '../../../src/proxy/profile-router'; @@ -144,6 +145,36 @@ describe('openai proxy message edge cases', () => { }); }); + it('does not leak upstream content-encoding onto synthesized error responses', async () => { + const compressed = zlib.gzipSync( + JSON.stringify({ error: { message: 'invalid upstream request' } }) + ); + + await startProxyWithHandler((_req, res) => { + res.writeHead(400, { + 'Content-Type': 'application/json', + 'Content-Encoding': 'gzip', + 'Content-Length': String(compressed.length), + }); + res.end(compressed); + }); + + const response = await requestProxy({ + model: 'hf-model', + messages: [{ role: 'user', content: 'hello' }], + }); + + expect(response.status).toBe(400); + expect(response.headers.get('content-encoding')).toBeNull(); + await expect(response.json()).resolves.toMatchObject({ + type: 'error', + error: { + type: 'invalid_request_error', + message: 'invalid upstream request', + }, + }); + }); + it('returns api_error when the upstream JSON response has no usable choices', async () => { await startProxyWithHandler((_req, res) => { res.writeHead(200, { 'Content-Type': 'application/json' });