aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Ciro Spaciari <ciro.spaciari@gmail.com> 2023-02-24 17:22:14 -0300
committerGravatar GitHub <noreply@github.com> 2023-02-24 12:22:14 -0800
commit1c531472c93f9d3a7b491b100803b8c0ad42d0e7 (patch)
tree729e877d8188630a4f2a431e02b88a472675a0f7
parentdc8e8450491f2485cc7c3b42fd82aaaf0f978260 (diff)
downloadbun-1c531472c93f9d3a7b491b100803b8c0ad42d0e7.tar.gz
bun-1c531472c93f9d3a7b491b100803b8c0ad42d0e7.tar.zst
bun-1c531472c93f9d3a7b491b100803b8c0ad42d0e7.zip
fix(body) Make Request/Reponse empty body to be null (#2156)
* make empty nullable * revert mistake change
-rw-r--r--src/bun.js/webcore/body.zig12
-rw-r--r--test/bun.js/fetch.test.js139
2 files changed, 92 insertions, 59 deletions
diff --git a/src/bun.js/webcore/body.zig b/src/bun.js/webcore/body.zig
index ad40c56ff..19e92d95a 100644
--- a/src/bun.js/webcore/body.zig
+++ b/src/bun.js/webcore/body.zig
@@ -363,7 +363,10 @@ pub const Body = struct {
JSC.markBinding(@src());
switch (this.*) {
- .Used, .Empty => {
+ .Empty => {
+ return JSValue.jsNull();
+ },
+ .Used => {
return JSC.WebCore.ReadableStream.empty(globalThis);
},
.InternalBlob,
@@ -435,7 +438,7 @@ pub const Body = struct {
pub fn fromJS(
globalThis: *JSGlobalObject,
- value: JSValue,
+ value: JSValue
) ?Value {
value.ensureStillAlive();
@@ -976,6 +979,10 @@ pub fn BodyMixin(comptime Type: type) type {
) callconv(.C) JSValue {
var body: *Body.Value = this.getBodyValue();
+ if (body.* == .Empty) {
+ return JSValue.jsNull();
+ }
+
if (body.* == .Used) {
// TODO: make this closed
return JSC.WebCore.ReadableStream.empty(globalThis);
@@ -997,6 +1004,7 @@ pub fn BodyMixin(comptime Type: type) type {
_: *JSC.CallFrame,
) callconv(.C) JSC.JSValue {
var value: *Body.Value = this.getBodyValue();
+
if (value.* == .Used) {
return handleBodyAlreadyUsed(globalObject);
}
diff --git a/test/bun.js/fetch.test.js b/test/bun.js/fetch.test.js
index ec903341f..1c27c53a0 100644
--- a/test/bun.js/fetch.test.js
+++ b/test/bun.js/fetch.test.js
@@ -523,33 +523,31 @@ function testBlobInterface(blobbyConstructor, hasBlobFn) {
if (withGC) gc();
});
- it(`${jsonObject.hello === true ? "latin1" : "utf16"} arrayBuffer -> json${
- withGC ? " (with gc) " : ""
- }`, async () => {
- if (withGC) gc();
- var response = blobbyConstructor(new TextEncoder().encode(JSON.stringify(jsonObject)));
- if (withGC) gc();
- expect(JSON.stringify(await response.json())).toBe(JSON.stringify(jsonObject));
- if (withGC) gc();
- });
+ it(`${jsonObject.hello === true ? "latin1" : "utf16"} arrayBuffer -> json${withGC ? " (with gc) " : ""
+ }`, async () => {
+ if (withGC) gc();
+ var response = blobbyConstructor(new TextEncoder().encode(JSON.stringify(jsonObject)));
+ if (withGC) gc();
+ expect(JSON.stringify(await response.json())).toBe(JSON.stringify(jsonObject));
+ if (withGC) gc();
+ });
- it(`${jsonObject.hello === true ? "latin1" : "utf16"} arrayBuffer -> invalid json${
- withGC ? " (with gc) " : ""
- }`, async () => {
- if (withGC) gc();
- var response = blobbyConstructor(
- new TextEncoder().encode(JSON.stringify(jsonObject) + " NOW WE ARE INVALID JSON"),
- );
- if (withGC) gc();
- var failed = false;
- try {
- await response.json();
- } catch (e) {
- failed = true;
- }
- expect(failed).toBe(true);
- if (withGC) gc();
- });
+ it(`${jsonObject.hello === true ? "latin1" : "utf16"} arrayBuffer -> invalid json${withGC ? " (with gc) " : ""
+ }`, async () => {
+ if (withGC) gc();
+ var response = blobbyConstructor(
+ new TextEncoder().encode(JSON.stringify(jsonObject) + " NOW WE ARE INVALID JSON"),
+ );
+ if (withGC) gc();
+ var failed = false;
+ try {
+ await response.json();
+ } catch (e) {
+ failed = true;
+ }
+ expect(failed).toBe(true);
+ if (withGC) gc();
+ });
it(`${jsonObject.hello === true ? "latin1" : "utf16"} text${withGC ? " (with gc) " : ""}`, async () => {
if (withGC) gc();
@@ -559,15 +557,14 @@ function testBlobInterface(blobbyConstructor, hasBlobFn) {
if (withGC) gc();
});
- it(`${jsonObject.hello === true ? "latin1" : "utf16"} arrayBuffer -> text${
- withGC ? " (with gc) " : ""
- }`, async () => {
- if (withGC) gc();
- var response = blobbyConstructor(new TextEncoder().encode(JSON.stringify(jsonObject)));
- if (withGC) gc();
- expect(await response.text()).toBe(JSON.stringify(jsonObject));
- if (withGC) gc();
- });
+ it(`${jsonObject.hello === true ? "latin1" : "utf16"} arrayBuffer -> text${withGC ? " (with gc) " : ""
+ }`, async () => {
+ if (withGC) gc();
+ var response = blobbyConstructor(new TextEncoder().encode(JSON.stringify(jsonObject)));
+ if (withGC) gc();
+ expect(await response.text()).toBe(JSON.stringify(jsonObject));
+ if (withGC) gc();
+ });
it(`${jsonObject.hello === true ? "latin1" : "utf16"} arrayBuffer${withGC ? " (with gc) " : ""}`, async () => {
if (withGC) gc();
@@ -592,30 +589,29 @@ function testBlobInterface(blobbyConstructor, hasBlobFn) {
if (withGC) gc();
});
- it(`${jsonObject.hello === true ? "latin1" : "utf16"} arrayBuffer -> arrayBuffer${
- withGC ? " (with gc) " : ""
- }`, async () => {
- if (withGC) gc();
+ it(`${jsonObject.hello === true ? "latin1" : "utf16"} arrayBuffer -> arrayBuffer${withGC ? " (with gc) " : ""
+ }`, async () => {
+ if (withGC) gc();
- var response = blobbyConstructor(new TextEncoder().encode(JSON.stringify(jsonObject)));
- if (withGC) gc();
+ var response = blobbyConstructor(new TextEncoder().encode(JSON.stringify(jsonObject)));
+ if (withGC) gc();
- const bytes = new TextEncoder().encode(JSON.stringify(jsonObject));
- if (withGC) gc();
+ const bytes = new TextEncoder().encode(JSON.stringify(jsonObject));
+ if (withGC) gc();
- const compare = new Uint8Array(await response.arrayBuffer());
- if (withGC) gc();
+ const compare = new Uint8Array(await response.arrayBuffer());
+ if (withGC) gc();
- withoutAggressiveGC(() => {
- for (let i = 0; i < compare.length; i++) {
- if (withGC) gc();
+ withoutAggressiveGC(() => {
+ for (let i = 0; i < compare.length; i++) {
+ if (withGC) gc();
- expect(compare[i]).toBe(bytes[i]);
- if (withGC) gc();
- }
+ expect(compare[i]).toBe(bytes[i]);
+ if (withGC) gc();
+ }
+ });
+ if (withGC) gc();
});
- if (withGC) gc();
- });
hasBlobFn &&
it(`${jsonObject.hello === true ? "latin1" : "utf16"} blob${withGC ? " (with gc) " : ""}`, async () => {
@@ -672,7 +668,7 @@ describe("Bun.file", () => {
it("size is Infinity on a fifo", () => {
try {
unlinkSync("/tmp/test-fifo");
- } catch (e) {}
+ } catch (e) { }
mkfifo("/tmp/test-fifo");
const { size } = Bun.file("/tmp/test-fifo");
@@ -690,14 +686,14 @@ describe("Bun.file", () => {
beforeAll(async () => {
try {
unlinkSync("/tmp/my-new-file");
- } catch {}
+ } catch { }
await Bun.write("/tmp/my-new-file", "hey");
chmodSync("/tmp/my-new-file", 0o000);
});
afterAll(() => {
try {
unlinkSync("/tmp/my-new-file");
- } catch {}
+ } catch { }
});
forEachMethod(m => () => {
@@ -710,7 +706,7 @@ describe("Bun.file", () => {
beforeAll(() => {
try {
unlinkSync("/tmp/does-not-exist");
- } catch {}
+ } catch { }
});
forEachMethod(m => async () => {
@@ -861,6 +857,12 @@ describe("Response", () => {
expect(response.status).toBe(407);
});
+ it("body nullable", () => {
+ expect(new Response(null).body).toBeNull();
+ expect(new Response(undefined).body).toBeNull();
+ expect(new Response().body).toBeNull();
+ });
+
it("supports headers", () => {
var response = Response.json("hello", {
headers: {
@@ -976,6 +978,29 @@ describe("Request", () => {
expect(await clone.text()).toBe("<div>hello</div>");
});
+ it("body nullable", async () => {
+ gc();
+ {
+ const req = new Request("https://hello.com", { body: null });
+ expect(req.body).toBeNull();
+ }
+ gc();
+ {
+ const req = new Request("https://hello.com", { body: undefined });
+ expect(req.body).toBeNull();
+ }
+ gc();
+ {
+ const req = new Request("https://hello.com");
+ expect(req.body).toBeNull();
+ }
+ gc();
+ {
+ const req = new Request("https://hello.com", { body: "" });
+ expect(req.body).toBeNull();
+ }
+ });
+
it("signal", async () => {
gc();
const controller = new AbortController();