Add unix domain socket support for bind targets#96
Conversation
|
For #69 I used a struct-backed Do you think it makes sense to expose it as a plain |
| /// ```swift | ||
| /// let target = BindTarget.unixDomainSocket(path: "/tmp/server.sock") | ||
| /// ``` | ||
| public static func unixDomainSocket(path: String) -> Self { |
There was a problem hiding this comment.
This should probably use the new FilePath type once it becomes available
There was a problem hiding this comment.
This should probably use the new
FilePathtype once it becomes available
In the UDS bind support the socket path has two different types depending on direction: on input we take a FilePath (BindTarget.unixDomainSocket(path:)), but on output we expose it as String (SocketAddress.unixDomainSocketPath, mirroring NIOCore.SocketAddress.pathname). If we commit to FilePath, I'd lean toward using it on output too for consistency — but keeping String also makes sense since that's just what NIO reports back. Which way should we go?
There was a problem hiding this comment.
Yeah I think ignore what NIO does and keep the API what looks the best in Swift, in this case FilePaths for all types that represent instead of a String
Adds a `.unixDomainSocket(path:)` bind target so the server can listen on a UNIX domain socket in addition to host and port. - Add `BindTarget.unixDomainSocket(path:)` and a matching `SocketAddress` case - Bind via `ServerBootstrap.bind(unixDomainSocketPath:)` for both plaintext and secure-upgrade channels, and report the bound path from `listeningAddresses` - Remove the socket file on shutdown; fail the bind if the path is already occupied so a stale socket is never silently reused - Support a `socketPath` key in swift-configuration, mutually exclusive with `host`/`port` Resolves swift-server#69
Motivation: The UDS bind path was typed as a plain String. A System.FilePath gives it a strongly-typed, path-aware API at the configuration boundary. Modifications: - BindTarget.unixDomainSocket(path:) and its backing now take a FilePath - Convert to String only at the NIO edge (bind(unixDomainSocketPath:) and fileIO.unlink), where NIO still requires a String - public import System where FilePath appears in public API; plain import elsewhere - Update UDS tests to pass a FilePath Result: The UDS bind path is strongly typed; string literals still work via ExpressibleByStringLiteral, so call sites are unchanged.
Motivation: SocketAddress.init(_:) folded address, port and pathname lookups into a single tuple switch with coarse error cases, making failure reasons ambiguous and leaving the mapping untested. Modifications: - Replace addressOrPortNotAvailable/unsupportedAddressType with the more precise addressNotAvailable and portNotAvailable cases - Rebuild init(_:) around per-field throwing accessors and an exhaustive switch over the address kind - Switch the NIOClient test helper over SocketAddress.base instead of the optional host/port/path accessors - Add SocketAddressTests covering the IPv4, IPv6, UDS and nil mappings Result: Listening-address construction has precise error reasons and unit-test coverage; behaviour is unchanged.
cb49c66 to
b65b663
Compare
Switch connectToTestSecureUpgradeHTTPServer over SocketAddress.base like the HTTP/1.1 helper, and drop the now-unused TestError.unsupportedAddress.
0xTim
left a comment
There was a problem hiding this comment.
Looking mostly good, I think we should add H2 support as well though
… HTTP/3 Merges swift-server#101 and rejects unix domain socket bind targets when HTTP/3 is enabled, since HTTP/3 runs over QUIC/UDP.
Motivation
NIOHTTPServer could only bind to a host and port. Serving over a UNIX domain socket is a common requirement (e.g. a reverse proxy talking to the server over a local socket), so this PR adds a UDS bind target.
Modifications
• Added BindTarget.unixDomainSocket(path:) (typed as System.FilePath) and a matching SocketAddress case; the path is converted to String only at the NIO edge (bind(unixDomainSocketPath:) and fileIO.unlink).
• Bind over a UNIX domain socket for both plaintext (HTTP/1.1) and secure-upgrade (HTTP/1.1 + HTTP/2) channels, and report the bound path from listeningAddresses.
• Remove the socket file on shutdown; fail the bind if the path is already occupied so a stale socket is never silently reused.
• Support a socketPath key in swift-configuration, mutually exclusive with host/port.
• Reject UNIX domain socket bind targets when HTTP/3 is enabled (HTTP/3 runs over QUIC/UDP), with a dedicated configuration error.
• Added tests for the listening-address mapping and the HTTP/3 rejection.
Result
NIOHTTPServer can now listen on a UNIX domain socket over HTTP/1.1 and HTTP/2. Resolves #69.