diff options
author | Yoshiya Hinosawa <stibium121@gmail.com> | 2023-10-04 11:37:39 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-10-04 11:37:39 +0900 |
commit | da0b945804f19903beac71b23ff1040ebdb9b554 (patch) | |
tree | 8ec0508fbc04839f113b2d58169090d14b474cdd /ext | |
parent | 8c1677ecbcbb474fc6a5ac9b5f73b562677bb829 (diff) |
feat(unstable): add unix domain socket support to Deno.serve (#20759)
Diffstat (limited to 'ext')
-rw-r--r-- | ext/http/00_serve.js | 44 | ||||
-rw-r--r-- | ext/net/01_net.js | 9 | ||||
-rw-r--r-- | ext/net/ops_unix.rs | 8 |
3 files changed, 53 insertions, 8 deletions
diff --git a/ext/http/00_serve.js b/ext/http/00_serve.js index aeebca93d..e74e1e71f 100644 --- a/ext/http/00_serve.js +++ b/ext/http/00_serve.js @@ -34,11 +34,12 @@ import { ReadableStreamPrototype, resourceForReadableStream, } from "ext:deno_web/06_streams.js"; -import { listen, TcpConn } from "ext:deno_net/01_net.js"; +import { listen, listenOptionApiName, TcpConn } from "ext:deno_net/01_net.js"; import { listenTls } from "ext:deno_net/02_tls.js"; const { ArrayPrototypePush, Error, + ObjectHasOwn, ObjectPrototypeIsPrototypeOf, PromisePrototypeCatch, Symbol, @@ -272,6 +273,13 @@ class InnerRequest { } get remoteAddr() { + const transport = this.#context.listener?.addr.transport; + if (transport === "unix" || transport === "unixpacket") { + return { + transport, + path: this.#context.listener.addr.path, + }; + } if (this.#methodAndUri === undefined) { if (this.#slabId === undefined) { throw new TypeError("request closed"); @@ -337,8 +345,9 @@ class CallbackContext { serverRid; closed; closing; + listener; - constructor(signal, args) { + constructor(signal, args, listener) { // The abort signal triggers a non-graceful shutdown signal?.addEventListener( "abort", @@ -352,6 +361,7 @@ class CallbackContext { this.scheme = args[1]; this.fallbackHost = args[2]; this.closed = false; + this.listener = listener; } close() { @@ -519,11 +529,29 @@ function serve(arg1, arg2) { } const wantsHttps = options.cert || options.key; + const wantsUnix = ObjectHasOwn(options, "path"); const signal = options.signal; const onError = options.onError ?? function (error) { console.error(error); return internalServerError(); }; + + if (wantsUnix) { + const listener = listen({ + transport: "unix", + path: options.path, + [listenOptionApiName]: "Deno.serve", + }); + const path = listener.addr.path; + return serveHttpOnListener(listener, signal, handler, onError, () => { + if (options.onListen) { + options.onListen({ path }); + } else { + console.log(`Listening on ${path}`); + } + }); + } + const listenOpts = { hostname: options.hostname ?? "0.0.0.0", port: options.port ?? 8000, @@ -581,7 +609,11 @@ function serve(arg1, arg2) { * Serve HTTP/1.1 and/or HTTP/2 on an arbitrary listener. */ function serveHttpOnListener(listener, signal, handler, onError, onListen) { - const context = new CallbackContext(signal, op_http_serve(listener.rid)); + const context = new CallbackContext( + signal, + op_http_serve(listener.rid), + listener, + ); const callback = mapToCallback(context, handler, onError); onListen(context.scheme); @@ -593,7 +625,11 @@ function serveHttpOnListener(listener, signal, handler, onError, onListen) { * Serve HTTP/1.1 and/or HTTP/2 on an arbitrary connection. */ function serveHttpOnConnection(connection, signal, handler, onError, onListen) { - const context = new CallbackContext(signal, op_http_serve_on(connection.rid)); + const context = new CallbackContext( + signal, + op_http_serve_on(connection.rid), + null, + ); const callback = mapToCallback(context, handler, onError); onListen(context.scheme); diff --git a/ext/net/01_net.js b/ext/net/01_net.js index 9cdcdb78c..f2bf5e7df 100644 --- a/ext/net/01_net.js +++ b/ext/net/01_net.js @@ -19,6 +19,7 @@ const { ObjectPrototypeIsPrototypeOf, PromiseResolve, SymbolAsyncIterator, + Symbol, SymbolFor, TypeError, TypedArrayPrototypeSubarray, @@ -416,6 +417,8 @@ class Datagram { } } +const listenOptionApiName = Symbol("listenOptionApiName"); + function listen(args) { switch (args.transport ?? "tcp") { case "tcp": { @@ -427,7 +430,10 @@ function listen(args) { return new Listener(rid, addr); } case "unix": { - const { 0: rid, 1: path } = ops.op_net_listen_unix(args.path); + const { 0: rid, 1: path } = ops.op_net_listen_unix( + args.path, + args[listenOptionApiName] ?? "Deno.listen", + ); const addr = { transport: "unix", path, @@ -505,6 +511,7 @@ export { Datagram, listen, Listener, + listenOptionApiName, resolveDns, shutdown, TcpConn, diff --git a/ext/net/ops_unix.rs b/ext/net/ops_unix.rs index beb41bb4a..7a5da9fa1 100644 --- a/ext/net/ops_unix.rs +++ b/ext/net/ops_unix.rs @@ -194,15 +194,17 @@ where pub fn op_net_listen_unix<NP>( state: &mut OpState, #[string] path: String, + #[string] api_name: String, ) -> Result<(ResourceId, Option<String>), AnyError> where NP: NetPermissions + 'static, { let address_path = Path::new(&path); - super::check_unstable(state, "Deno.listen"); + super::check_unstable(state, &api_name); let permissions = state.borrow_mut::<NP>(); - permissions.check_read(address_path, "Deno.listen()")?; - permissions.check_write(address_path, "Deno.listen()")?; + let api_call_expr = format!("{}()", api_name); + permissions.check_read(address_path, &api_call_expr)?; + permissions.check_write(address_path, &api_call_expr)?; let listener = UnixListener::bind(address_path)?; let local_addr = listener.local_addr()?; let pathname = local_addr.as_pathname().map(pathstring).transpose()?; |