diff --git a/.changeset/empty-ghosts-sip.md b/.changeset/empty-ghosts-sip.md new file mode 100644 index 000000000..3073fc3ac --- /dev/null +++ b/.changeset/empty-ghosts-sip.md @@ -0,0 +1,5 @@ +--- +"openapi-fetch": minor +--- + +Do not treat Content-Length=0 as empty when Transfer-Encoding is chunked diff --git a/packages/openapi-fetch/src/index.js b/packages/openapi-fetch/src/index.js index 9c0de61f9..a83623f70 100644 --- a/packages/openapi-fetch/src/index.js +++ b/packages/openapi-fetch/src/index.js @@ -237,7 +237,11 @@ export default function createClient(clientOptions) { const contentLength = response.headers.get("Content-Length"); // handle empty content - if (response.status === 204 || request.method === "HEAD" || contentLength === "0") { + if ( + response.status === 204 || + request.method === "HEAD" || + (contentLength === "0" && !response.headers.get("Transfer-Encoding")?.includes("chunked")) + ) { return response.ok ? { data: undefined, response } : { error: undefined, response }; } diff --git a/packages/openapi-fetch/test/common/response.test.ts b/packages/openapi-fetch/test/common/response.test.ts index cdedabc4c..72f4f1f6e 100644 --- a/packages/openapi-fetch/test/common/response.test.ts +++ b/packages/openapi-fetch/test/common/response.test.ts @@ -204,4 +204,36 @@ describe("response", () => { } }); }); + + describe("chunked transfer with zero Content-Length", () => { + test("does not treat chunked body with Content-Length: 0 as empty", async () => { + const mock = [{ id: 1 }]; + const client = createObservedClient({}, async () => + Response.json(mock, { + status: 200, + headers: { "Content-Length": "0", "Transfer-Encoding": "chunked" }, + }), + ); + + const { data, error, response } = await client.GET("/resources"); + expect(response.status).toBe(200); + expect(error).toBeUndefined(); + expect(data).toEqual(mock); + }); + }); + describe("Content-Length: 0 without chunked", () => { + test("treats as empty when not chunked", async () => { + const client = createObservedClient({}, async () => + Response.json([{ id: 1 }], { + status: 200, + headers: { "Content-Length": "0" }, + }), + ); + + const { data, error, response } = await client.GET("/resources"); + expect(response.status).toBe(200); + expect(error).toBeUndefined(); + expect(data).toBeUndefined(); + }); + }); });