diff --git a/src/http.zig b/src/http.zig index 0812b7be9d..9078fe0f70 100644 --- a/src/http.zig +++ b/src/http.zig @@ -2337,6 +2337,10 @@ pub fn hashHeaderConst(comptime name: string) u64 { return hasher.final(); } +// for each request we need this hashs, putting on top of the file to avoid exceeding comptime quota limit +const authorization_header_hash = hashHeaderConst("Authorization"); +const proxy_authorization_header_hash = hashHeaderConst("Proxy-Authorization"); +const cookie_header_hash = hashHeaderConst("Cookie"); pub const Encoding = enum { identity, @@ -4578,20 +4582,36 @@ pub fn handleResponseMetadata( // locationURL’s origin, then for each headerName of CORS // non-wildcard request-header name, delete headerName from // request’s header list. + // var authorization_removed = false; + // var proxy_authorization_removed = false; + // var cookie_removed = false; + // References: + // https://github.com/nodejs/undici/commit/6805746680d27a5369d7fb67bc05f95a28247d75#diff-ea7696549c3a0b60a4a7e07cc79b6d4e950c7cb1068d47e368a510967d77e7e5R206 + // https://github.com/denoland/deno/commit/7456255cd10286d71363fc024e51b2662790448a#diff-6e35f325f0a4e1ae3214fde20c9108e9b3531df5d284ba3c93becb99bbfc48d5R70 if (!is_same_origin and this.header_entries.len > 0) { - const authorization_header_hash = comptime hashHeaderConst("Authorization"); - for (this.header_entries.items(.name), 0..) |name_ptr, i| { - const name = this.headerStr(name_ptr); - if (name.len == "Authorization".len) { - const hash = hashHeaderName(name); - if (hash == authorization_header_hash) { - this.header_entries.orderedRemove(i); - break; + const headers_to_remove: []const struct { + name: []const u8, + hash: u64, + } = &.{ + .{ .name = "Authorization", .hash = authorization_header_hash }, + .{ .name = "Proxy-Authorization", .hash = proxy_authorization_header_hash }, + .{ .name = "Cookie", .hash = cookie_header_hash }, + }; + inline for (headers_to_remove) |header| { + const names = this.header_entries.items(.name); + + for (names, 0..) |name_ptr, i| { + const name = this.headerStr(name_ptr); + if (name.len == header.name.len) { + const hash = hashHeaderName(name); + if (hash == header.hash) { + this.header_entries.orderedRemove(i); + break; + } } } } } - this.state.flags.is_redirect_pending = true; if (this.method.hasRequestBody()) { this.state.flags.resend_request_body_on_redirect = true; diff --git a/test/js/web/fetch/fetch.test.ts b/test/js/web/fetch/fetch.test.ts index 6e8fc443ef..e976032f7e 100644 --- a/test/js/web/fetch/fetch.test.ts +++ b/test/js/web/fetch/fetch.test.ts @@ -1697,15 +1697,18 @@ describe("should strip headers", () => { }); }, }); - const { headers, url, redirected } = await fetch(`http://${server1.hostname}:${server1.port}/redirect`, { method: "GET", headers: { "Authorization": "yes", + "Proxy-Authorization": "yes", + "Cookie": "yes", }, }); expect(headers.get("Authorization")).toBeNull(); + expect(headers.get("Proxy-Authorization")).toBeNull(); + expect(headers.get("Cookie")).toBeNull(); expect(url).toEndWith("/redirected"); expect(redirected).toBe(true); }); @@ -1735,10 +1738,14 @@ it("same-origin status code 302 should not strip headers", async () => { method: "GET", headers: { "Authorization": "yes", + "Proxy-Authorization": "yes", + "Cookie": "yes", }, }); expect(headers.get("Authorization")).toEqual("yes"); + expect(headers.get("Proxy-Authorization")).toEqual("yes"); + expect(headers.get("Cookie")).toEqual("yes"); expect(url).toEndWith("/redirected"); expect(redirected).toBe(true); });