Skip to content

Add Unix domain socket support #637

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 4, 2025
Merged

Add Unix domain socket support #637

merged 1 commit into from
Jun 4, 2025

Conversation

rschmitt
Copy link
Contributor

This change adds Unix domain socket support. The sync client uses JUnixSocket, which provides synchronous UDS support through the legacy java.net.Socket API; the async client uses the JEP 380 implementation of UDS through the java.nio.channels.SocketChannel API (requires JDK16 or later).

Since the synchronous client is tightly coupled to the Socket API, we can't trivially use JEP 380 UDS support. We would first have to write an adapter to implement the Socket API, backed by a JEP 380 UDS SocketChannel. This would require us to implement features like socket option configuration, connection timeouts, and socket timeouts; we would also have to implement APIs like getInetAddress() which don't actually make sense in a UDS context. This is probably doable (JUnixSocket does it, albeit with a different implementation strategy based on native code), but it's not trivial.

The asynchronous client is the other way around: it supports JEP 380, but not JUnixSocket. The issue here is more subtle: JDK and JUnixDomain channels cannot be mixed in the same selector, and since JUnixDomain does not provide an implementation of TCP/IP channels, supporting JUnixSocket in the async client would require substantial rework in the IO reactor. Since JDK8 is end-of-life next year, I doubt this is worth doing unless we can find some clever way of integrating the new channel type with minimal churn.

Unix domain socket support is exposed through the RequestConfig API. A path to a Unix domain socket can be provided as a client-wide default through setDefaultRequestConfig, or on a per-request basis through setConfig. Currently, proxies and TLS are not supported through UDS. The former feature seems unnecessary, but the latter is likely worth adding at some point, since contacting an HTTPS endpoint over UDS (sometimes denoted by the URI scheme https+unix) is not unheard of.

@rschmitt rschmitt requested a review from ok2c May 29, 2025 21:53
@ok2c
Copy link
Member

ok2c commented May 30, 2025

@rschmitt It is a big one. Please allow me a few days to get around to it.

@rschmitt
Copy link
Contributor Author

I suggest reading the diff from the bottom up. It just flows more logically that way: example code, connection changes, routing changes, integration test changes.

This change adds Unix domain socket support. The sync client uses
JUnixSocket, which provides synchronous UDS support through the legacy
`java.net.Socket` API; the async client uses the JEP 380 implementation
of UDS through the `java.nio.channels.SocketChannel` API (requires JDK16
or later).

Since the synchronous client is tightly coupled to the `Socket` API, we
can't trivially use JEP 380 UDS support. We would first have to write an
adapter to implement the `Socket` API, backed by a JEP 380 UDS
`SocketChannel`. This would require us to implement features like socket
option configuration, connection timeouts, and socket timeouts; we would
also have to implement APIs like `getInetAddress()` which don't actually
make sense in a UDS context. This is probably doable (JUnixSocket does
it, albeit with a different implementation strategy based on native
code), but it's not trivial.

The asynchronous client is the other way around: it supports JEP 380,
but not JUnixSocket. The issue here is more subtle: JDK and JUnixDomain
channels cannot be mixed in the same selector, and since JUnixDomain
does not provide an implementation of TCP/IP channels, supporting
JUnixSocket in the async client would require substantial rework in the
IO reactor. Since JDK8 is end-of-life next year, I doubt this is worth
doing unless we can find some clever way of integrating the new channel
type with minimal churn.

Unix domain socket support is exposed through the `RequestConfig` API. A
path to a Unix domain socket can be provided as a client-wide default
through `setDefaultRequestConfig`, or on a per-request basis through
`setConfig`. Currently, proxies and TLS are not supported through UDS.
The former feature seems unnecessary, but the latter is likely worth
adding at some point, since contacting an HTTPS endpoint over UDS
(sometimes denoted by the URI scheme `https+unix`) is not unheard of.
Copy link
Member

@michael-o michael-o left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Final word has @ok2c

Copy link
Member

@ok2c ok2c left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rschmitt Looks good to me

@rschmitt rschmitt merged commit 03043d6 into apache:master Jun 4, 2025
10 checks passed
@rschmitt rschmitt deleted the uds branch June 4, 2025 16:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants