diff options
-rw-r--r-- | bench/fetch/bun.js | 17 | ||||
-rw-r--r-- | bench/fetch/deno.js | 17 | ||||
-rw-r--r-- | bench/fetch/node.mjs | 17 | ||||
-rw-r--r-- | src/bun.js/api/server.zig | 11 | ||||
-rw-r--r-- | test/bun.js/websocket-server.test.ts | 40 |
5 files changed, 99 insertions, 3 deletions
diff --git a/bench/fetch/bun.js b/bench/fetch/bun.js new file mode 100644 index 000000000..f61eeb0c6 --- /dev/null +++ b/bench/fetch/bun.js @@ -0,0 +1,17 @@ +import { bench, run } from "mitata"; + +const count = 100; + +bench(`fetch(https://example.com) x ${count}`, async () => { + const requests = new Array(count); + + for (let i = 0; i < requests.length; i++) { + requests[i] = fetch(`https://www.example.com/?cachebust=${i}`).then((r) => + r.text() + ); + } + + await Promise.all(requests); +}); + +await run(); diff --git a/bench/fetch/deno.js b/bench/fetch/deno.js new file mode 100644 index 000000000..929a478a0 --- /dev/null +++ b/bench/fetch/deno.js @@ -0,0 +1,17 @@ +import { bench, run } from "https://esm.run/mitata"; + +const count = 100; + +bench(`fetch(https://example.com) x ${count}`, async () => { + const requests = new Array(count); + + for (let i = 0; i < requests.length; i++) { + requests[i] = fetch(`https://www.example.com/?cachebust=${i}`).then((r) => + r.text() + ); + } + + await Promise.all(requests); +}); + +await run(); diff --git a/bench/fetch/node.mjs b/bench/fetch/node.mjs new file mode 100644 index 000000000..f61eeb0c6 --- /dev/null +++ b/bench/fetch/node.mjs @@ -0,0 +1,17 @@ +import { bench, run } from "mitata"; + +const count = 100; + +bench(`fetch(https://example.com) x ${count}`, async () => { + const requests = new Array(count); + + for (let i = 0; i < requests.length; i++) { + requests[i] = fetch(`https://www.example.com/?cachebust=${i}`).then((r) => + r.text() + ); + } + + await Promise.all(requests); +}); + +await run(); diff --git a/src/bun.js/api/server.zig b/src/bun.js/api/server.zig index 0cb5d4cd1..0adaf8b3b 100644 --- a/src/bun.js/api/server.zig +++ b/src/bun.js/api/server.zig @@ -3644,13 +3644,11 @@ pub fn NewServer(comptime ssl_enabled_: bool, comptime debug_mode_: bool) type { if (upgrader.aborted) { return JSC.jsBoolean(false); } - request.upgrader = null; + if (upgrader.upgrade_context == null or @ptrToInt(upgrader.upgrade_context) == std.math.maxInt(usize)) { return JSC.jsBoolean(false); } var ctx = upgrader.upgrade_context.?; - // obviously invalid pointer marks it as used - upgrader.upgrade_context = @intToPtr(*uws.uws_socket_context_s, std.math.maxInt(usize)); var sec_websocket_key_str = ZigString.Empty; @@ -3736,6 +3734,13 @@ pub fn NewServer(comptime ssl_enabled_: bool, comptime debug_mode_: bool) type { } } + // --- After this point, do not throw an exception + // See https://github.com/oven-sh/bun/issues/1339 + + // obviously invalid pointer marks it as used + upgrader.upgrade_context = @intToPtr(*uws.uws_socket_context_s, std.math.maxInt(usize)); + request.upgrader = null; + upgrader.resp.clearAborted(); var ws = this.vm.allocator.create(ServerWebSocket) catch return .zero; ws.* = .{ diff --git a/test/bun.js/websocket-server.test.ts b/test/bun.js/websocket-server.test.ts index 61cd08f7a..6c2dfa64f 100644 --- a/test/bun.js/websocket-server.test.ts +++ b/test/bun.js/websocket-server.test.ts @@ -53,6 +53,46 @@ describe("websocket server", () => { }); server.stop(); }); + + it("headers error doesn't crash", async () => { + var resolve, reject; + var server = serve({ + port: getPort(), + websocket: { + open(ws) {}, + message(ws, msg) {}, + close() { + resolve(); + }, + }, + error(err) { + resolve(); + }, + fetch(req, server) { + if ( + server.upgrade(req, { + data: "hello world", + + headers: 1238, + }) + ) { + reject(); + return; + } + reject(); + return new Response("noooooo hello world"); + }, + }); + + await new Promise((resolve_, reject) => { + resolve = resolve_; + const websocket = new WebSocket(`ws://localhost:${server.port}`); + websocket.onopen = () => websocket.close(); + websocket.onmessage = (e) => {}; + websocket.onerror = (e) => {}; + }); + server.stop(); + }); it("can do hello world", async () => { var server = serve({ port: getPort(), |