From 7b91d8740ff101d3d480dbe6cfdc71fade08ba03 Mon Sep 17 00:00:00 2001 From: Ryan Schmitt Date: Thu, 22 May 2025 16:22:14 -0700 Subject: [PATCH] Avoid legacy Socket API in reactor code The `Socket` API is considered tightly coupled to Internet Protocol, and `socketChannel.socket()` is effectively a kind of unchecked downcast which will throw an exception if called on a Unix domain SocketChannel. This change removes some trivial coupling to `Socket` in preparation for introducing support for JEP 380 Unix domain sockets. --- .../hc/core5/reactor/IOSessionImpl.java | 12 ++++++++-- .../hc/core5/reactor/SingleCoreIOReactor.java | 24 ++++++++++++------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/httpcore5/src/main/java/org/apache/hc/core5/reactor/IOSessionImpl.java b/httpcore5/src/main/java/org/apache/hc/core5/reactor/IOSessionImpl.java index 45379c0560..7b5b91dafb 100644 --- a/httpcore5/src/main/java/org/apache/hc/core5/reactor/IOSessionImpl.java +++ b/httpcore5/src/main/java/org/apache/hc/core5/reactor/IOSessionImpl.java @@ -131,12 +131,20 @@ public ByteChannel channel() { @Override public SocketAddress getLocalAddress() { - return this.channel.socket().getLocalSocketAddress(); + try { + return this.channel.getLocalAddress(); + } catch (final IOException e) { + return null; + } } @Override public SocketAddress getRemoteAddress() { - return this.channel.socket().getRemoteSocketAddress(); + try { + return channel.getRemoteAddress(); + } catch (final IOException e) { + return null; + } } @Override diff --git a/httpcore5/src/main/java/org/apache/hc/core5/reactor/SingleCoreIOReactor.java b/httpcore5/src/main/java/org/apache/hc/core5/reactor/SingleCoreIOReactor.java index 7091e724d3..2442f355b3 100644 --- a/httpcore5/src/main/java/org/apache/hc/core5/reactor/SingleCoreIOReactor.java +++ b/httpcore5/src/main/java/org/apache/hc/core5/reactor/SingleCoreIOReactor.java @@ -32,6 +32,7 @@ import java.net.Socket; import java.net.SocketAddress; import java.net.SocketOption; +import java.net.StandardSocketOptions; import java.net.UnknownHostException; import java.nio.channels.CancelledKeyException; import java.nio.channels.ClosedChannelException; @@ -277,21 +278,26 @@ public Future connect( } private void prepareSocket(final SocketChannel socketChannel) throws IOException { - final Socket socket = socketChannel.socket(); - socket.setTcpNoDelay(this.reactorConfig.isTcpNoDelay()); - socket.setKeepAlive(this.reactorConfig.isSoKeepAlive()); if (this.reactorConfig.getSndBufSize() > 0) { - socket.setSendBufferSize(this.reactorConfig.getSndBufSize()); + socketChannel.setOption(StandardSocketOptions.SO_SNDBUF, this.reactorConfig.getSndBufSize()); } if (this.reactorConfig.getRcvBufSize() > 0) { - socket.setReceiveBufferSize(this.reactorConfig.getRcvBufSize()); - } - if (this.reactorConfig.getTrafficClass() > 0) { - socket.setTrafficClass(this.reactorConfig.getTrafficClass()); + socketChannel.setOption(StandardSocketOptions.SO_RCVBUF, this.reactorConfig.getRcvBufSize()); } final int linger = this.reactorConfig.getSoLinger().toSecondsIntBound(); if (linger >= 0) { - socket.setSoLinger(true, linger); + socketChannel.setOption(StandardSocketOptions.SO_LINGER, linger); + } + + // None of the below options are applicable to Unix domain sockets. + if (!(socketChannel.getRemoteAddress() instanceof InetSocketAddress)) { + return; + } + socketChannel.setOption(StandardSocketOptions.TCP_NODELAY, this.reactorConfig.isTcpNoDelay()); + socketChannel.setOption(StandardSocketOptions.SO_KEEPALIVE, this.reactorConfig.isSoKeepAlive()); + + if (this.reactorConfig.getTrafficClass() > 0) { + socketChannel.setOption(StandardSocketOptions.IP_TOS, this.reactorConfig.getTrafficClass()); } if (this.reactorConfig.getTcpKeepIdle() > 0) { setExtendedSocketOption(socketChannel, SocketSupport.TCP_KEEPIDLE, this.reactorConfig.getTcpKeepIdle());