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
This commit is contained in:
Liz
2023-09-30 01:13:49 +02:00
committed by GitHub
parent 72bdd380af
commit fa7d7bd1e4
2 changed files with 24 additions and 13 deletions

View File

@@ -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();

View File

@@ -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();