aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Dylan Conway <35280289+dylan-conway@users.noreply.github.com> 2023-09-05 06:12:54 -0700
committerGravatar GitHub <noreply@github.com> 2023-09-05 06:12:54 -0700
commit7dae4db52a403396bbe23ec6299f5a06d50e829b (patch)
tree50056ef0128beac5ce69a5b455fbc841399b122f
parentbcab2f9a0e6c59e18d96d886ae76a0086584c4bc (diff)
downloadbun-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.zig13
-rw-r--r--test/js/web/fetch/fetch.test.ts20
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 () => {