diff options
author | 2023-02-24 17:22:14 -0300 | |
---|---|---|
committer | 2023-02-24 12:22:14 -0800 | |
commit | 1c531472c93f9d3a7b491b100803b8c0ad42d0e7 (patch) | |
tree | 729e877d8188630a4f2a431e02b88a472675a0f7 | |
parent | dc8e8450491f2485cc7c3b42fd82aaaf0f978260 (diff) | |
download | bun-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.zig | 12 | ||||
-rw-r--r-- | test/bun.js/fetch.test.js | 139 |
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(); |