Skip to content

Commit

Permalink
HTTPCORE-761: support ExtendedSocketOption (#473)
Browse files Browse the repository at this point in the history
  • Loading branch information
kkewwei authored Aug 10, 2024
1 parent 9be6b1c commit d5f903a
Show file tree
Hide file tree
Showing 10 changed files with 449 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,14 @@
import org.apache.hc.core5.pool.PoolEntry;
import org.apache.hc.core5.pool.PoolStats;
import org.apache.hc.core5.util.Args;
import org.apache.hc.core5.util.ReflectionUtils;
import org.apache.hc.core5.util.TimeValue;
import org.apache.hc.core5.util.Timeout;

import static org.apache.hc.core5.util.NetUtils.TCP_KEEPCOUNT;
import static org.apache.hc.core5.util.NetUtils.TCP_KEEPIDLE;
import static org.apache.hc.core5.util.NetUtils.TCP_KEEPINTERVAL;

/**
* HTTP/1.1 client side message exchange initiator.
*
Expand Down Expand Up @@ -249,6 +254,15 @@ private HttpClientConnection createConnection(final Socket sock, final HttpHost
if (socketConfig.getSndBufSize() > 0) {
sock.setSendBufferSize(socketConfig.getSndBufSize());
}
if (this.socketConfig.getTcpKeepIdle() > 0) {
ReflectionUtils.setOption(sock, TCP_KEEPIDLE, this.socketConfig.getTcpKeepIdle());
}
if (this.socketConfig.getTcpKeepInterval() > 0) {
ReflectionUtils.setOption(sock, TCP_KEEPINTERVAL, this.socketConfig.getTcpKeepInterval());
}
if (this.socketConfig.getTcpKeepCount() > 0) {
ReflectionUtils.setOption(sock, TCP_KEEPCOUNT, this.socketConfig.getTcpKeepCount());
}
final int linger = socketConfig.getSoLinger().toMillisecondsIntBound();
if (linger >= 0) {
sock.setSoLinger(true, linger);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,14 @@
import org.apache.hc.core5.io.Closer;
import org.apache.hc.core5.io.ModalCloseable;
import org.apache.hc.core5.util.Args;
import org.apache.hc.core5.util.ReflectionUtils;
import org.apache.hc.core5.util.TimeValue;
import org.apache.hc.core5.util.Timeout;

import static org.apache.hc.core5.util.NetUtils.TCP_KEEPCOUNT;
import static org.apache.hc.core5.util.NetUtils.TCP_KEEPIDLE;
import static org.apache.hc.core5.util.NetUtils.TCP_KEEPINTERVAL;

/**
* HTTP/1.1 server side message exchange handler.
*
Expand Down Expand Up @@ -145,6 +150,15 @@ public void start() throws IOException {
if (this.socketConfig.getRcvBufSize() > 0) {
this.serverSocket.setReceiveBufferSize(this.socketConfig.getRcvBufSize());
}
if (this.socketConfig.getTcpKeepIdle() > 0) {
ReflectionUtils.setOption(this.serverSocket, TCP_KEEPIDLE, this.socketConfig.getTcpKeepIdle());
}
if (this.socketConfig.getTcpKeepInterval() > 0) {
ReflectionUtils.setOption(this.serverSocket, TCP_KEEPINTERVAL, this.socketConfig.getTcpKeepInterval());
}
if (this.socketConfig.getTcpKeepCount() > 0) {
ReflectionUtils.setOption(this.serverSocket, TCP_KEEPCOUNT, this.socketConfig.getTcpKeepCount());
}
if (this.sslSetupHandler != null && this.serverSocket instanceof SSLServerSocket) {
final SSLServerSocket sslServerSocket = (SSLServerSocket) this.serverSocket;
final SSLParameters sslParameters = sslServerSocket.getSSLParameters();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@
import org.apache.hc.core5.http.io.HttpServerConnection;
import org.apache.hc.core5.http.io.SocketConfig;
import org.apache.hc.core5.io.Closer;
import org.apache.hc.core5.util.ReflectionUtils;

import static org.apache.hc.core5.util.NetUtils.TCP_KEEPCOUNT;
import static org.apache.hc.core5.util.NetUtils.TCP_KEEPIDLE;
import static org.apache.hc.core5.util.NetUtils.TCP_KEEPINTERVAL;

class RequestListener implements Runnable {

Expand Down Expand Up @@ -91,6 +96,15 @@ private HttpServerConnection createConnection(final Socket socket) throws IOExce
if (this.socketConfig.getSoLinger().toSeconds() >= 0) {
socket.setSoLinger(true, this.socketConfig.getSoLinger().toSecondsIntBound());
}
if (this.socketConfig.getTcpKeepIdle() > 0) {
ReflectionUtils.setOption(this.serverSocket, TCP_KEEPIDLE, this.socketConfig.getTcpKeepIdle());
}
if (this.socketConfig.getTcpKeepInterval() > 0) {
ReflectionUtils.setOption(this.serverSocket, TCP_KEEPINTERVAL, this.socketConfig.getTcpKeepInterval());
}
if (this.socketConfig.getTcpKeepCount() > 0) {
ReflectionUtils.setOption(this.serverSocket, TCP_KEEPCOUNT, this.socketConfig.getTcpKeepCount());
}
if (!(socket instanceof SSLSocket) && sslSocketFactory != null) {
final SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket(socket, null, -1, false);
sslSocket.setUseClientMode(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ public class SocketConfig {
private final int sndBufSize;
private final int rcvBufSize;
private final int backlogSize;
private final int tcpKeepIdle;
private final int tcpKeepInterval;
private final int tcpKeepCount;
private final SocketAddress socksProxyAddress;

SocketConfig(
Expand All @@ -67,6 +70,9 @@ public class SocketConfig {
final int sndBufSize,
final int rcvBufSize,
final int backlogSize,
final int tcpKeepIdle,
final int tcpKeepInterval,
final int tcpKeepCount,
final SocketAddress socksProxyAddress) {
super();
this.soTimeout = soTimeout;
Expand All @@ -77,6 +83,9 @@ public class SocketConfig {
this.sndBufSize = sndBufSize;
this.rcvBufSize = rcvBufSize;
this.backlogSize = backlogSize;
this.tcpKeepIdle = tcpKeepIdle;
this.tcpKeepInterval = tcpKeepInterval;
this.tcpKeepCount = tcpKeepCount;
this.socksProxyAddress = socksProxyAddress;
}

Expand Down Expand Up @@ -139,6 +148,30 @@ public int getBacklogSize() {
return backlogSize;
}

/**
* @see Builder#setTcpKeepIdle(int)
* @since 5.3
*/
public int getTcpKeepIdle() {
return this.tcpKeepIdle;
}

/**
* @see Builder#setTcpKeepInterval(int)
* @since 5.3
*/
public int getTcpKeepInterval() {
return this.tcpKeepInterval;
}

/**
* @see Builder#setTcpKeepCount(int)
* @since 5.3
*/
public int getTcpKeepCount() {
return this.tcpKeepCount;
}

/**
* @see Builder#setSocksProxyAddress(SocketAddress)
*/
Expand All @@ -157,6 +190,9 @@ public String toString() {
.append(", sndBufSize=").append(this.sndBufSize)
.append(", rcvBufSize=").append(this.rcvBufSize)
.append(", backlogSize=").append(this.backlogSize)
.append(", tcpKeepIdle=").append(this.tcpKeepIdle)
.append(", tcpKeepInterval=").append(this.tcpKeepInterval)
.append(", tcpKeepCount=").append(this.tcpKeepCount)
.append(", socksProxyAddress=").append(this.socksProxyAddress)
.append("]");
return builder.toString();
Expand All @@ -177,6 +213,9 @@ public static SocketConfig.Builder copy(final SocketConfig config) {
.setSndBufSize(config.getSndBufSize())
.setRcvBufSize(config.getRcvBufSize())
.setBacklogSize(config.getBacklogSize())
.setTcpKeepIdle(config.getTcpKeepIdle())
.setTcpKeepInterval(config.getTcpKeepInterval())
.setTcpKeepCount(config.getTcpKeepCount())
.setSocksProxyAddress(config.getSocksProxyAddress());
}

Expand All @@ -190,6 +229,9 @@ public static class Builder {
private int sndBufSize;
private int rcvBufSize;
private int backlogSize;
private int tcpKeepIdle;
private int tcpKeepInterval;
private int tcpKeepCount;
private SocketAddress socksProxyAddress;

Builder() {
Expand All @@ -201,6 +243,9 @@ public static class Builder {
this.sndBufSize = 0;
this.rcvBufSize = 0;
this.backlogSize = 0;
this.tcpKeepIdle = -1;
this.tcpKeepInterval = -1;
this.tcpKeepCount = -1;
this.socksProxyAddress = null;
}

Expand Down Expand Up @@ -340,6 +385,46 @@ public Builder setBacklogSize(final int backlogSize) {
return this;
}

/**
* Determines the time (in seconds) the connection needs to remain idle before TCP starts
* sending keepalive probes.
* <p>
* Default: {@code -1} (system default)
* </p>
* @return the time (in seconds) the connection needs to remain idle before TCP starts
* @since 5.3
*/
public Builder setTcpKeepIdle(final int tcpKeepIdle) {
this.tcpKeepIdle = tcpKeepIdle;
return this;
}

/**
* Determines the time (in seconds) between individual keepalive probes.
* <p>
* Default: {@code -1} (system default)
* </p>
* @return the time (in seconds) between individual keepalive probes.
* @since 5.3
*/
public Builder setTcpKeepInterval(final int tcpKeepInterval) {
this.tcpKeepInterval = tcpKeepInterval;
return this;
}

/**
* Determines the maximum number of keepalive probes TCP should send before dropping the connection.
* <p>
* Default: {@code -1} (system default)
* </p>
* @return the maximum number of keepalive probes TCP should send before dropping the connection.
* @since 5.3
*/
public Builder setTcpKeepCount(final int tcpKeepCount) {
this.tcpKeepCount = tcpKeepCount;
return this;
}

/**
* The address of the SOCKS proxy to use.
*/
Expand All @@ -354,6 +439,7 @@ public SocketConfig build() {
soReuseAddress,
soLinger != null ? soLinger : TimeValue.NEG_ONE_SECOND,
soKeepAlive, tcpNoDelay, sndBufSize, rcvBufSize, backlogSize,
tcpKeepIdle, tcpKeepInterval, tcpKeepCount,
socksProxyAddress);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ public final class IOReactorConfig {
private final int sndBufSize;
private final int rcvBufSize;
private final int backlogSize;
private final int tcpKeepIdle;
private final int tcpKeepInterval;
private final int tcpKeepCount;
private final SocketAddress socksProxyAddress;
private final String socksProxyUsername;
private final String socksProxyPassword;
Expand All @@ -73,6 +76,9 @@ public final class IOReactorConfig {
final int sndBufSize,
final int rcvBufSize,
final int backlogSize,
final int tcpKeepIdle,
final int tcpKeepInterval,
final int tcpKeepCount,
final SocketAddress socksProxyAddress,
final String socksProxyUsername,
final String socksProxyPassword) {
Expand All @@ -88,6 +94,9 @@ public final class IOReactorConfig {
this.sndBufSize = sndBufSize;
this.rcvBufSize = rcvBufSize;
this.backlogSize = backlogSize;
this.tcpKeepIdle = tcpKeepIdle;
this.tcpKeepInterval = tcpKeepInterval;
this.tcpKeepCount = tcpKeepCount;
this.socksProxyAddress = socksProxyAddress;
this.socksProxyUsername = socksProxyUsername;
this.socksProxyPassword = socksProxyPassword;
Expand Down Expand Up @@ -182,6 +191,33 @@ public int getBacklogSize() {
return backlogSize;
}

/**
* @see Builder#setTcpKeepIdle(int)
*
* @since 5.3
*/
public int getTcpKeepIdle() {
return this.tcpKeepIdle;
}

/**
* @see Builder#setTcpKeepInterval(int)
*
* @since 5.3
*/
public int getTcpKeepInterval() {
return this.tcpKeepInterval;
}

/**
* @see Builder#setTcpKeepCount(int)
*
* @since 5.3
*/
public int getTcpKeepCount() {
return this.tcpKeepCount;
}

/**
* @see Builder#setSocksProxyAddress(SocketAddress)
*/
Expand Down Expand Up @@ -220,6 +256,9 @@ public static Builder copy(final IOReactorConfig config) {
.setSndBufSize(config.getSndBufSize())
.setRcvBufSize(config.getRcvBufSize())
.setBacklogSize(config.getBacklogSize())
.setTcpKeepIdle(config.getTcpKeepIdle())
.setTcpKeepInterval(config.getTcpKeepInterval())
.setTcpKeepCount(config.getTcpKeepCount())
.setSocksProxyAddress(config.getSocksProxyAddress())
.setSocksProxyUsername(config.getSocksProxyUsername())
.setSocksProxyPassword(config.getSocksProxyPassword());
Expand Down Expand Up @@ -265,6 +304,9 @@ public static void setDefaultMaxIOThreadCount(final int defaultMaxIOThreadCount)
private int sndBufSize;
private int rcvBufSize;
private int backlogSize;
private int tcpKeepIdle;
private int tcpKeepInterval;
private int tcpKeepCount;
private SocketAddress socksProxyAddress;
private String socksProxyUsername;
private String socksProxyPassword;
Expand All @@ -281,6 +323,9 @@ public static void setDefaultMaxIOThreadCount(final int defaultMaxIOThreadCount)
this.sndBufSize = 0;
this.rcvBufSize = 0;
this.backlogSize = 0;
this.tcpKeepIdle = -1;
this.tcpKeepInterval = -1;
this.tcpKeepCount = -1;
this.socksProxyAddress = null;
this.socksProxyUsername = null;
this.socksProxyPassword = null;
Expand Down Expand Up @@ -462,6 +507,37 @@ public Builder setBacklogSize(final int backlogSize) {
return this;
}

/**
* Determines the time (in seconds) the connection needs to remain idle before TCP starts
* sending keepalive probes.
*
* @since 5.3
*/
public Builder setTcpKeepIdle(final int tcpKeepIdle) {
this.tcpKeepIdle = tcpKeepIdle;
return this;
}

/**
* Determines the time (in seconds) between individual keepalive probes.
*
* @since 5.3
*/
public Builder setTcpKeepInterval(final int tcpKeepInterval) {
this.tcpKeepInterval = tcpKeepInterval;
return this;
}

/**
* Determines the maximum number of keepalive probes TCP should send before dropping the connection.
*
* @since 5.3
*/
public Builder setTcpKeepCount(final int tcpKeepCount) {
this.tcpKeepCount = tcpKeepCount;
return this;
}

/**
* The address of the SOCKS proxy to use.
*/
Expand Down Expand Up @@ -497,6 +573,7 @@ public IOReactorConfig build() {
tcpNoDelay,
trafficClass,
sndBufSize, rcvBufSize, backlogSize,
tcpKeepIdle, tcpKeepInterval, tcpKeepCount,
socksProxyAddress, socksProxyUsername, socksProxyPassword);
}

Expand Down
Loading

0 comments on commit d5f903a

Please sign in to comment.