diff options
author | 2023-09-05 06:12:54 -0700 | |
---|---|---|
committer | 2023-09-05 06:12:54 -0700 | |
commit | 7dae4db52a403396bbe23ec6299f5a06d50e829b (patch) | |
tree | 50056ef0128beac5ce69a5b455fbc841399b122f | |
parent | bcab2f9a0e6c59e18d96d886ae76a0086584c4bc (diff) | |
download | bun-7dae4db52a403396bbe23ec6299f5a06d50e829b.tar.gz bun-7dae4db52a403396bbe23ec6299f5a06d50e829b.tar.zst bun-7dae4db52a403396bbe23ec6299f5a06d50e829b.zip |
fix ipv6 localhost fetch (#4498)
* `node` null for localhost getaddrinfo
* more test
-rw-r--r-- | src/deps/uws.zig | 13 | ||||
-rw-r--r-- | test/js/web/fetch/fetch.test.ts | 20 |
2 files changed, 31 insertions, 2 deletions
diff --git a/src/deps/uws.zig b/src/deps/uws.zig index 201544a75..d3228141b 100644 --- a/src/deps/uws.zig +++ b/src/deps/uws.zig @@ -369,8 +369,17 @@ pub fn NewSocketHandler(comptime is_ssl: bool) type { debug("connect({s}, {d})", .{ host, port }); var stack_fallback = std.heap.stackFallback(1024, bun.default_allocator); var allocator = stack_fallback.get(); - var host_ = allocator.dupeZ(u8, host) catch return null; - defer allocator.free(host_); + + var host_: ?[*:0]u8 = brk: { + // getaddrinfo expects `node` to be null if localhost + if (host.len < 6 and (bun.strings.eqlComptime(host, "[::1]") or bun.strings.eqlComptime(host, "[::]"))) { + break :brk null; + } + + break :brk allocator.dupeZ(u8, host) catch return null; + }; + + defer if (host_) |host__| allocator.free(host__[0..host.len]); var socket = us_socket_context_connect(comptime ssl_int, socket_ctx, host_, port, null, 0, @sizeOf(*anyopaque)) orelse return null; const socket_ = ThisSocket{ .socket = socket }; diff --git a/test/js/web/fetch/fetch.test.ts b/test/js/web/fetch/fetch.test.ts index 59847dde9..aa44ee76a 100644 --- a/test/js/web/fetch/fetch.test.ts +++ b/test/js/web/fetch/fetch.test.ts @@ -531,6 +531,26 @@ describe("fetch", () => { expect(response2.status).toBe(200); expect(await response2.text()).toBe("0"); }); + + it("should work with ipv6 localhost", async () => { + const server = Bun.serve({ + port: 0, + fetch(req) { + return new Response("Pass!"); + }, + }); + + let res = await fetch(`http://[::1]:${server.port}`); + expect(await res.text()).toBe("Pass!"); + res = await fetch(`http://[::]:${server.port}/`); + expect(await res.text()).toBe("Pass!"); + res = await fetch(`http://[0:0:0:0:0:0:0:1]:${server.port}/`); + expect(await res.text()).toBe("Pass!"); + res = await fetch(`http://[0000:0000:0000:0000:0000:0000:0000:0001]:${server.port}/`); + expect(await res.text()).toBe("Pass!"); + + server.stop(); + }); }); it("simultaneous HTTPS fetch", async () => { |