import { describe, it, expect, beforeAll, afterAll } from "bun:test"; const port = 3009; const url = `http://localhost:${port}`; let server; describe("Headers", async () => { // Start up a single server and reuse it between tests beforeAll(() => { server = Bun.serve({ fetch(req) { const hdr = req.headers.get("x-test"); return new Response(hdr); }, port: port, }); }); afterAll(() => { server.stop(); }); it("Headers should work", async () => { expect(await fetchContent({"x-test": "header 1"})).toBe("header 1"); }); it("Header names must be valid", async () => { expect(() => fetch(url, {headers: {"a\tb:c": "foo" }})).toThrow("Invalid header name: 'a\tb:c'"); expect(() => fetch(url, {headers: {"❤️": "foo" }})).toThrow("Invalid header name: '❤️'"); }); it("Header values must be valid", async () => { expect(() => fetch(url, {headers: {"x-test": "\0" }})).toThrow("Header 'x-test' has invalid value: '\0'"); expect(() => fetch(url, {headers: {"x-test": "❤️" }})).toThrow("Header 'x-test' has invalid value: '❤️'"); }); it("repro 1602", async () => { const origString = "😂1234".slice(3); var encoder = new TextEncoder(); var decoder = new TextDecoder(); const roundTripString = decoder.decode(encoder.encode(origString)); expect(roundTripString).toBe(origString); // This one will pass expect(await fetchContent({"x-test": roundTripString})).toBe(roundTripString); // This would hang expect(await fetchContent({"x-test": origString})).toBe(origString); }); }); async function fetchContent(headers) { const res = await fetch( url, { headers: headers }, { verbose: true } ); return await res.text(); }