From 6c3aaefed2654950d54b0ddb8e980070242f5e2f Mon Sep 17 00:00:00 2001 From: Meghan Denny Date: Thu, 3 Apr 2025 22:43:35 -0800 Subject: [PATCH] node:net: fix Server.prototype.address() (#18771) --- src/bun.js/api/bun/socket.zig | 44 +++++++++++++++++++++++-------- src/bun.js/api/sockets.classes.ts | 5 ++++ src/deps/uws.zig | 4 +++ src/js/node/net.ts | 23 +++------------- 4 files changed, 46 insertions(+), 30 deletions(-) diff --git a/src/bun.js/api/bun/socket.zig b/src/bun.js/api/bun/socket.zig index b275c21c39..2bdb48f618 100644 --- a/src/bun.js/api/bun/socket.zig +++ b/src/bun.js/api/bun/socket.zig @@ -540,11 +540,7 @@ pub const Listener = struct { return this.strong_data.get() orelse JSValue.jsUndefined(); } - pub fn setData( - this: *Listener, - globalObject: *JSC.JSGlobalObject, - value: JSC.JSValue, - ) callconv(.C) bool { + pub fn setData(this: *Listener, globalObject: *JSC.JSGlobalObject, value: JSC.JSValue) callconv(.C) bool { log("setData()", .{}); this.strong_data.set(globalObject, value); return true; @@ -847,15 +843,11 @@ pub const Listener = struct { return this_value; } - pub fn onCreateTLS( - socket: uws.NewSocketHandler(true), - ) void { + pub fn onCreateTLS(socket: uws.NewSocketHandler(true)) void { onCreate(true, socket); } - pub fn onCreateTCP( - socket: uws.NewSocketHandler(false), - ) void { + pub fn onCreateTCP(socket: uws.NewSocketHandler(false)) void { onCreate(false, socket); } @@ -1263,6 +1255,36 @@ pub const Listener = struct { }, } } + + pub fn getsockname(this: *Listener, globalThis: *JSC.JSGlobalObject, callFrame: *JSC.CallFrame) bun.JSError!JSValue { + if (this.listener != .uws) { + return .jsUndefined(); + } + + const out = callFrame.argumentsAsArray(1)[0]; + const socket = this.listener.uws; + + var buf: [64]u8 = [_]u8{0} ** 64; + var text_buf: [512]u8 = undefined; + const address_bytes: []const u8 = socket.getLocalAddress(this.ssl, &buf) catch return .jsUndefined(); + const address_zig: std.net.Address = switch (address_bytes.len) { + 4 => std.net.Address.initIp4(address_bytes[0..4].*, 0), + 16 => std.net.Address.initIp6(address_bytes[0..16].*, 0, 0, 0), + else => return .jsUndefined(), + }; + const family_js = switch (address_bytes.len) { + 4 => bun.String.static("IPv4").toJS(globalThis), + 16 => bun.String.static("IPv6").toJS(globalThis), + else => return .jsUndefined(), + }; + const address_js = ZigString.init(bun.fmt.formatIp(address_zig, &text_buf) catch unreachable).toJS(globalThis); + const port_js: JSValue = .jsNumber(socket.getLocalPort(this.ssl)); + + out.put(globalThis, bun.String.static("family"), family_js); + out.put(globalThis, bun.String.static("address"), address_js); + out.put(globalThis, bun.String.static("port"), port_js); + return .jsUndefined(); + } }; fn JSSocketType(comptime ssl: bool) type { diff --git a/src/bun.js/api/sockets.classes.ts b/src/bun.js/api/sockets.classes.ts index c43cc7118c..b85d79176e 100644 --- a/src/bun.js/api/sockets.classes.ts +++ b/src/bun.js/api/sockets.classes.ts @@ -281,6 +281,11 @@ export default [ getter: "getData", setter: "setData", }, + + getsockname: { + fn: "getsockname", + length: 1, + }, }, finalize: true, construct: true, diff --git a/src/deps/uws.zig b/src/deps/uws.zig index 96754a1018..f4eb921d86 100644 --- a/src/deps/uws.zig +++ b/src/deps/uws.zig @@ -3014,6 +3014,10 @@ pub const ListenSocket = opaque { pub fn close(this: *ListenSocket, ssl: bool) void { us_listen_socket_close(@intFromBool(ssl), this); } + pub fn getLocalAddress(this: *ListenSocket, ssl: bool, buf: []u8) ![]const u8 { + const self: *uws.Socket = @ptrCast(this); + return self.localAddress(ssl, buf); + } pub fn getLocalPort(this: *ListenSocket, ssl: bool) i32 { const self: *uws.Socket = @ptrCast(this); return self.localPort(ssl); diff --git a/src/js/node/net.ts b/src/js/node/net.ts index 529ab4ea71..eee2eebcaf 100644 --- a/src/js/node/net.ts +++ b/src/js/node/net.ts @@ -1310,25 +1310,10 @@ Server.prototype.address = function address() { return unix; } - //TODO: fix adress when host is passed - let address = server.hostname; - const type = isIP(address); - const port = server.port; - if (typeof port === "number") { - return { - port, - address, - family: type ? `IPv${type}` : undefined, - }; - } - if (type) { - return { - address, - family: type ? `IPv${type}` : undefined, - }; - } - - return address; + const out = {}; + const err = this._handle.getsockname(out); + if (err) throw new ErrnoException(err, "address"); + return out; } return null; };