From 778bad9dfd1b093cfd58a41a44ca9106828a9e0f Mon Sep 17 00:00:00 2001 From: Liz Date: Sun, 19 Nov 2023 19:38:33 +0100 Subject: [PATCH] fix(Bun.serve): return EACCESS when we don't have perms (#7191) * fix(Bun.serve): return EACCESS when we don't have perms The error reported to js land when listening fails was always the same, this adds a second one for EACCESS when we are not the super user. Fixes: https://github.com/oven-sh/bun/issues/7187 * fix: adjust code to be only ran on linuz * fix: correct typo * fix: remove comment since its linux only now --- src/bun.js/api/server.zig | 25 ++++++++++++++++++++----- test/js/bun/http/serve.test.ts | 11 +++++++++++ 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/bun.js/api/server.zig b/src/bun.js/api/server.zig index 5e9abc282a..73a6a512a2 100644 --- a/src/bun.js/api/server.zig +++ b/src/bun.js/api/server.zig @@ -14,6 +14,7 @@ const IdentityContext = @import("../../identity_context.zig").IdentityContext; const Fs = @import("../../fs.zig"); const Resolver = @import("../../resolver/resolver.zig"); const ast = @import("../../import_record.zig"); +const Sys = @import("../../sys.zig"); const MacroEntryPoint = bun.bundler.MacroEntryPoint; const logger = @import("root").bun.logger; @@ -5601,11 +5602,25 @@ pub fn NewServer(comptime NamespaceType: type, comptime ssl_enabled_: bool, comp if (error_instance == .zero) { switch (this.config.address) { .tcp => |tcp| { - error_instance = (JSC.SystemError{ - .message = bun.String.init(std.fmt.bufPrint(&output_buf, "Failed to start server. Is port {d} in use?", .{tcp.port}) catch "Failed to start server"), - .code = bun.String.static("EADDRINUSE"), - .syscall = bun.String.static("listen"), - }).toErrorInstance(this.globalThis); + error_set: { + if (comptime Environment.isLinux) { + var rc: i32 = -1; + const code = Sys.getErrno(rc); + if (code == bun.C.E.ACCES) { + error_instance = (JSC.SystemError{ + .message = bun.String.init(std.fmt.bufPrint(&output_buf, "permission denied {s}:{d}", .{ tcp.hostname orelse "0.0.0.0", tcp.port }) catch "Failed to start server"), + .code = bun.String.static("EACCES"), + .syscall = bun.String.static("listen"), + }).toErrorInstance(this.globalThis); + break :error_set; + } + } + error_instance = (JSC.SystemError{ + .message = bun.String.init(std.fmt.bufPrint(&output_buf, "Failed to start server. Is port {d} in use?", .{tcp.port}) catch "Failed to start server"), + .code = bun.String.static("EADDRINUSE"), + .syscall = bun.String.static("listen"), + }).toErrorInstance(this.globalThis); + } }, .unix => |unix| { error_instance = (JSC.SystemError{ diff --git a/test/js/bun/http/serve.test.ts b/test/js/bun/http/serve.test.ts index aef748c0d9..db321d9e85 100644 --- a/test/js/bun/http/serve.test.ts +++ b/test/js/bun/http/serve.test.ts @@ -1304,3 +1304,14 @@ it("should response with HTTP 413 when request body is larger than maxRequestBod server.stop(true); }); +if (process.platform === "linux") + it("should use correct error when using a root range port(#7187)", () => { + expect(() => { + const server = Bun.serve({ + port: 1003, + fetch(req) { + return new Response("request answered"); + }, + }); + }).toThrow("permission denied 0.0.0.0:1003"); + });