import { test } from "bun:test"; import { once } from "events"; import { request } from "http"; import { AddressInfo, Server } from "net"; const fixture = "node-http-transfer-encoding-fixture.ts"; test(`should not duplicate transfer-encoding header`, async () => { const { resolve, promise } = Promise.withResolvers(); const tcpServer = new Server(); tcpServer.listen(0, "127.0.0.1"); await once(tcpServer, "listening"); tcpServer.on("connection", async socket => { const requestHeader = await once(socket, "data").then(data => data.toString()); queueMicrotask(() => { socket.write("HTTP/1.1 200 OK\r\nConnection: close\r\nContent-Length: 0\r\n\r\n"); socket.end(resolve); }); const httpHeadersArray = requestHeader .split("\r\n") .slice(1) // Skip the first line (HTTP method line) .map(line => line.trim()) .filter((_, index, arr) => index < arr.indexOf("")) .reduce( (headers, line) => { const [key, value] = line.split(/\s*:\s*/); return [...headers, { [key.toLowerCase()]: value }]; }, [] as { [key: string]: string }[], ); const transferEncodingHeaders = httpHeadersArray.filter(header => header["transfer-encoding"]); if (transferEncodingHeaders.length > 1) { throw new Error(`Duplicate 'transfer-encoding' header found: ${JSON.stringify(transferEncodingHeaders)}`); } }); const serverAddress = tcpServer.address() as AddressInfo; const chunkedRequest = request({ host: "localhost", port: serverAddress.port, path: "/", method: "PUT", agent: false, headers: { "transfer-encoding": "chunked", }, }); // Requires multiple chunks to trigger streaming behavior chunkedRequest.write("Hello, World!"); chunkedRequest.end("Goodbye, World!"); return promise; });