diff options
author | 2023-09-30 01:13:49 +0200 | |
---|---|---|
committer | 2023-09-29 16:13:49 -0700 | |
commit | fa7d7bd1e4a701d1f5d3ec89f287f30a2dd0babb (patch) | |
tree | 53f30298dbabb6949355772db3470aa28682c118 | |
parent | 72bdd380af1739a2fccdeca4e3a196035ff58203 (diff) | |
download | bun-fa7d7bd1e4a701d1f5d3ec89f287f30a2dd0babb.tar.gz bun-fa7d7bd1e4a701d1f5d3ec89f287f30a2dd0babb.tar.zst bun-fa7d7bd1e4a701d1f5d3ec89f287f30a2dd0babb.zip |
fix: don't set default request method when creating a Request (#6154)
In the case of creating a Request with the parameters `(Request, object)`,
there was a bug that method and headers are set from the default created by
the init rather then the already present value from the request param.
This is because for a to me unknown reason the order in which the parameters
are processed is reversed.
This fixes that by adding a check which stops the defaults from being set,
unless they are explicitly passed.
Fixes: https://github.com/oven-sh/bun/issues/6144
-rw-r--r-- | src/bun.js/webcore/request.zig | 27 | ||||
-rw-r--r-- | test/js/web/fetch/fetch.test.ts | 10 |
2 files changed, 24 insertions, 13 deletions
diff --git a/src/bun.js/webcore/request.zig b/src/bun.js/webcore/request.zig index 381ae2750..7f37bea46 100644 --- a/src/bun.js/webcore/request.zig +++ b/src/bun.js/webcore/request.zig @@ -507,10 +507,9 @@ pub const Request = struct { }; const values_to_try = values_to_try_[0 .. @as(usize, @intFromBool(!is_first_argument_a_url)) + @as(usize, @intFromBool(arguments.len > 1 and arguments[1].isObject()))]; - for (values_to_try) |value| { const value_type = value.jsType(); - + const explicit_check = values_to_try.len == 2 and value_type == .FinalObject and values_to_try[1].jsType() == .DOMWrapper; if (value_type == .DOMWrapper) { if (value.as(Request)) |request| { if (values_to_try.len == 1) { @@ -625,23 +624,25 @@ pub const Request = struct { if (!fields.contains(.method) or !fields.contains(.headers)) { if (Body.Init.init(globalThis.allocator(), globalThis, value) catch null) |init| { - if (!fields.contains(.method)) { - req.method = init.method; - fields.insert(.method); + if (!explicit_check or (explicit_check and value.fastGet(globalThis, .method) != null)) { + if (!fields.contains(.method)) { + req.method = init.method; + fields.insert(.method); + } } - - if (init.headers) |headers| { - if (!fields.contains(.headers)) { - req.headers = headers; - fields.insert(.headers); - } else { - headers.deref(); + if (!explicit_check or (explicit_check and value.fastGet(globalThis, .headers) != null)) { + if (init.headers) |headers| { + if (!fields.contains(.headers)) { + req.headers = headers; + fields.insert(.headers); + } else { + headers.deref(); + } } } } } } - if (req.url.isEmpty()) { globalThis.throw("Failed to construct 'Request': url is required.", .{}); req.finalizeWithoutDeinit(); diff --git a/test/js/web/fetch/fetch.test.ts b/test/js/web/fetch/fetch.test.ts index 85e2296cd..4f7b20d3c 100644 --- a/test/js/web/fetch/fetch.test.ts +++ b/test/js/web/fetch/fetch.test.ts @@ -1241,6 +1241,16 @@ describe("Request", () => { expect(req.signal.aborted).toBe(true); }); + it("copies method (#6144)", () => { + const request = new Request("http://localhost:1337/test", { + method: "POST", + }); + const new_req = new Request(request, { + body: JSON.stringify({ message: "Hello world" }), + }); + expect(new_req.method).toBe("POST"); + }); + it("cloned signal", async () => { gc(); const controller = new AbortController(); |