diff options
author | 2023-07-30 23:51:43 -0700 | |
---|---|---|
committer | 2023-07-30 23:51:43 -0700 | |
commit | 9ecae59bbb1a302977afa94fd879a0c6f8d6195f (patch) | |
tree | 7bfff6d9c3264b8d1fce85f63891a1f3e5833a52 /test/js | |
parent | 2ea7290172da21f4a9cd58232bf9c1ea0997d6e2 (diff) | |
download | bun-9ecae59bbb1a302977afa94fd879a0c6f8d6195f.tar.gz bun-9ecae59bbb1a302977afa94fd879a0c6f8d6195f.tar.zst bun-9ecae59bbb1a302977afa94fd879a0c6f8d6195f.zip |
Fix memory leak in response.clone(), further reduce memory usage of Request & Response (#3902)
* Atomize respsone.url & response.statusText
* Fix warning
* Atomize Request & Response URLs when possible
* Fix memory leak in response.clone()
bun/bench/snippets on jarred/atomize
❯ mem bun --smol request-response-clone.mjs
cpu: Apple M1 Max
runtime: bun 0.7.2 (arm64-darwin)
benchmark time (avg) (min … max) p75 p99 p995
-------------------------------------------------------- -----------------------------
req.clone().url 77.3 ns/iter (40.35 ns … 222.64 ns) 91.53 ns 128.11 ns 172.78 ns
resp.clone().url 162.43 ns/iter (116 ns … 337.77 ns) 177.4 ns 232.38 ns 262.65 ns
Peak memory usage: 60 MB
bun/bench/snippets on jarred/atomize
❯ mem bun-0.7.1 --smol request-response-clone.mjs
cpu: Apple M1 Max
runtime: bun 0.7.1 (arm64-darwin)
benchmark time (avg) (min … max) p75 p99 p995
-------------------------------------------------------- -----------------------------
req.clone().url 115.85 ns/iter (80.35 ns … 247.39 ns) 128.19 ns 181.93 ns 207.23 ns
resp.clone().url 252.32 ns/iter (202.6 ns … 351.07 ns) 266.56 ns 325.88 ns 334.73 ns
Peak memory usage: 1179 MB
* Update tests
* Update js_ast.zig
* Update test
---------
Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
Diffstat (limited to 'test/js')
-rw-r--r-- | test/js/bun/http/bun-server.test.ts | 4 | ||||
-rw-r--r-- | test/js/bun/util/inspect.test.js | 2 | ||||
-rw-r--r-- | test/js/web/fetch/body-stream.test.ts | 5 | ||||
-rw-r--r-- | test/js/web/fetch/fetch.test.ts | 40 |
4 files changed, 42 insertions, 9 deletions
diff --git a/test/js/bun/http/bun-server.test.ts b/test/js/bun/http/bun-server.test.ts index 37675c25d..9fd97e3cb 100644 --- a/test/js/bun/http/bun-server.test.ts +++ b/test/js/bun/http/bun-server.test.ts @@ -205,7 +205,7 @@ describe("Server", () => { }, }); try { - const url = `http://${server.hostname}:${server.port}`; + const url = `http://${server.hostname}:${server.port}/`; const response = await server.fetch(url); expect(await response.text()).toBe("Hello World!"); expect(response.status).toBe(200); @@ -222,7 +222,7 @@ describe("Server", () => { }, }); try { - const url = `http://${server.hostname}:${server.port}`; + const url = `http://${server.hostname}:${server.port}/`; const response = await server.fetch(new Request(url)); expect(await response.text()).toBe("Hello World!"); expect(response.status).toBe(200); diff --git a/test/js/bun/util/inspect.test.js b/test/js/bun/util/inspect.test.js index e91204c69..4d5165543 100644 --- a/test/js/bun/util/inspect.test.js +++ b/test/js/bun/util/inspect.test.js @@ -107,7 +107,7 @@ it("Request object", () => { ` Request (0 KB) { method: "GET", - url: "https://example.com", + url: "https://example.com/", headers: Headers {} }`.trim(), ); diff --git a/test/js/web/fetch/body-stream.test.ts b/test/js/web/fetch/body-stream.test.ts index 64b3434e1..8e2baf92a 100644 --- a/test/js/web/fetch/body-stream.test.ts +++ b/test/js/web/fetch/body-stream.test.ts @@ -1,7 +1,6 @@ // @ts-nocheck -import { file, gc, serve, ServeOptions } from "bun"; -import { afterAll, afterEach, describe, expect, it, test } from "bun:test"; -import { readFileSync } from "fs"; +import { gc, ServeOptions } from "bun"; +import { afterAll, describe, expect, it, test } from "bun:test"; var port = 0; diff --git a/test/js/web/fetch/fetch.test.ts b/test/js/web/fetch/fetch.test.ts index d7fc87ade..ec73069de 100644 --- a/test/js/web/fetch/fetch.test.ts +++ b/test/js/web/fetch/fetch.test.ts @@ -30,6 +30,14 @@ afterAll(() => { const payload = new Uint8Array(1024 * 1024 * 2); crypto.getRandomValues(payload); +it("new Request(invalid url) throws", () => { + expect(() => new Request("http")).toThrow(); + expect(() => new Request("")).toThrow(); + expect(() => new Request("http://[::1")).toThrow(); + expect(() => new Request("https://[::1")).toThrow(); + expect(() => new Request("!")).toThrow(); +}); + describe("AbortSignal", () => { beforeEach(() => { startServer({ @@ -1165,9 +1173,9 @@ it("should not be able to parse json from empty body", () => { }); it("#874", () => { - expect(new Request(new Request("https://example.com"), {}).url).toBe("https://example.com"); - expect(new Request(new Request("https://example.com")).url).toBe("https://example.com"); - expect(new Request({ url: "https://example.com" }).url).toBe("https://example.com"); + expect(new Request(new Request("https://example.com"), {}).url).toBe("https://example.com/"); + expect(new Request(new Request("https://example.com")).url).toBe("https://example.com/"); + expect(new Request({ url: "https://example.com" }).url).toBe("https://example.com/"); }); it("#2794", () => { @@ -1213,3 +1221,29 @@ it("fetch() file:// works", async () => { await Bun.file(Bun.fileURLToPath(new URL("file with space in the name.txt", import.meta.url))).text(), ); }); + +it("cloned response headers are independent before accessing", () => { + const response = new Response("hello", { + headers: { + "content-type": "text/html; charset=utf-8", + }, + }); + const cloned = response.clone(); + cloned.headers.set("content-type", "text/plain"); + expect(response.headers.get("content-type")).toBe("text/html; charset=utf-8"); +}); + +it("cloned response headers are independent after accessing", () => { + const response = new Response("hello", { + headers: { + "content-type": "text/html; charset=utf-8", + }, + }); + + // create the headers + response.headers; + + const cloned = response.clone(); + cloned.headers.set("content-type", "text/plain"); + expect(response.headers.get("content-type")).toBe("text/html; charset=utf-8"); +}); |