import { expect, test } from "bun:test"; import { RequestInit } from "undici-types"; // https://github.com/oven-sh/bun/issues/4718 test("fetch() calls request.method & request.url getters on subclass", async () => { class MyRequest extends Request { constructor(input: string, init?: RequestInit, actual_url?: string) { super(input, init); Object.defineProperty(this, "url", { get() { return actual_url; }, }); Object.defineProperty(this, "headers", { get() { return { "X-My-Header": "123", }; }, }); } // @ts-ignore get method() { return "POST"; } } using server = Bun.serve({ fetch(req) { return new Response(req.method, { headers: req.headers }); }, port: 0, }); const request = new MyRequest("https://example.com", {}, server.url.href); expect(request.method).toBe("POST"); const response = await fetch(request); expect(await response.text()).toBe("POST"); expect(response.headers.get("X-My-Header")).toBe("123"); }); test("fetch() with subclass containing invalid HTTP headers throws without crashing", async () => { class MyRequest extends Request { constructor(input: string, init?: RequestInit, actual_url?: string) { super(input, init); Object.defineProperty(this, "url", { get() { return actual_url; }, }); Object.defineProperty(this, "headers", { get() { return { "[I am not a valid header]!": "123", }; }, }); } // @ts-ignore get method() { return "POST"; } } const request = new MyRequest("https://example.com", {}, "https://example.com"); expect(request.method).toBe("POST"); expect(() => fetch(request)).toThrow("Invalid header name"); // quick gc test for (let i = 0; i < 1e4; i++) { try { fetch(request); } catch (e) {} } expect(() => fetch(request)).toThrow("Invalid header name"); });