You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2025/05/22 17:00:37 UTC
(tomcat) branch main updated (0f72e51cad -> 9432ba7054)
This is an automated email from the ASF dual-hosted git repository.
markt pushed a change to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git
from 0f72e51cad Code clean-up - formatting. No functional change.
new 5a5afb6e96 Improve formatting
new 9432ba7054 Code clean-up - formatting. No functional change.
The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
.../apache/tomcat/util/net/AbstractEndpoint.java | 540 +++++++++-------
.../util/net/AbstractNetworkChannelEndpoint.java | 3 +-
java/org/apache/tomcat/util/net/Acceptor.java | 28 +-
.../tomcat/util/net/ApplicationBufferHandler.java | 7 +-
java/org/apache/tomcat/util/net/Constants.java | 21 +-
java/org/apache/tomcat/util/net/DispatchType.java | 5 +-
java/org/apache/tomcat/util/net/IPv6Utils.java | 65 +-
java/org/apache/tomcat/util/net/NioChannel.java | 57 +-
java/org/apache/tomcat/util/net/NioEndpoint.java | 326 +++++-----
java/org/apache/tomcat/util/net/SSLContext.java | 8 +-
java/org/apache/tomcat/util/net/SSLHostConfig.java | 73 +--
.../tomcat/util/net/SSLHostConfigCertificate.java | 37 +-
.../apache/tomcat/util/net/SSLImplementation.java | 26 +-
.../apache/tomcat/util/net/SSLSessionManager.java | 3 +-
java/org/apache/tomcat/util/net/SSLSupport.java | 82 +--
java/org/apache/tomcat/util/net/SSLUtil.java | 39 +-
java/org/apache/tomcat/util/net/SSLUtilBase.java | 126 ++--
.../apache/tomcat/util/net/SecureNioChannel.java | 302 ++++-----
.../apache/tomcat/util/net/SendfileDataBase.java | 20 +-
.../tomcat/util/net/SendfileKeepAliveState.java | 12 +-
java/org/apache/tomcat/util/net/SendfileState.java | 6 +-
.../tomcat/util/net/ServletConnectionImpl.java | 4 +-
.../tomcat/util/net/SocketBufferHandler.java | 14 +-
java/org/apache/tomcat/util/net/SocketEvent.java | 24 +-
.../apache/tomcat/util/net/SocketProperties.java | 125 ++--
.../apache/tomcat/util/net/SocketWrapperBase.java | 688 +++++++++------------
.../tomcat/util/net/TLSClientHelloExtractor.java | 56 +-
java/org/apache/tomcat/util/net/WriteBuffer.java | 22 +-
28 files changed, 1340 insertions(+), 1379 deletions(-)
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org
(tomcat) 01/02: Improve formatting
Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
markt pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit 5a5afb6e9626392d5b86ad81f329e5f50076bc44
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Thu May 22 18:00:08 2025 +0100
Improve formatting
---
.../apache/tomcat/util/net/SocketProperties.java | 42 ++++++++++++----------
1 file changed, 24 insertions(+), 18 deletions(-)
diff --git a/java/org/apache/tomcat/util/net/SocketProperties.java b/java/org/apache/tomcat/util/net/SocketProperties.java
index 92bbc2d8bc..9fdd494700 100644
--- a/java/org/apache/tomcat/util/net/SocketProperties.java
+++ b/java/org/apache/tomcat/util/net/SocketProperties.java
@@ -42,9 +42,10 @@ public class SocketProperties {
/**
* Enable/disable socket processor cache, this bounded cache stores
- * SocketProcessor objects to reduce GC
- * Default is 0
- * -1 is unlimited
+ * SocketProcessor objects to reduce GC.
+ * <p>
+ * Default is 0<br>
+ * -1 is unlimited<br>
* 0 is disabled
*/
protected int processorCache = 0;
@@ -52,22 +53,23 @@ public class SocketProperties {
/**
* Enable/disable poller event cache, this bounded cache stores
* PollerEvent objects to reduce GC for the poller
- * Default is 0
- * -1 is unlimited
- * 0 is disabled
+ * <p>
+ * Default is 0<br>
+ * -1 is unlimited<br>
+ * 0 is disabled<br>
* >0 the max number of objects to keep in cache.
*/
protected int eventCache = 0;
/**
- * Enable/disable direct buffers for the network buffers
- * Default value is disabled
+ * Enable/disable direct buffers for the network buffers.
+ * Default value is disabled.
*/
protected boolean directBuffer = false;
/**
- * Enable/disable direct buffers for the network buffers for SSL
- * Default value is disabled
+ * Enable/disable direct buffers for the network buffers for SSL.
+ * Default value is disabled.
*/
protected boolean directSslBuffer = false;
@@ -85,28 +87,32 @@ public class SocketProperties {
/**
* The application read buffer size in bytes.
- * Default value is 8192
+ * Default value is 8192.
*/
protected int appReadBufSize = 8192;
/**
- * The application write buffer size in bytes
- * Default value is 8192
+ * The application write buffer size in bytes.
+ * Default value is 8192.
*/
protected int appWriteBufSize = 8192;
/**
* NioChannel pool size for the endpoint,
- * this value is how many channels
- * -1 means unlimited cached, 0 means no cache,
- * -2 means bufferPoolSize will be used
+ * this value is how many channels.
+ * <p>
+ * 0 means no cache<br>
+ * -1 means unlimited cached<br>
+ * -2 means bufferPoolSize will be used<br>
* Default value is -2
*/
protected int bufferPool = -2;
/**
- * Buffer pool size in bytes to be cached
- * -1 means unlimited, 0 means no cache
+ * Buffer pool size in bytes to be cached.
+ * <p>
+ * -1 means unlimited<br>
+ * 0 means no cache<br>
* Default value is based on the max memory reported by the JVM,
* if less than 1GB, then 0, else the value divided by 32. This value
* will then be used to compute bufferPool if its value is -2
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org
(tomcat) 02/02: Code clean-up - formatting. No functional change.
Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
markt pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit 9432ba70546820dcda27738c932c828282cd676a
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Thu May 22 18:00:32 2025 +0100
Code clean-up - formatting. No functional change.
---
.../apache/tomcat/util/net/AbstractEndpoint.java | 540 +++++++++-------
.../util/net/AbstractNetworkChannelEndpoint.java | 3 +-
java/org/apache/tomcat/util/net/Acceptor.java | 28 +-
.../tomcat/util/net/ApplicationBufferHandler.java | 7 +-
java/org/apache/tomcat/util/net/Constants.java | 21 +-
java/org/apache/tomcat/util/net/DispatchType.java | 5 +-
java/org/apache/tomcat/util/net/IPv6Utils.java | 65 +-
java/org/apache/tomcat/util/net/NioChannel.java | 57 +-
java/org/apache/tomcat/util/net/NioEndpoint.java | 326 +++++-----
java/org/apache/tomcat/util/net/SSLContext.java | 8 +-
java/org/apache/tomcat/util/net/SSLHostConfig.java | 73 +--
.../tomcat/util/net/SSLHostConfigCertificate.java | 37 +-
.../apache/tomcat/util/net/SSLImplementation.java | 26 +-
.../apache/tomcat/util/net/SSLSessionManager.java | 3 +-
java/org/apache/tomcat/util/net/SSLSupport.java | 82 +--
java/org/apache/tomcat/util/net/SSLUtil.java | 39 +-
java/org/apache/tomcat/util/net/SSLUtilBase.java | 126 ++--
.../apache/tomcat/util/net/SecureNioChannel.java | 302 ++++-----
.../apache/tomcat/util/net/SendfileDataBase.java | 20 +-
.../tomcat/util/net/SendfileKeepAliveState.java | 12 +-
java/org/apache/tomcat/util/net/SendfileState.java | 6 +-
.../tomcat/util/net/ServletConnectionImpl.java | 4 +-
.../tomcat/util/net/SocketBufferHandler.java | 14 +-
java/org/apache/tomcat/util/net/SocketEvent.java | 24 +-
.../apache/tomcat/util/net/SocketProperties.java | 101 ++-
.../apache/tomcat/util/net/SocketWrapperBase.java | 688 +++++++++------------
.../tomcat/util/net/TLSClientHelloExtractor.java | 56 +-
java/org/apache/tomcat/util/net/WriteBuffer.java | 22 +-
28 files changed, 1325 insertions(+), 1370 deletions(-)
diff --git a/java/org/apache/tomcat/util/net/AbstractEndpoint.java b/java/org/apache/tomcat/util/net/AbstractEndpoint.java
index 0b7cb7c5da..ef2b9dc1b7 100644
--- a/java/org/apache/tomcat/util/net/AbstractEndpoint.java
+++ b/java/org/apache/tomcat/util/net/AbstractEndpoint.java
@@ -65,15 +65,13 @@ import org.apache.tomcat.util.threads.ThreadPoolExecutor;
import org.apache.tomcat.util.threads.VirtualThreadExecutor;
/**
- * @param <S> The type used by the socket wrapper associated with this endpoint.
- * Might be the same as U.
- * @param <U> The type of the underlying socket used by this endpoint. Might be
- * the same as S.
+ * @param <S> The type used by the socket wrapper associated with this endpoint. Might be the same as U.
+ * @param <U> The type of the underlying socket used by this endpoint. Might be the same as S.
*
* @author Mladen Turk
* @author Remy Maucherat
*/
-public abstract class AbstractEndpoint<S,U> {
+public abstract class AbstractEndpoint<S, U> {
// -------------------------------------------------------------- Constants
@@ -86,8 +84,16 @@ public abstract class AbstractEndpoint<S,U> {
*/
enum SocketState {
// TODO Add a new state to the AsyncStateMachine and remove
- // ASYNC_END (if possible)
- OPEN, CLOSED, LONG, ASYNC_END, SENDFILE, UPGRADING, UPGRADED, ASYNC_IO, SUSPENDED
+ // ASYNC_END (if possible)
+ OPEN,
+ CLOSED,
+ LONG,
+ ASYNC_END,
+ SENDFILE,
+ UPGRADING,
+ UPGRADED,
+ ASYNC_IO,
+ SUSPENDED
}
@@ -99,8 +105,7 @@ public abstract class AbstractEndpoint<S,U> {
*
* @return The state of the socket after processing
*/
- SocketState process(SocketWrapperBase<S> socket,
- SocketEvent status);
+ SocketState process(SocketWrapperBase<S> socket, SocketEvent status);
/**
@@ -120,10 +125,9 @@ public abstract class AbstractEndpoint<S,U> {
/**
- * Inform the handler that the endpoint has stopped accepting any new
- * connections. Typically, the endpoint will be stopped shortly
- * afterwards but it is possible that the endpoint will be resumed so
- * the handler should not assume that a stop will follow.
+ * Inform the handler that the endpoint has stopped accepting any new connections. Typically, the endpoint will
+ * be stopped shortly afterwards but it is possible that the endpoint will be resumed so the handler should not
+ * assume that a stop will follow.
*/
void pause();
@@ -191,6 +195,7 @@ public abstract class AbstractEndpoint<S,U> {
* Socket properties
*/
protected final SocketProperties socketProperties = new SocketProperties();
+
public SocketProperties getSocketProperties() {
return socketProperties;
}
@@ -210,10 +215,11 @@ public abstract class AbstractEndpoint<S,U> {
/**
* Map holding all current connections keyed with the sockets.
*/
- protected Map<U, SocketWrapperBase<S>> connections = new ConcurrentHashMap<>();
+ protected Map<U,SocketWrapperBase<S>> connections = new ConcurrentHashMap<>();
/**
* Get a set with the current open connections.
+ *
* @return A set with the open socket wrappers
*/
public Set<SocketWrapperBase<S>> getConnections() {
@@ -221,6 +227,7 @@ public abstract class AbstractEndpoint<S,U> {
}
private SSLImplementation sslImplementation = null;
+
public SSLImplementation getSslImplementation() {
return sslImplementation;
}
@@ -229,70 +236,71 @@ public abstract class AbstractEndpoint<S,U> {
// ----------------------------------------------------------------- Properties
private String sslImplementationName = null;
+
public String getSslImplementationName() {
return sslImplementationName;
}
+
public void setSslImplementationName(String s) {
this.sslImplementationName = s;
}
private int sniParseLimit = 64 * 1024;
+
public int getSniParseLimit() {
return sniParseLimit;
}
+
public void setSniParseLimit(int sniParseLimit) {
this.sniParseLimit = sniParseLimit;
}
private String defaultSSLHostConfigName = SSLHostConfig.DEFAULT_SSL_HOST_NAME;
+
/**
- * @return The host name for the default SSL configuration for this endpoint
- * - always in lower case.
+ * @return The host name for the default SSL configuration for this endpoint - always in lower case.
*/
public String getDefaultSSLHostConfigName() {
return defaultSSLHostConfigName;
}
+
public void setDefaultSSLHostConfigName(String defaultSSLHostConfigName) {
this.defaultSSLHostConfigName = defaultSSLHostConfigName.toLowerCase(Locale.ENGLISH);
}
protected ConcurrentMap<String,SSLHostConfig> sslHostConfigs = new ConcurrentHashMap<>();
+
/**
* Add the given SSL Host configuration.
*
* @param sslHostConfig The configuration to add
*
- * @throws IllegalArgumentException If the host name is not valid or if a
- * configuration has already been provided
- * for that host
+ * @throws IllegalArgumentException If the host name is not valid or if a configuration has already been provided
+ * for that host
*/
public void addSslHostConfig(SSLHostConfig sslHostConfig) throws IllegalArgumentException {
addSslHostConfig(sslHostConfig, false);
}
+
/**
- * Add the given SSL Host configuration, optionally replacing the existing
- * configuration for the given host.
+ * Add the given SSL Host configuration, optionally replacing the existing configuration for the given host.
*
* @param sslHostConfig The configuration to add
- * @param replace If {@code true} replacement of an existing
- * configuration is permitted, otherwise any such
- * attempted replacement will trigger an exception
+ * @param replace If {@code true} replacement of an existing configuration is permitted, otherwise any such
+ * attempted replacement will trigger an exception
*
- * @throws IllegalArgumentException If the host name is not valid or if a
- * configuration has already been provided
- * for that host and replacement is not
- * allowed
+ * @throws IllegalArgumentException If the host name is not valid or if a configuration has already been provided
+ * for that host and replacement is not allowed
*/
public void addSslHostConfig(SSLHostConfig sslHostConfig, boolean replace) throws IllegalArgumentException {
String key = sslHostConfig.getHostName();
if (key == null || key.isEmpty()) {
throw new IllegalArgumentException(sm.getString("endpoint.noSslHostName"));
}
- if (bindState != BindState.UNBOUND && bindState != BindState.SOCKET_CLOSED_ON_STOP &&
- isSSLEnabled()) {
+ if (bindState != BindState.UNBOUND && bindState != BindState.SOCKET_CLOSED_ON_STOP && isSSLEnabled()) {
try {
createSSLContext(sslHostConfig);
} catch (IllegalArgumentException e) {
@@ -321,14 +329,13 @@ public abstract class AbstractEndpoint<S,U> {
registerJmx(sslHostConfig);
}
}
+
/**
- * Removes the SSL host configuration for the given host name, if such a
- * configuration exists.
+ * Removes the SSL host configuration for the given host name, if such a configuration exists.
*
- * @param hostName The host name associated with the SSL host configuration
- * to remove
+ * @param hostName The host name associated with the SSL host configuration to remove
*
- * @return The SSL host configuration that was removed, if any
+ * @return The SSL host configuration that was removed, if any
*/
public SSLHostConfig removeSslHostConfig(String hostName) {
if (hostName == null) {
@@ -339,20 +346,18 @@ public abstract class AbstractEndpoint<S,U> {
// keys are compared in a case-sensitive manner.
String hostNameLower = hostName.toLowerCase(Locale.ENGLISH);
if (hostNameLower.equals(getDefaultSSLHostConfigName())) {
- throw new IllegalArgumentException(
- sm.getString("endpoint.removeDefaultSslHostConfig", hostName));
+ throw new IllegalArgumentException(sm.getString("endpoint.removeDefaultSslHostConfig", hostName));
}
SSLHostConfig sslHostConfig = sslHostConfigs.remove(hostNameLower);
unregisterJmx(sslHostConfig);
return sslHostConfig;
}
+
/**
- * Re-read the configuration files for the SSL host and replace the existing
- * SSL configuration with the updated settings. Note this replacement will
- * happen even if the settings remain unchanged.
+ * Re-read the configuration files for the SSL host and replace the existing SSL configuration with the updated
+ * settings. Note this replacement will happen even if the settings remain unchanged.
*
- * @param hostName The SSL host for which the configuration should be
- * reloaded. This must match a current SSL host
+ * @param hostName The SSL host for which the configuration should be reloaded. This must match a current SSL host
*/
public void reloadSslHostConfig(String hostName) {
// Host names are case-insensitive but stored/processed in lower case
@@ -363,21 +368,21 @@ public abstract class AbstractEndpoint<S,U> {
// the call path.
SSLHostConfig sslHostConfig = sslHostConfigs.get(hostName.toLowerCase(Locale.ENGLISH));
if (sslHostConfig == null) {
- throw new IllegalArgumentException(
- sm.getString("endpoint.unknownSslHostName", hostName));
+ throw new IllegalArgumentException(sm.getString("endpoint.unknownSslHostName", hostName));
}
addSslHostConfig(sslHostConfig, true);
}
+
/**
- * Re-read the configuration files for all SSL hosts and replace the
- * existing SSL configuration with the updated settings. Note this
- * replacement will happen even if the settings remain unchanged.
+ * Re-read the configuration files for all SSL hosts and replace the existing SSL configuration with the updated
+ * settings. Note this replacement will happen even if the settings remain unchanged.
*/
public void reloadSslHostConfigs() {
for (String hostName : sslHostConfigs.keySet()) {
reloadSslHostConfig(hostName);
}
}
+
public SSLHostConfig[] findSslHostConfigs() {
return sslHostConfigs.values().toArray(new SSLHostConfig[0]);
}
@@ -385,17 +390,15 @@ public abstract class AbstractEndpoint<S,U> {
/**
* Create the SSLContext for the given SSLHostConfig.
*
- * @param sslHostConfig The SSLHostConfig for which the SSLContext should be
- * created
- * @throws IllegalArgumentException If the SSLContext cannot be created for
- * the given SSLHostConfig
+ * @param sslHostConfig The SSLHostConfig for which the SSLContext should be created
+ *
+ * @throws IllegalArgumentException If the SSLContext cannot be created for the given SSLHostConfig
*/
protected void createSSLContext(SSLHostConfig sslHostConfig) throws IllegalArgumentException {
// HTTP/2 does not permit optional certificate authentication with any
// version of TLS.
- if (sslHostConfig.getCertificateVerification().isOptional() &&
- negotiableProtocols.contains("h2")) {
+ if (sslHostConfig.getCertificateVerification().isOptional() && negotiableProtocols.contains("h2")) {
getLog().warn(sm.getString("sslHostConfig.certificateVerificationWithHttp2", sslHostConfig.getHostName()));
}
@@ -412,10 +415,10 @@ public abstract class AbstractEndpoint<S,U> {
SSLContext sslContextGenerated = certificate.getSslContextGenerated();
// Generate the SSLContext from configuration unless (e.g. embedded) an SSLContext has been provided.
// Need to handle both initial configuration and reload.
- // Initial, SSLContext provided - sslContext will be non-null and sslContextGenerated will be null
+ // Initial, SSLContext provided - sslContext will be non-null and sslContextGenerated will be null
// Initial, SSLContext not provided - sslContext null and sslContextGenerated will be null
- // Reload, SSLContext provided - sslContext will be non-null and sslContextGenerated will be null
- // Reload, SSLContext not provided - sslContext non-null and equal to sslContextGenerated
+ // Reload, SSLContext provided - sslContext will be non-null and sslContextGenerated will be null
+ // Reload, SSLContext not provided - sslContext non-null and equal to sslContextGenerated
if (sslContext == null || sslContext == sslContextGenerated) {
try {
sslContext = sslUtil.createSSLContext(negotiableProtocols);
@@ -512,8 +515,7 @@ public abstract class AbstractEndpoint<S,U> {
SSLContext sslContext = certificate.getSslContext();
if (sslContext == null) {
- throw new IllegalStateException(
- sm.getString("endpoint.jsse.noSslContext", sniHostName));
+ throw new IllegalStateException(sm.getString("endpoint.jsse.noSslContext", sniHostName));
}
SSLEngine engine = sslContext.createSSLEngine();
@@ -523,9 +525,8 @@ public abstract class AbstractEndpoint<S,U> {
SSLParameters sslParameters = engine.getSSLParameters();
sslParameters.setUseCipherSuitesOrder(sslHostConfig.getHonorCipherOrder());
- if (clientRequestedApplicationProtocols != null
- && !clientRequestedApplicationProtocols.isEmpty()
- && !negotiableProtocols.isEmpty()) {
+ if (clientRequestedApplicationProtocols != null && !clientRequestedApplicationProtocols.isEmpty() &&
+ !negotiableProtocols.isEmpty()) {
// Only try to negotiate if both client and server have at least
// one protocol in common
// Note: Tomcat does not explicitly negotiate http/1.1
@@ -537,17 +538,17 @@ public abstract class AbstractEndpoint<S,U> {
}
}
switch (sslHostConfig.getCertificateVerification()) {
- case NONE:
- sslParameters.setNeedClientAuth(false);
- sslParameters.setWantClientAuth(false);
- break;
- case OPTIONAL:
- case OPTIONAL_NO_CA:
- sslParameters.setWantClientAuth(true);
- break;
- case REQUIRED:
- sslParameters.setNeedClientAuth(true);
- break;
+ case NONE:
+ sslParameters.setNeedClientAuth(false);
+ sslParameters.setWantClientAuth(false);
+ break;
+ case OPTIONAL:
+ case OPTIONAL_NO_CA:
+ sslParameters.setWantClientAuth(true);
+ break;
+ case REQUIRED:
+ sslParameters.setNeedClientAuth(true);
+ break;
}
// The getter (at least in OpenJDK and derivatives) returns a defensive copy
engine.setSSLParameters(sslParameters);
@@ -556,8 +557,7 @@ public abstract class AbstractEndpoint<S,U> {
}
- private SSLHostConfigCertificate selectCertificate(
- SSLHostConfig sslHostConfig, List<Cipher> clientCiphers) {
+ private SSLHostConfigCertificate selectCertificate(SSLHostConfig sslHostConfig, List<Cipher> clientCiphers) {
Set<SSLHostConfigCertificate> certificates = sslHostConfig.getCertificates(true);
if (certificates.size() == 1) {
@@ -599,8 +599,8 @@ public abstract class AbstractEndpoint<S,U> {
// Validate default SSLHostConfigName
if (sslHostConfigs.get(getDefaultSSLHostConfigName()) == null) {
- throw new IllegalArgumentException(sm.getString("endpoint.noSslHostConfig",
- getDefaultSSLHostConfigName(), getName()));
+ throw new IllegalArgumentException(
+ sm.getString("endpoint.noSslHostConfig", getDefaultSSLHostConfigName(), getName()));
}
}
@@ -619,8 +619,7 @@ public abstract class AbstractEndpoint<S,U> {
/**
* Release the SSLContext, if any, associated with the SSLHostConfig.
*
- * @param sslHostConfig The SSLHostConfig for which the SSLContext should be
- * released
+ * @param sslHostConfig The SSLHostConfig for which the SSLContext should be released
*/
protected void releaseSSLContext(SSLHostConfig sslHostConfig) {
for (SSLHostConfigCertificate certificate : sslHostConfig.getCertificates()) {
@@ -643,7 +642,7 @@ public abstract class AbstractEndpoint<S,U> {
* <li>default SSLHostConfig</li>
* </ol>
*
- * @param sniHostName Host name - must be in lower case
+ * @param sniHostName Host name - must be in lower case
*
* @return The SSLHostConfig for the given host name.
*/
@@ -679,17 +678,19 @@ public abstract class AbstractEndpoint<S,U> {
* Has the user requested that send file be used where possible?
*/
private boolean useSendfile = true;
+
public boolean getUseSendfile() {
return useSendfile;
}
+
public void setUseSendfile(boolean useSendfile) {
this.useSendfile = useSendfile;
}
/**
- * Time to wait for the internal executor (if used) to terminate when the
- * endpoint is stopped in milliseconds. Defaults to 5000 (5 seconds).
+ * Time to wait for the internal executor (if used) to terminate when the endpoint is stopped in milliseconds.
+ * Defaults to 5000 (5 seconds).
*/
private long executorTerminationTimeoutMillis = 5000;
@@ -697,8 +698,7 @@ public abstract class AbstractEndpoint<S,U> {
return executorTerminationTimeoutMillis;
}
- public void setExecutorTerminationTimeoutMillis(
- long executorTerminationTimeoutMillis) {
+ public void setExecutorTerminationTimeoutMillis(long executorTerminationTimeoutMillis) {
this.executorTerminationTimeoutMillis = executorTerminationTimeoutMillis;
}
@@ -707,13 +707,18 @@ public abstract class AbstractEndpoint<S,U> {
* Priority of the acceptor threads.
*/
protected int acceptorThreadPriority = Thread.NORM_PRIORITY;
+
public void setAcceptorThreadPriority(int acceptorThreadPriority) {
this.acceptorThreadPriority = acceptorThreadPriority;
}
- public int getAcceptorThreadPriority() { return acceptorThreadPriority; }
+ public int getAcceptorThreadPriority() {
+ return acceptorThreadPriority;
+ }
+
+
+ private int maxConnections = 8 * 1024;
- private int maxConnections = 8*1024;
public void setMaxConnections(int maxCon) {
this.maxConnections = maxCon;
LimitLatch latch = this.connectionLimitLatch;
@@ -728,19 +733,19 @@ public abstract class AbstractEndpoint<S,U> {
initializeConnectionLatch();
}
}
- public int getMaxConnections() { return this.maxConnections; }
+
+ public int getMaxConnections() {
+ return this.maxConnections;
+ }
/**
- * Return the current count of connections handled by this endpoint, if the
- * connections are counted (which happens when the maximum count of
- * connections is limited), or <code>-1</code> if they are not. This
- * property is added here so that this value can be inspected through JMX.
- * It is visible on "ThreadPool" MBean.
- *
- * <p>The count is incremented by the Acceptor before it tries to accept a
- * new connection. Until the limit is reached and thus the count cannot be
- * incremented, this value is more by 1 (the count of acceptors) than the
- * actual count of connections that are being served.
+ * Return the current count of connections handled by this endpoint, if the connections are counted (which happens
+ * when the maximum count of connections is limited), or <code>-1</code> if they are not. This property is added
+ * here so that this value can be inspected through JMX. It is visible on "ThreadPool" MBean.
+ * <p>
+ * The count is incremented by the Acceptor before it tries to accept a new connection. Until the limit is reached
+ * and thus the count cannot be incremented, this value is more by 1 (the count of acceptors) than the actual count
+ * of connections that are being served.
*
* @return The count
*/
@@ -756,17 +761,23 @@ public abstract class AbstractEndpoint<S,U> {
* External Executor based thread pool.
*/
private Executor executor = null;
+
public void setExecutor(Executor executor) {
this.executor = executor;
this.internalExecutor = (executor == null);
}
- public Executor getExecutor() { return executor; }
+
+ public Executor getExecutor() {
+ return executor;
+ }
private boolean useVirtualThreads = false;
+
public void setUseVirtualThreads(boolean useVirtualThreads) {
this.useVirtualThreads = useVirtualThreads;
}
+
public boolean getUseVirtualThreads() {
return useVirtualThreads;
}
@@ -776,9 +787,11 @@ public abstract class AbstractEndpoint<S,U> {
* External Executor based thread pool for utility tasks.
*/
private ScheduledExecutorService utilityExecutor = null;
+
public void setUtilityExecutor(ScheduledExecutorService utilityExecutor) {
this.utilityExecutor = utilityExecutor;
}
+
public ScheduledExecutorService getUtilityExecutor() {
if (utilityExecutor == null) {
getLog().warn(sm.getString("endpoint.warn.noUtilityExecutor"));
@@ -792,13 +805,23 @@ public abstract class AbstractEndpoint<S,U> {
* Server socket port.
*/
private int port = -1;
- public int getPort() { return port; }
- public void setPort(int port ) { this.port=port; }
+
+ public int getPort() {
+ return port;
+ }
+
+ public void setPort(int port) {
+ this.port = port;
+ }
private int portOffset = 0;
- public int getPortOffset() { return portOffset; }
- public void setPortOffset(int portOffset ) {
+
+ public int getPortOffset() {
+ return portOffset;
+ }
+
+ public void setPortOffset(int portOffset) {
if (portOffset < 0) {
throw new IllegalArgumentException(
sm.getString("endpoint.portOffset.invalid", Integer.valueOf(portOffset)));
@@ -834,46 +857,62 @@ public abstract class AbstractEndpoint<S,U> {
* Address for the server socket.
*/
private InetAddress address;
- public InetAddress getAddress() { return address; }
- public void setAddress(InetAddress address) { this.address = address; }
+
+ public InetAddress getAddress() {
+ return address;
+ }
+
+ public void setAddress(InetAddress address) {
+ this.address = address;
+ }
/**
- * Obtain the network address the server socket is bound to. This primarily
- * exists to enable the correct address to be used when unlocking the server
- * socket since it removes the guess-work involved if no address is
- * specifically set.
+ * Obtain the network address the server socket is bound to. This primarily exists to enable the correct address to
+ * be used when unlocking the server socket since it removes the guess-work involved if no address is specifically
+ * set.
*
- * @return The network address that the server socket is listening on or
- * null if the server socket is not currently bound.
+ * @return The network address that the server socket is listening on or null if the server socket is not currently
+ * bound.
*
- * @throws IOException If there is a problem determining the currently bound
- * socket
+ * @throws IOException If there is a problem determining the currently bound socket
*/
protected abstract InetSocketAddress getLocalAddress() throws IOException;
/**
- * Allows the server developer to specify the acceptCount (backlog) that
- * should be used for server sockets. By default, this value
- * is 100.
+ * Allows the server developer to specify the acceptCount (backlog) that should be used for server sockets. By
+ * default, this value is 100.
*/
private int acceptCount = 100;
- public void setAcceptCount(int acceptCount) { if (acceptCount > 0) {
- this.acceptCount = acceptCount;
- } }
- public int getAcceptCount() { return acceptCount; }
+
+ public void setAcceptCount(int acceptCount) {
+ if (acceptCount > 0) {
+ this.acceptCount = acceptCount;
+ }
+ }
+
+ public int getAcceptCount() {
+ return acceptCount;
+ }
/**
- * Controls when the Endpoint binds the port. <code>true</code>, the default
- * binds the port on {@link #init()} and unbinds it on {@link #destroy()}.
- * If set to <code>false</code> the port is bound on {@link #start()} and
- * unbound on {@link #stop()}.
+ * Controls when the Endpoint binds the port. <code>true</code>, the default binds the port on {@link #init()} and
+ * unbinds it on {@link #destroy()}. If set to <code>false</code> the port is bound on {@link #start()} and unbound
+ * on {@link #stop()}.
*/
private boolean bindOnInit = true;
- public boolean getBindOnInit() { return bindOnInit; }
- public void setBindOnInit(boolean b) { this.bindOnInit = b; }
+
+ public boolean getBindOnInit() {
+ return bindOnInit;
+ }
+
+ public void setBindOnInit(boolean b) {
+ this.bindOnInit = b;
+ }
+
private volatile BindState bindState = BindState.UNBOUND;
+
protected BindState getBindState() {
return bindState;
}
@@ -882,6 +921,7 @@ public abstract class AbstractEndpoint<S,U> {
* Keepalive timeout, if not set the soTimeout is used.
*/
private Integer keepAliveTimeout = null;
+
public int getKeepAliveTimeout() {
if (keepAliveTimeout == null) {
return getConnectionTimeout();
@@ -889,6 +929,7 @@ public abstract class AbstractEndpoint<S,U> {
return keepAliveTimeout.intValue();
}
}
+
public void setKeepAliveTimeout(int keepAliveTimeout) {
this.keepAliveTimeout = Integer.valueOf(keepAliveTimeout);
}
@@ -897,23 +938,29 @@ public abstract class AbstractEndpoint<S,U> {
/**
* Socket TCP no delay.
*
- * @return The current TCP no delay setting for sockets created by this
- * endpoint
+ * @return The current TCP no delay setting for sockets created by this endpoint
*/
- public boolean getTcpNoDelay() { return socketProperties.getTcpNoDelay();}
- public void setTcpNoDelay(boolean tcpNoDelay) { socketProperties.setTcpNoDelay(tcpNoDelay); }
+ public boolean getTcpNoDelay() {
+ return socketProperties.getTcpNoDelay();
+ }
+
+ public void setTcpNoDelay(boolean tcpNoDelay) {
+ socketProperties.setTcpNoDelay(tcpNoDelay);
+ }
/**
* Socket linger.
*
- * @return The current socket linger time for sockets created by this
- * endpoint
+ * @return The current socket linger time for sockets created by this endpoint
*/
- public int getConnectionLinger() { return socketProperties.getSoLingerTime(); }
+ public int getConnectionLinger() {
+ return socketProperties.getSoLingerTime();
+ }
+
public void setConnectionLinger(int connectionLinger) {
socketProperties.setSoLingerTime(connectionLinger);
- socketProperties.setSoLingerOn(connectionLinger>=0);
+ socketProperties.setSoLingerOn(connectionLinger >= 0);
}
@@ -922,17 +969,29 @@ public abstract class AbstractEndpoint<S,U> {
*
* @return The current socket timeout for sockets created by this endpoint
*/
- public int getConnectionTimeout() { return socketProperties.getSoTimeout(); }
- public void setConnectionTimeout(int soTimeout) { socketProperties.setSoTimeout(soTimeout); }
+ public int getConnectionTimeout() {
+ return socketProperties.getSoTimeout();
+ }
+
+ public void setConnectionTimeout(int soTimeout) {
+ socketProperties.setSoTimeout(soTimeout);
+ }
/**
* SSL engine.
*/
private boolean SSLEnabled = false;
- public boolean isSSLEnabled() { return SSLEnabled; }
- public void setSSLEnabled(boolean SSLEnabled) { this.SSLEnabled = SSLEnabled; }
+
+ public boolean isSSLEnabled() {
+ return SSLEnabled;
+ }
+
+ public void setSSLEnabled(boolean SSLEnabled) {
+ this.SSLEnabled = SSLEnabled;
+ }
private int minSpareThreads = 10;
+
public void setMinSpareThreads(int minSpareThreads) {
this.minSpareThreads = minSpareThreads;
Executor executor = this.executor;
@@ -944,9 +1003,11 @@ public abstract class AbstractEndpoint<S,U> {
((ThreadPoolExecutor) executor).setCorePoolSize(minSpareThreads);
}
}
+
public int getMinSpareThreads() {
return Math.min(getMinSpareThreadsInternal(), getMaxThreads());
}
+
private int getMinSpareThreadsInternal() {
if (internalExecutor) {
return minSpareThreads;
@@ -960,6 +1021,7 @@ public abstract class AbstractEndpoint<S,U> {
* Maximum amount of worker threads.
*/
private int maxThreads = 200;
+
public void setMaxThreads(int maxThreads) {
this.maxThreads = maxThreads;
Executor executor = this.executor;
@@ -971,6 +1033,7 @@ public abstract class AbstractEndpoint<S,U> {
((ThreadPoolExecutor) executor).setMaximumPoolSize(maxThreads);
}
}
+
public int getMaxThreads() {
if (internalExecutor) {
return maxThreads;
@@ -984,9 +1047,11 @@ public abstract class AbstractEndpoint<S,U> {
* Task queue capacity for the thread pool.
*/
private int maxQueueSize = Integer.MAX_VALUE;
+
public void setMaxQueueSize(int maxQueueSize) {
this.maxQueueSize = maxQueueSize;
}
+
public int getMaxQueueSize() {
if (internalExecutor) {
return maxQueueSize;
@@ -997,10 +1062,11 @@ public abstract class AbstractEndpoint<S,U> {
/**
- * Amount of time in milliseconds before the internal thread pool stops any idle threads
- * if the amount of thread is greater than the minimum amount of spare threads.
+ * Amount of time in milliseconds before the internal thread pool stops any idle threads if the amount of thread is
+ * greater than the minimum amount of spare threads.
*/
private int threadsMaxIdleTime = 60000;
+
public void setThreadsMaxIdleTime(int threadsMaxIdleTime) {
this.threadsMaxIdleTime = threadsMaxIdleTime;
Executor executor = this.executor;
@@ -1012,6 +1078,7 @@ public abstract class AbstractEndpoint<S,U> {
((ThreadPoolExecutor) executor).setKeepAliveTime(threadsMaxIdleTime, TimeUnit.MILLISECONDS);
}
}
+
public int getThreadsMaxIdleTime() {
if (internalExecutor) {
return threadsMaxIdleTime;
@@ -1024,10 +1091,12 @@ public abstract class AbstractEndpoint<S,U> {
* Priority of the worker threads.
*/
protected int threadPriority = Thread.NORM_PRIORITY;
+
public void setThreadPriority(int threadPriority) {
// Can't change this once the executor has started
this.threadPriority = threadPriority;
}
+
public int getThreadPriority() {
if (internalExecutor) {
return threadPriority;
@@ -1040,7 +1109,8 @@ public abstract class AbstractEndpoint<S,U> {
/**
* Max keep alive requests
*/
- private int maxKeepAliveRequests=100; // as in Apache HTTPD server
+ private int maxKeepAliveRequests = 100; // as in Apache HTTPD server
+
public int getMaxKeepAliveRequests() {
// Disable keep-alive if the server socket is not bound
if (bindState.isBound()) {
@@ -1049,6 +1119,7 @@ public abstract class AbstractEndpoint<S,U> {
return 1;
}
}
+
public void setMaxKeepAliveRequests(int maxKeepAliveRequests) {
this.maxKeepAliveRequests = maxKeepAliveRequests;
}
@@ -1058,40 +1129,63 @@ public abstract class AbstractEndpoint<S,U> {
* Name of the thread pool, which will be used for naming child threads.
*/
private String name = "TP";
- public void setName(String name) { this.name = name; }
- public String getName() { return name; }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
/**
* Name of domain to use for JMX registration.
*/
private String domain;
- public void setDomain(String domain) { this.domain = domain; }
- public String getDomain() { return domain; }
+
+ public void setDomain(String domain) {
+ this.domain = domain;
+ }
+
+ public String getDomain() {
+ return domain;
+ }
/**
- * The default is true - the created threads will be
- * in daemon mode. If set to false, the control thread
- * will not be daemon - and will keep the process alive.
+ * The default is true - the created threads will be in daemon mode. If set to false, the control thread will not be
+ * daemon - and will keep the process alive.
*/
private boolean daemon = true;
- public void setDaemon(boolean b) { daemon = b; }
- public boolean getDaemon() { return daemon; }
+
+ public void setDaemon(boolean b) {
+ daemon = b;
+ }
+
+ public boolean getDaemon() {
+ return daemon;
+ }
/**
* Expose asynchronous IO capability.
*/
private boolean useAsyncIO = true;
- public void setUseAsyncIO(boolean useAsyncIO) { this.useAsyncIO = useAsyncIO; }
- public boolean getUseAsyncIO() { return useAsyncIO; }
+
+ public void setUseAsyncIO(boolean useAsyncIO) {
+ this.useAsyncIO = useAsyncIO;
+ }
+
+ public boolean getUseAsyncIO() {
+ return useAsyncIO;
+ }
/**
- * The default behavior is to identify connectors uniquely with address
- * and port. However, certain connectors are not using that and need
- * some other identifier, which then can be used as a replacement.
+ * The default behavior is to identify connectors uniquely with address and port. However, certain connectors are
+ * not using that and need some other identifier, which then can be used as a replacement.
+ *
* @return the id
*/
public String getId() {
@@ -1100,9 +1194,11 @@ public abstract class AbstractEndpoint<S,U> {
protected final List<String> negotiableProtocols = new ArrayList<>();
+
public void addNegotiatedProtocol(String negotiableProtocol) {
negotiableProtocols.add(negotiableProtocol);
}
+
public boolean hasNegotiableProtocols() {
return (!negotiableProtocols.isEmpty());
}
@@ -1112,23 +1208,26 @@ public abstract class AbstractEndpoint<S,U> {
* Handling of accepted sockets.
*/
private Handler<S> handler = null;
- public void setHandler(Handler<S> handler ) { this.handler = handler; }
- public Handler<S> getHandler() { return handler; }
+
+ public void setHandler(Handler<S> handler) {
+ this.handler = handler;
+ }
+
+ public Handler<S> getHandler() {
+ return handler;
+ }
/**
- * Attributes provide a way for configuration to be passed to subcomponents
- * without the {@link org.apache.coyote.ProtocolHandler} being aware of the
- * properties available on those subcomponents.
+ * Attributes provide a way for configuration to be passed to subcomponents without the
+ * {@link org.apache.coyote.ProtocolHandler} being aware of the properties available on those subcomponents.
*/
- protected HashMap<String, Object> attributes = new HashMap<>();
+ protected HashMap<String,Object> attributes = new HashMap<>();
/**
- * Generic property setter called when a property for which a specific
- * setter already exists within the
- * {@link org.apache.coyote.ProtocolHandler} needs to be made available to
- * subcomponents. The specific setter will call this method to populate the
- * attributes.
+ * Generic property setter called when a property for which a specific setter already exists within the
+ * {@link org.apache.coyote.ProtocolHandler} needs to be made available to subcomponents. The specific setter will
+ * call this method to populate the attributes.
*
* @param name Name of property to set
* @param value The value to set the property to
@@ -1139,11 +1238,11 @@ public abstract class AbstractEndpoint<S,U> {
}
attributes.put(name, value);
}
+
/**
* Used by subcomponents to retrieve configuration information.
*
- * @param key The name of the property for which the value should be
- * retrieved
+ * @param key The name of the property for which the value should be retrieved
*
* @return The value of the specified property
*/
@@ -1156,7 +1255,6 @@ public abstract class AbstractEndpoint<S,U> {
}
-
public boolean setProperty(String name, String value) {
setAttribute(name, value);
final String socketName = "socket.";
@@ -1164,13 +1262,14 @@ public abstract class AbstractEndpoint<S,U> {
if (name.startsWith(socketName)) {
return IntrospectionUtils.setProperty(socketProperties, name.substring(socketName.length()), value);
} else {
- return IntrospectionUtils.setProperty(this,name,value,false);
+ return IntrospectionUtils.setProperty(this, name, value, false);
}
- }catch ( Exception x ) {
+ } catch (Exception x) {
getLog().error(sm.getString("endpoint.setAttributeError", name, value), x);
return false;
}
}
+
public String getProperty(String name) {
String value = (String) getAttribute(name);
final String socketName = "socket.";
@@ -1249,7 +1348,7 @@ public abstract class AbstractEndpoint<S,U> {
if (executor != null && internalExecutor) {
this.executor = null;
if (executor instanceof ThreadPoolExecutor tpe) {
- //this is our internal one, so we need to shut it down
+ // this is our internal one, so we need to shut it down
tpe.shutdownNow();
long timeout = getExecutorTerminationTimeoutMillis();
if (timeout > 0) {
@@ -1319,11 +1418,10 @@ public abstract class AbstractEndpoint<S,U> {
Thread.sleep(1);
}
}
- } catch(Throwable t) {
+ } catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
if (getLog().isDebugEnabled()) {
- getLog().debug(sm.getString(
- "endpoint.debug.unlock.fail", String.valueOf(getPortWithOffset())), t);
+ getLog().debug(sm.getString("endpoint.debug.unlock.fail", String.valueOf(getPortWithOffset())), t);
}
}
}
@@ -1381,19 +1479,16 @@ public abstract class AbstractEndpoint<S,U> {
// ---------------------------------------------- Request processing methods
/**
- * Process the given SocketWrapper with the given status. Used to trigger
- * processing as if the Poller (for those endpoints that have one)
- * selected the socket.
+ * Process the given SocketWrapper with the given status. Used to trigger processing as if the Poller (for those
+ * endpoints that have one) selected the socket.
*
* @param socketWrapper The socket wrapper to process
* @param event The socket event to be processed
- * @param dispatch Should the processing be performed on a new
- * container thread
+ * @param dispatch Should the processing be performed on a new container thread
*
* @return if processing was triggered successfully
*/
- public boolean processSocket(SocketWrapperBase<S> socketWrapper,
- SocketEvent event, boolean dispatch) {
+ public boolean processSocket(SocketWrapperBase<S> socketWrapper, SocketEvent event, boolean dispatch) {
try {
if (socketWrapper == null) {
return false;
@@ -1414,7 +1509,7 @@ public abstract class AbstractEndpoint<S,U> {
sc.run();
}
} catch (RejectedExecutionException ree) {
- getLog().warn(sm.getString("endpoint.executor.fail", socketWrapper) , ree);
+ getLog().warn(sm.getString("endpoint.executor.fail", socketWrapper), ree);
return false;
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
@@ -1427,16 +1522,15 @@ public abstract class AbstractEndpoint<S,U> {
}
- protected abstract SocketProcessorBase<S> createSocketProcessor(
- SocketWrapperBase<S> socketWrapper, SocketEvent event);
+ protected abstract SocketProcessorBase<S> createSocketProcessor(SocketWrapperBase<S> socketWrapper,
+ SocketEvent event);
// ------------------------------------------------------- Lifecycle methods
/*
- * NOTE: There is no maintenance of state or checking for valid transitions
- * within this class other than ensuring that bind/unbind are called in the
- * right place. It is expected that the calling code will maintain state and
+ * NOTE: There is no maintenance of state or checking for valid transitions within this class other than ensuring
+ * that bind/unbind are called in the right place. It is expected that the calling code will maintain state and
* prevent invalid state transitions.
*/
@@ -1482,8 +1576,8 @@ public abstract class AbstractEndpoint<S,U> {
oname = new ObjectName(domain + ":type=ThreadPool,name=\"" + getName() + "\"");
Registry.getRegistry(null).registerComponent(this, oname, null);
- ObjectName socketPropertiesOname = new ObjectName(domain +
- ":type=SocketProperties,name=\"" + getName() + "\"");
+ ObjectName socketPropertiesOname =
+ new ObjectName(domain + ":type=SocketProperties,name=\"" + getName() + "\"");
socketProperties.setObjectName(socketPropertiesOname);
Registry.getRegistry(null).registerComponent(socketProperties, socketPropertiesOname, null);
@@ -1501,8 +1595,8 @@ public abstract class AbstractEndpoint<S,U> {
}
ObjectName sslOname;
try {
- sslOname = new ObjectName(domain + ":type=SSLHostConfig,ThreadPool=\"" +
- getName() + "\",name=" + ObjectName.quote(sslHostConfig.getHostName()));
+ sslOname = new ObjectName(domain + ":type=SSLHostConfig,ThreadPool=\"" + getName() + "\",name=" +
+ ObjectName.quote(sslHostConfig.getHostName()));
sslHostConfig.setObjectName(sslOname);
try {
Registry.getRegistry(null).registerComponent(sslHostConfig, sslOname, null);
@@ -1510,27 +1604,24 @@ public abstract class AbstractEndpoint<S,U> {
getLog().warn(sm.getString("endpoint.jmxRegistrationFailed", sslOname), e);
}
} catch (MalformedObjectNameException e) {
- getLog().warn(sm.getString("endpoint.invalidJmxNameSslHost",
- sslHostConfig.getHostName()), e);
+ getLog().warn(sm.getString("endpoint.invalidJmxNameSslHost", sslHostConfig.getHostName()), e);
}
for (SSLHostConfigCertificate sslHostConfigCert : sslHostConfig.getCertificates()) {
ObjectName sslCertOname;
try {
- sslCertOname = new ObjectName(domain +
- ":type=SSLHostConfigCertificate,ThreadPool=\"" + getName() +
- "\",Host=" + ObjectName.quote(sslHostConfig.getHostName()) +
- ",name=" + sslHostConfigCert.getType());
+ sslCertOname = new ObjectName(
+ domain + ":type=SSLHostConfigCertificate,ThreadPool=\"" + getName() + "\",Host=" +
+ ObjectName.quote(sslHostConfig.getHostName()) + ",name=" + sslHostConfigCert.getType());
sslHostConfigCert.setObjectName(sslCertOname);
try {
- Registry.getRegistry(null).registerComponent(
- sslHostConfigCert, sslCertOname, null);
+ Registry.getRegistry(null).registerComponent(sslHostConfigCert, sslCertOname, null);
} catch (Exception e) {
getLog().warn(sm.getString("endpoint.jmxRegistrationFailed", sslCertOname), e);
}
} catch (MalformedObjectNameException e) {
- getLog().warn(sm.getString("endpoint.invalidJmxNameSslHostCert",
- sslHostConfig.getHostName(), sslHostConfigCert.getType()), e);
+ getLog().warn(sm.getString("endpoint.invalidJmxNameSslHostCert", sslHostConfig.getHostName(),
+ sslHostConfigCert.getType()), e);
}
}
}
@@ -1566,8 +1657,7 @@ public abstract class AbstractEndpoint<S,U> {
/**
- * Pause the endpoint, which will stop it accepting new connections and
- * unlock the acceptor.
+ * Pause the endpoint, which will stop it accepting new connections and unlock the acceptor.
*/
public void pause() {
if (running && !paused) {
@@ -1579,8 +1669,7 @@ public abstract class AbstractEndpoint<S,U> {
}
/**
- * Resume the endpoint, which will make it start accepting new connections
- * again.
+ * Resume the endpoint, which will make it start accepting new connections again.
*/
public void resume() {
if (running) {
@@ -1617,10 +1706,10 @@ public abstract class AbstractEndpoint<S,U> {
}
protected LimitLatch initializeConnectionLatch() {
- if (maxConnections==-1) {
+ if (maxConnections == -1) {
return null;
}
- if (connectionLimitLatch==null) {
+ if (connectionLimitLatch == null) {
connectionLimitLatch = new LimitLatch(getMaxConnections());
}
return connectionLimitLatch;
@@ -1628,30 +1717,30 @@ public abstract class AbstractEndpoint<S,U> {
private void releaseConnectionLatch() {
LimitLatch latch = connectionLimitLatch;
- if (latch!=null) {
+ if (latch != null) {
latch.releaseAll();
}
connectionLimitLatch = null;
}
protected void countUpOrAwaitConnection() throws InterruptedException {
- if (maxConnections==-1) {
+ if (maxConnections == -1) {
return;
}
LimitLatch latch = connectionLimitLatch;
- if (latch!=null) {
+ if (latch != null) {
latch.countUpOrAwait();
}
}
protected long countDownConnection() {
- if (maxConnections==-1) {
+ if (maxConnections == -1) {
return -1;
}
LimitLatch latch = connectionLimitLatch;
- if (latch!=null) {
+ if (latch != null) {
long result = latch.countDown();
- if (result<0) {
+ if (result < 0) {
getLog().warn(sm.getString("endpoint.warn.incorrectConnectionCount"));
}
return result;
@@ -1662,9 +1751,8 @@ public abstract class AbstractEndpoint<S,U> {
/**
- * Close the server socket (to prevent further connections) if the server
- * socket was originally bound on {@link #start()} (rather than on
- * {@link #init()}).
+ * Close the server socket (to prevent further connections) if the server socket was originally bound on
+ * {@link #start()} (rather than on {@link #init()}).
*
* @see #getBindOnInit()
*/
@@ -1691,12 +1779,10 @@ public abstract class AbstractEndpoint<S,U> {
/**
- * Wait for the client connections to the server to close gracefully. The
- * method will return when all of the client connections have closed or the
- * method has been waiting for {@code waitTimeMillis}.
+ * Wait for the client connections to the server to close gracefully. The method will return when all of the client
+ * connections have closed or the method has been waiting for {@code waitTimeMillis}.
*
- * @param waitMillis The maximum time to wait in milliseconds for the
- * client connections to close.
+ * @param waitMillis The maximum time to wait in milliseconds for the client connections to close.
*
* @return The wait time, if any remaining when the method returned
*/
@@ -1726,10 +1812,10 @@ public abstract class AbstractEndpoint<S,U> {
protected abstract boolean setSocketOptions(U socket);
/**
- * Close the socket when the connection has to be immediately closed when
- * an error occurs while configuring the accepted socket or trying to
- * dispatch it for processing. The wrapper associated with the socket will
- * be used for the close.
+ * Close the socket when the connection has to be immediately closed when an error occurs while configuring the
+ * accepted socket or trying to dispatch it for processing. The wrapper associated with the socket will be used for
+ * the close.
+ *
* @param socket The newly accepted socket
*/
protected void closeSocket(U socket) {
@@ -1740,9 +1826,9 @@ public abstract class AbstractEndpoint<S,U> {
}
/**
- * Close the socket. This is used when the connector is not in a state
- * which allows processing the socket, or if there was an error which
- * prevented the allocation of the socket wrapper.
+ * Close the socket. This is used when the connector is not in a state which allows processing the socket, or if
+ * there was an error which prevented the allocation of the socket wrapper.
+ *
* @param socket The newly accepted socket
*/
protected abstract void destroySocket(U socket);
diff --git a/java/org/apache/tomcat/util/net/AbstractNetworkChannelEndpoint.java b/java/org/apache/tomcat/util/net/AbstractNetworkChannelEndpoint.java
index 67c0666321..06c19f4f6f 100644
--- a/java/org/apache/tomcat/util/net/AbstractNetworkChannelEndpoint.java
+++ b/java/org/apache/tomcat/util/net/AbstractNetworkChannelEndpoint.java
@@ -23,9 +23,10 @@ import java.nio.channels.Channel;
import java.nio.channels.NetworkChannel;
public abstract class AbstractNetworkChannelEndpoint<S extends Channel, U extends NetworkChannel>
- extends AbstractEndpoint<S, U> {
+ extends AbstractEndpoint<S,U> {
protected abstract NetworkChannel getServerSocket();
+
protected abstract S createChannel(SocketBufferHandler buffer);
diff --git a/java/org/apache/tomcat/util/net/Acceptor.java b/java/org/apache/tomcat/util/net/Acceptor.java
index c9552e2948..1d8e93acc0 100644
--- a/java/org/apache/tomcat/util/net/Acceptor.java
+++ b/java/org/apache/tomcat/util/net/Acceptor.java
@@ -35,9 +35,8 @@ public class Acceptor<U> implements Runnable {
private final AbstractEndpoint<?,U> endpoint;
private String threadName;
/*
- * Tracked separately rather than using endpoint.isRunning() as calls to
- * endpoint.stop() and endpoint.start() in quick succession can cause the
- * acceptor to continue running when it should terminate.
+ * Tracked separately rather than using endpoint.isRunning() as calls to endpoint.stop() and endpoint.start() in
+ * quick succession can cause the acceptor to continue running when it should terminate.
*/
private volatile boolean stopCalled = false;
private final CountDownLatch stopLatch = new CountDownLatch(1);
@@ -83,9 +82,9 @@ public class Acceptor<U> implements Runnable {
// excessive CPU usage.
// Therefore, we start with a tight loop but if there isn't a
// rapid transition to stop then sleeps are introduced.
- // < 1ms - tight loop
+ // < 1ms - tight loop
// 1ms to 10ms - 1ms sleep
- // > 10ms - 10ms sleep
+ // > 10ms - 10ms sleep
while (endpoint.isPaused() && !stopCalled) {
if (state != AcceptorState.PAUSED) {
pauseStart = System.nanoTime();
@@ -112,7 +111,7 @@ public class Acceptor<U> implements Runnable {
state = AcceptorState.RUNNING;
try {
- //if we have reached max connections, wait
+ // if we have reached max connections, wait
endpoint.countUpOrAwaitConnection();
// Endpoint might have been paused while waiting for latch
@@ -169,7 +168,7 @@ public class Acceptor<U> implements Runnable {
if (waitMilliseconds > 0) {
try {
if (!stopLatch.await(waitMilliseconds, TimeUnit.MILLISECONDS)) {
- log.warn(sm.getString("acceptor.stop.fail", getThreadName()));
+ log.warn(sm.getString("acceptor.stop.fail", getThreadName()));
}
} catch (InterruptedException e) {
log.warn(sm.getString("acceptor.stop.interrupted", getThreadName()), e);
@@ -179,13 +178,13 @@ public class Acceptor<U> implements Runnable {
/**
- * Handles exceptions where a delay is required to prevent a Thread from
- * entering a tight loop which will consume CPU and may also trigger large
- * amounts of logging. For example, this can happen if the ulimit for open
- * files is reached.
+ * Handles exceptions where a delay is required to prevent a Thread from entering a tight loop which will consume
+ * CPU and may also trigger large amounts of logging. For example, this can happen if the ulimit for open files is
+ * reached.
*
* @param currentErrorDelay The current delay being applied on failure
- * @return The delay to apply on the next failure
+ *
+ * @return The delay to apply on the next failure
*/
protected int handleExceptionWithDelay(int currentErrorDelay) {
// Don't delay on first exception
@@ -210,6 +209,9 @@ public class Acceptor<U> implements Runnable {
public enum AcceptorState {
- NEW, RUNNING, PAUSED, ENDED
+ NEW,
+ RUNNING,
+ PAUSED,
+ ENDED
}
}
diff --git a/java/org/apache/tomcat/util/net/ApplicationBufferHandler.java b/java/org/apache/tomcat/util/net/ApplicationBufferHandler.java
index 0e8873c796..e62fdaf769 100644
--- a/java/org/apache/tomcat/util/net/ApplicationBufferHandler.java
+++ b/java/org/apache/tomcat/util/net/ApplicationBufferHandler.java
@@ -19,8 +19,7 @@ package org.apache.tomcat.util.net;
import java.nio.ByteBuffer;
/**
- * Callback interface to be able to expand buffers when buffer overflow
- * exceptions happen or to replace buffers
+ * Callback interface to be able to expand buffers when buffer overflow exceptions happen or to replace buffers
*/
public interface ApplicationBufferHandler {
@@ -30,9 +29,11 @@ public interface ApplicationBufferHandler {
@Override
public void expand(int newSize) {
}
+
@Override
public void setByteBuffer(ByteBuffer buffer) {
}
+
@Override
public ByteBuffer getByteBuffer() {
return EMPTY_BUFFER;
@@ -41,6 +42,7 @@ public interface ApplicationBufferHandler {
/**
* Set the byte buffer.
+ *
* @param buffer the byte buffer
*/
void setByteBuffer(ByteBuffer buffer);
@@ -52,6 +54,7 @@ public interface ApplicationBufferHandler {
/**
* Expand the byte buffer to at least the given size. Some implementations may not implement this.
+ *
* @param size the desired size
*/
void expand(int size);
diff --git a/java/org/apache/tomcat/util/net/Constants.java b/java/org/apache/tomcat/util/net/Constants.java
index ca5c0e4a15..af6d85a0d8 100644
--- a/java/org/apache/tomcat/util/net/Constants.java
+++ b/java/org/apache/tomcat/util/net/Constants.java
@@ -19,23 +19,22 @@ package org.apache.tomcat.util.net;
public class Constants {
/**
- * Name of the system property containing
- * the tomcat instance installation path
+ * Name of the system property containing the tomcat instance installation path
*/
public static final String CATALINA_BASE_PROP = "catalina.base";
/**
* JSSE and OpenSSL protocol names
*/
- public static final String SSL_PROTO_ALL = "all";
- public static final String SSL_PROTO_TLS = "TLS";
- public static final String SSL_PROTO_TLSv1_3 = "TLSv1.3";
- public static final String SSL_PROTO_TLSv1_2 = "TLSv1.2";
- public static final String SSL_PROTO_TLSv1_1 = "TLSv1.1";
+ public static final String SSL_PROTO_ALL = "all";
+ public static final String SSL_PROTO_TLS = "TLS";
+ public static final String SSL_PROTO_TLSv1_3 = "TLSv1.3";
+ public static final String SSL_PROTO_TLSv1_2 = "TLSv1.2";
+ public static final String SSL_PROTO_TLSv1_1 = "TLSv1.1";
// Two different forms for TLS 1.0
- public static final String SSL_PROTO_TLSv1_0 = "TLSv1.0";
- public static final String SSL_PROTO_TLSv1 = "TLSv1";
- public static final String SSL_PROTO_SSLv3 = "SSLv3";
- public static final String SSL_PROTO_SSLv2 = "SSLv2";
+ public static final String SSL_PROTO_TLSv1_0 = "TLSv1.0";
+ public static final String SSL_PROTO_TLSv1 = "TLSv1";
+ public static final String SSL_PROTO_SSLv3 = "SSLv3";
+ public static final String SSL_PROTO_SSLv2 = "SSLv2";
public static final String SSL_PROTO_SSLv2Hello = "SSLv2Hello";
}
diff --git a/java/org/apache/tomcat/util/net/DispatchType.java b/java/org/apache/tomcat/util/net/DispatchType.java
index ee04a0555e..e10c249573 100644
--- a/java/org/apache/tomcat/util/net/DispatchType.java
+++ b/java/org/apache/tomcat/util/net/DispatchType.java
@@ -17,9 +17,8 @@
package org.apache.tomcat.util.net;
/**
- * This enumeration lists the different types of dispatches that request
- * processing can trigger. In this instance, dispatch means re-process this
- * request using the given socket status.
+ * This enumeration lists the different types of dispatches that request processing can trigger. In this instance,
+ * dispatch means re-process this request using the given socket status.
*/
public enum DispatchType {
diff --git a/java/org/apache/tomcat/util/net/IPv6Utils.java b/java/org/apache/tomcat/util/net/IPv6Utils.java
index 3651540749..c0da66b0c4 100644
--- a/java/org/apache/tomcat/util/net/IPv6Utils.java
+++ b/java/org/apache/tomcat/util/net/IPv6Utils.java
@@ -17,9 +17,10 @@
package org.apache.tomcat.util.net;
/**
- * <p>IPv6 utilities.
- * <p>For the moment, it only contains function to canonicalize IPv6 address
- * into RFC 5952 form.
+ * <p>
+ * IPv6 utilities.
+ * <p>
+ * For the moment, it only contains function to canonicalize IPv6 address into RFC 5952 form.
*/
public class IPv6Utils {
@@ -27,21 +28,25 @@ public class IPv6Utils {
private static final int MAX_GROUP_LENGTH = 4;
/**
- * <p>Convert IPv6 address into RFC 5952 form.
- * E.g. 2001:db8:0:1:0:0:0:1 -> 2001:db8:0:1::1</p>
- *
- * <p>Method is null safe, and if IPv4 address or host name is passed to the
- * method it is returned without any processing.</p>
- *
- * <p>Method also supports IPv4 in IPv6 (e.g. 0:0:0:0:0:ffff:192.0.2.1 ->
- * ::ffff:192.0.2.1), and zone ID (e.g. fe80:0:0:0:f0f0:c0c0:1919:1234%4
- * -> fe80::f0f0:c0c0:1919:1234%4).</p>
- *
- * <p>The behaviour of this method is undefined if an invalid IPv6 address
- * is passed in as input.</p>
+ * <p>
+ * Convert IPv6 address into RFC 5952 form. E.g. 2001:db8:0:1:0:0:0:1 -> 2001:db8:0:1::1
+ * </p>
+ * <p>
+ * Method is null safe, and if IPv4 address or host name is passed to the method it is returned without any
+ * processing.
+ * </p>
+ * <p>
+ * Method also supports IPv4 in IPv6 (e.g. 0:0:0:0:0:ffff:192.0.2.1 -> ::ffff:192.0.2.1), and zone ID (e.g.
+ * fe80:0:0:0:f0f0:c0c0:1919:1234%4 -> fe80::f0f0:c0c0:1919:1234%4).
+ * </p>
+ * <p>
+ * The behaviour of this method is undefined if an invalid IPv6 address is passed in as input.
+ * </p>
*
* @param ipv6Address String representing valid IPv6 address.
+ *
* @return String representing IPv6 in canonical form.
+ *
* @throws IllegalArgumentException if IPv6 format is unacceptable.
*/
public static String canonize(String ipv6Address) throws IllegalArgumentException {
@@ -64,16 +69,12 @@ public class IPv6Utils {
int lastColonsPos = ipv6Address.lastIndexOf("::");
if (lastColonsPos >= 0 && lastColonPos == lastColonsPos + 1) {
/*
- * IPv6 part ends with two consecutive colons,
- * last colon is part of IPv6 format.
- * e.g. ::127.0.0.1
+ * IPv6 part ends with two consecutive colons, last colon is part of IPv6 format. e.g. ::127.0.0.1
*/
ipv6AddressLength = lastColonPos + 1;
} else {
/*
- * IPv6 part ends with only one colon,
- * last colon is not part of IPv6 format.
- * e.g. ::FFFF:127.0.0.1
+ * IPv6 part ends with only one colon, last colon is not part of IPv6 format. e.g. ::FFFF:127.0.0.1
*/
ipv6AddressLength = lastColonPos;
}
@@ -84,7 +85,7 @@ public class IPv6Utils {
}
StringBuilder result = new StringBuilder();
- char [][] groups = new char[MAX_NUMBER_OF_GROUPS][MAX_GROUP_LENGTH];
+ char[][] groups = new char[MAX_NUMBER_OF_GROUPS][MAX_GROUP_LENGTH];
int groupCounter = 0;
int charInGroupCounter = 0;
@@ -100,8 +101,7 @@ public class IPv6Utils {
boolean groupStart = true;
/*
- * Two consecutive colons, initial expansion.
- * e.g. 2001:db8:0:0:1::1 -> 2001:db8:0:0:1:0:0:1
+ * Two consecutive colons, initial expansion. e.g. 2001:db8:0:0:1::1 -> 2001:db8:0:0:1:0:0:1
*/
StringBuilder expanded = new StringBuilder(ipv6Address);
@@ -183,16 +183,15 @@ public class IPv6Utils {
// Output results
for (groupCounter = 0; groupCounter < numberOfGroups; groupCounter++) {
- if (maxZeroGroupLength <= 1 || groupCounter < maxZeroGroupIndex
- || groupCounter >= maxZeroGroupIndex + maxZeroGroupLength) {
+ if (maxZeroGroupLength <= 1 || groupCounter < maxZeroGroupIndex ||
+ groupCounter >= maxZeroGroupIndex + maxZeroGroupLength) {
for (int j = 0; j < MAX_GROUP_LENGTH; j++) {
if (groups[groupCounter][j] != 0) {
result.append(groups[groupCounter][j]);
}
}
- if (groupCounter < (numberOfGroups - 1)
- && (groupCounter != maxZeroGroupIndex - 1
- || maxZeroGroupLength <= 1)) {
+ if (groupCounter < (numberOfGroups - 1) &&
+ (groupCounter != maxZeroGroupIndex - 1 || maxZeroGroupLength <= 1)) {
result.append(':');
}
} else if (groupCounter == maxZeroGroupIndex) {
@@ -203,8 +202,8 @@ public class IPv6Utils {
// Solve problem with three colons in IPv4 in IPv6 format
// e.g. 0:0:0:0:0:0:127.0.0.1 -> :::127.0.0.1 -> ::127.0.0.1
int resultLength = result.length();
- if (result.charAt(resultLength - 1) == ':' && ipv6AddressLength < ipv6Address.length()
- && ipv6Address.charAt(ipv6AddressLength) == ':') {
+ if (result.charAt(resultLength - 1) == ':' && ipv6AddressLength < ipv6Address.length() &&
+ ipv6Address.charAt(ipv6AddressLength) == ':') {
result.delete(resultLength - 1, resultLength);
}
@@ -222,6 +221,7 @@ public class IPv6Utils {
* Heuristic check if string might be an IPv6 address.
*
* @param input Any string or null
+ *
* @return true, if input string contains only hex digits and at least two colons, before '.' or '%' character
*/
static boolean mayBeIPv6Address(String input) {
@@ -237,8 +237,7 @@ public class IPv6Utils {
// IPv4 in IPv6 or Zone ID detected, end of checking.
break;
}
- if (!((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f')
- || (c >= 'A' && c <= 'F') || c == ':')) {
+ if (!((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') || c == ':')) {
return false;
} else if (c == ':') {
colonsCounter++;
diff --git a/java/org/apache/tomcat/util/net/NioChannel.java b/java/org/apache/tomcat/util/net/NioChannel.java
index cb4dc276bb..672f3a664a 100644
--- a/java/org/apache/tomcat/util/net/NioChannel.java
+++ b/java/org/apache/tomcat/util/net/NioChannel.java
@@ -28,9 +28,8 @@ import org.apache.tomcat.util.net.NioEndpoint.NioSocketWrapper;
import org.apache.tomcat.util.res.StringManager;
/**
- * Base class for a SocketChannel wrapper used by the endpoint.
- * This way, logic for an SSL socket channel remains the same as for
- * a non SSL, making sure we don't need to code for any exception cases.
+ * Base class for a SocketChannel wrapper used by the endpoint. This way, logic for an SSL socket channel remains the
+ * same as for a non SSL, making sure we don't need to code for any exception cases.
*/
public class NioChannel implements ByteChannel, ScatteringByteChannel, GatheringByteChannel {
@@ -49,8 +48,9 @@ public class NioChannel implements ByteChannel, ScatteringByteChannel, Gathering
/**
* Reset the channel
*
- * @param channel the socket channel
+ * @param channel the socket channel
* @param socketWrapper the socket wrapper
+ *
* @throws IOException If a problem was encountered resetting the channel
*/
public void reset(SocketChannel channel, NioSocketWrapper socketWrapper) throws IOException {
@@ -87,6 +87,7 @@ public class NioChannel implements ByteChannel, ScatteringByteChannel, Gathering
* Close the connection.
*
* @param force Should the underlying socket be forcibly closed?
+ *
* @throws IOException If closing the secure channel fails.
*/
public void close(boolean force) throws IOException {
@@ -109,7 +110,9 @@ public class NioChannel implements ByteChannel, ScatteringByteChannel, Gathering
* Writes a sequence of bytes to this channel from the given buffer.
*
* @param src The buffer from which bytes are to be retrieved
+ *
* @return The number of bytes written, possibly zero
+ *
* @throws IOException If some other I/O error occurs
*/
@Override
@@ -128,8 +131,7 @@ public class NioChannel implements ByteChannel, ScatteringByteChannel, Gathering
}
@Override
- public long write(ByteBuffer[] srcs, int offset, int length)
- throws IOException {
+ public long write(ByteBuffer[] srcs, int offset, int length) throws IOException {
checkInterruptStatus();
return sc.write(srcs, offset, length);
}
@@ -138,8 +140,9 @@ public class NioChannel implements ByteChannel, ScatteringByteChannel, Gathering
* Reads a sequence of bytes from this channel into the given buffer.
*
* @param dst The buffer into which bytes are to be transferred
- * @return The number of bytes read, possibly zero, or <code>-1</code> if
- * the channel has reached end-of-stream
+ *
+ * @return The number of bytes read, possibly zero, or <code>-1</code> if the channel has reached end-of-stream
+ *
* @throws IOException If some other I/O error occurs
*/
@Override
@@ -153,8 +156,7 @@ public class NioChannel implements ByteChannel, ScatteringByteChannel, Gathering
}
@Override
- public long read(ByteBuffer[] dsts, int offset, int length)
- throws IOException {
+ public long read(ByteBuffer[] dsts, int offset, int length) throws IOException {
return sc.read(dsts, offset, length);
}
@@ -175,12 +177,13 @@ public class NioChannel implements ByteChannel, ScatteringByteChannel, Gathering
}
/**
- * Performs SSL handshake hence is a no-op for the non-secure
- * implementation.
+ * Performs SSL handshake hence is a no-op for the non-secure implementation.
*
* @param read Unused in non-secure implementation
* @param write Unused in non-secure implementation
+ *
* @return Always returns zero
+ *
* @throws IOException Never for non-secure channel
*/
public int handshake(boolean read, boolean write) throws IOException {
@@ -200,6 +203,7 @@ public class NioChannel implements ByteChannel, ScatteringByteChannel, Gathering
* Return true if the buffer wrote data. NO-OP for non-secure channel.
*
* @return Always returns {@code false} for non-secure channel
+ *
* @throws IOException Never for non-secure channel
*/
public boolean flushOutbound() throws IOException {
@@ -207,13 +211,10 @@ public class NioChannel implements ByteChannel, ScatteringByteChannel, Gathering
}
/**
- * This method should be used to check the interrupt status before
- * attempting a write.
- * If a thread has been interrupted and the interrupt has not been cleared
- * then an attempt to write to the socket will fail. When this happens the
- * socket is removed from the poller without the socket being selected. This
- * results in a connection limit leak for NIO as the endpoint expects the
- * socket to be selected even in error conditions.
+ * This method should be used to check the interrupt status before attempting a write. If a thread has been
+ * interrupted and the interrupt has not been cleared then an attempt to write to the socket will fail. When this
+ * happens the socket is removed from the poller without the socket being selected. This results in a connection
+ * limit leak for NIO as the endpoint expects the socket to be selected even in error conditions.
*
* @throws IOException If the current thread was interrupted
*/
@@ -224,9 +225,11 @@ public class NioChannel implements ByteChannel, ScatteringByteChannel, Gathering
}
private ApplicationBufferHandler appReadBufHandler;
+
public void setAppReadBufHandler(ApplicationBufferHandler handler) {
this.appReadBufHandler = handler;
}
+
protected ApplicationBufferHandler getAppReadBufHandler() {
return appReadBufHandler;
}
@@ -235,42 +238,50 @@ public class NioChannel implements ByteChannel, ScatteringByteChannel, Gathering
@Override
public void close() throws IOException {
}
+
@Override
public boolean isOpen() {
return false;
}
+
@Override
public void reset(SocketChannel channel, NioSocketWrapper socketWrapper) throws IOException {
}
+
@Override
public void free() {
}
+
@Override
protected ApplicationBufferHandler getAppReadBufHandler() {
return ApplicationBufferHandler.EMPTY;
}
+
@Override
public void setAppReadBufHandler(ApplicationBufferHandler handler) {
}
+
@Override
public int read(ByteBuffer dst) throws IOException {
return -1;
}
+
@Override
- public long read(ByteBuffer[] dsts, int offset, int length)
- throws IOException {
+ public long read(ByteBuffer[] dsts, int offset, int length) throws IOException {
return -1L;
}
+
@Override
public int write(ByteBuffer src) throws IOException {
checkInterruptStatus();
throw new ClosedChannelException();
}
+
@Override
- public long write(ByteBuffer[] srcs, int offset, int length)
- throws IOException {
+ public long write(ByteBuffer[] srcs, int offset, int length) throws IOException {
throw new ClosedChannelException();
}
+
@Override
public String toString() {
return "Closed NioChannel";
diff --git a/java/org/apache/tomcat/util/net/NioEndpoint.java b/java/org/apache/tomcat/util/net/NioEndpoint.java
index fd3fdb009f..f6ef6a5b30 100644
--- a/java/org/apache/tomcat/util/net/NioEndpoint.java
+++ b/java/org/apache/tomcat/util/net/NioEndpoint.java
@@ -81,7 +81,7 @@ public class NioEndpoint extends AbstractNetworkChannelEndpoint<NioChannel,Socke
private static final Log logHandshake = LogFactory.getLog(NioEndpoint.class.getName() + ".handshake");
- public static final int OP_REGISTER = 0x100; //register interest op
+ public static final int OP_REGISTER = 0x100; // register interest op
// ----------------------------------------------------------------- Fields
@@ -115,15 +115,25 @@ public class NioEndpoint extends AbstractNetworkChannelEndpoint<NioChannel,Socke
* Use System.inheritableChannel to obtain channel from stdin/stdout.
*/
private boolean useInheritedChannel = false;
- public void setUseInheritedChannel(boolean useInheritedChannel) { this.useInheritedChannel = useInheritedChannel; }
- public boolean getUseInheritedChannel() { return useInheritedChannel; }
+
+ public void setUseInheritedChannel(boolean useInheritedChannel) {
+ this.useInheritedChannel = useInheritedChannel;
+ }
+
+ public boolean getUseInheritedChannel() {
+ return useInheritedChannel;
+ }
/**
* Path for the Unix domain socket, used to create the socket address.
*/
private String unixDomainSocketPath = null;
- public String getUnixDomainSocketPath() { return this.unixDomainSocketPath; }
+
+ public String getUnixDomainSocketPath() {
+ return this.unixDomainSocketPath;
+ }
+
public void setUnixDomainSocketPath(String unixDomainSocketPath) {
this.unixDomainSocketPath = unixDomainSocketPath;
}
@@ -133,7 +143,11 @@ public class NioEndpoint extends AbstractNetworkChannelEndpoint<NioChannel,Socke
* Permissions which will be set on the Unix domain socket if it is created.
*/
private String unixDomainSocketPathPermissions = null;
- public String getUnixDomainSocketPathPermissions() { return this.unixDomainSocketPathPermissions; }
+
+ public String getUnixDomainSocketPathPermissions() {
+ return this.unixDomainSocketPathPermissions;
+ }
+
public void setUnixDomainSocketPathPermissions(String unixDomainSocketPathPermissions) {
this.unixDomainSocketPathPermissions = unixDomainSocketPathPermissions;
}
@@ -143,13 +157,25 @@ public class NioEndpoint extends AbstractNetworkChannelEndpoint<NioChannel,Socke
* Priority of the poller thread.
*/
private int pollerThreadPriority = Thread.NORM_PRIORITY;
- public void setPollerThreadPriority(int pollerThreadPriority) { this.pollerThreadPriority = pollerThreadPriority; }
- public int getPollerThreadPriority() { return pollerThreadPriority; }
+
+ public void setPollerThreadPriority(int pollerThreadPriority) {
+ this.pollerThreadPriority = pollerThreadPriority;
+ }
+
+ public int getPollerThreadPriority() {
+ return pollerThreadPriority;
+ }
private long selectorTimeout = 1000;
- public void setSelectorTimeout(long timeout) { this.selectorTimeout = timeout;}
- public long getSelectorTimeout() { return this.selectorTimeout; }
+
+ public void setSelectorTimeout(long timeout) {
+ this.selectorTimeout = timeout;
+ }
+
+ public long getSelectorTimeout() {
+ return this.selectorTimeout;
+ }
/**
* The socket poller.
@@ -162,8 +188,8 @@ public class NioEndpoint extends AbstractNetworkChannelEndpoint<NioChannel,Socke
/**
* Number of keep-alive sockets.
*
- * @return The number of sockets currently in the keep-alive state waiting
- * for the next request to be received on the socket
+ * @return The number of sockets currently in the keep-alive state waiting for the next request to be received on
+ * the socket
*/
public int getKeepAliveCount() {
if (poller == null) {
@@ -240,7 +266,7 @@ public class NioEndpoint extends AbstractNetworkChannelEndpoint<NioChannel,Socke
InetSocketAddress addr = new InetSocketAddress(getAddress(), getPortWithOffset());
serverSock.bind(addr, getAcceptCount());
}
- serverSock.configureBlocking(true); //mimic APR behavior
+ serverSock.configureBlocking(true); // mimic APR behavior
}
@@ -255,18 +281,15 @@ public class NioEndpoint extends AbstractNetworkChannelEndpoint<NioChannel,Socke
paused = false;
if (socketProperties.getProcessorCache() != 0) {
- processorCache = new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE,
- socketProperties.getProcessorCache());
+ processorCache =
+ new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE, socketProperties.getProcessorCache());
}
if (socketProperties.getEventCache() != 0) {
- eventCache = new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE,
- socketProperties.getEventCache());
+ eventCache = new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE, socketProperties.getEventCache());
}
- int actualBufferPool =
- socketProperties.getActualBufferPool(isSSLEnabled() ? getSniParseLimit() * 2 : 0);
+ int actualBufferPool = socketProperties.getActualBufferPool(isSSLEnabled() ? getSniParseLimit() * 2 : 0);
if (actualBufferPool != 0) {
- nioChannels = new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE,
- actualBufferPool);
+ nioChannels = new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE, actualBufferPool);
}
// Create worker collection
@@ -341,8 +364,7 @@ public class NioEndpoint extends AbstractNetworkChannelEndpoint<NioChannel,Socke
@Override
public void unbind() throws Exception {
if (log.isTraceEnabled()) {
- log.trace("Destroy initiated for " +
- new InetSocketAddress(getAddress(),getPortWithOffset()));
+ log.trace("Destroy initiated for " + new InetSocketAddress(getAddress(), getPortWithOffset()));
}
if (running) {
stop();
@@ -354,12 +376,11 @@ public class NioEndpoint extends AbstractNetworkChannelEndpoint<NioChannel,Socke
}
destroySsl();
super.unbind();
- if (getHandler() != null ) {
+ if (getHandler() != null) {
getHandler().recycle();
}
if (log.isTraceEnabled()) {
- log.trace("Destroy completed for " +
- new InetSocketAddress(getAddress(), getPortWithOffset()));
+ log.trace("Destroy completed for " + new InetSocketAddress(getAddress(), getPortWithOffset()));
}
}
@@ -400,16 +421,14 @@ public class NioEndpoint extends AbstractNetworkChannelEndpoint<NioChannel,Socke
}
// Wait for up to 1000ms acceptor threads to unlock
long waitLeft = 1000;
- while (waitLeft > 0 &&
- acceptor.getState() == AcceptorState.RUNNING) {
+ while (waitLeft > 0 && acceptor.getState() == AcceptorState.RUNNING) {
Thread.sleep(5);
waitLeft -= 5;
}
- } catch(Throwable t) {
+ } catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
if (getLog().isDebugEnabled()) {
- getLog().debug(sm.getString(
- "endpoint.debug.unlock.fail", String.valueOf(getPortWithOffset())), t);
+ getLog().debug(sm.getString("endpoint.debug.unlock.fail", String.valueOf(getPortWithOffset())), t);
}
}
}
@@ -438,10 +457,11 @@ public class NioEndpoint extends AbstractNetworkChannelEndpoint<NioChannel,Socke
/**
* Process the specified connection.
+ *
* @param socket The socket channel
- * @return <code>true</code> if the socket was correctly configured
- * and processing may continue, <code>false</code> if the socket needs to be
- * close immediately
+ *
+ * @return <code>true</code> if the socket was correctly configured and processing may continue, <code>false</code>
+ * if the socket needs to be close immediately
*/
@Override
protected boolean setSocketOptions(SocketChannel socket) {
@@ -453,10 +473,8 @@ public class NioEndpoint extends AbstractNetworkChannelEndpoint<NioChannel,Socke
channel = nioChannels.pop();
}
if (channel == null) {
- SocketBufferHandler bufhandler = new SocketBufferHandler(
- socketProperties.getAppReadBufSize(),
- socketProperties.getAppWriteBufSize(),
- socketProperties.getDirectBuffer());
+ SocketBufferHandler bufhandler = new SocketBufferHandler(socketProperties.getAppReadBufSize(),
+ socketProperties.getAppWriteBufSize(), socketProperties.getDirectBuffer());
channel = createChannel(bufhandler);
}
NioSocketWrapper newWrapper = new NioSocketWrapper(channel, this);
@@ -544,8 +562,8 @@ public class NioEndpoint extends AbstractNetworkChannelEndpoint<NioChannel,Socke
@Override
- protected SocketProcessorBase<NioChannel> createSocketProcessor(
- SocketWrapperBase<NioChannel> socketWrapper, SocketEvent event) {
+ protected SocketProcessorBase<NioChannel> createSocketProcessor(SocketWrapperBase<NioChannel> socketWrapper,
+ SocketEvent event) {
return new SocketProcessor(socketWrapper, event);
}
@@ -601,8 +619,7 @@ public class NioEndpoint extends AbstractNetworkChannelEndpoint<NioChannel,Socke
public class Poller implements Runnable {
private final Selector selector;
- private final SynchronizedQueue<PollerEvent> events =
- new SynchronizedQueue<>();
+ private final SynchronizedQueue<PollerEvent> events = new SynchronizedQueue<>();
private volatile boolean close = false;
// Optimize expiration handling
@@ -616,9 +633,13 @@ public class NioEndpoint extends AbstractNetworkChannelEndpoint<NioChannel,Socke
this.selector = Selector.open();
}
- public int getKeyCount() { return keyCount; }
+ public int getKeyCount() {
+ return keyCount;
+ }
- public Selector getSelector() { return selector; }
+ public Selector getSelector() {
+ return selector;
+ }
/**
* Destroy the poller.
@@ -652,14 +673,12 @@ public class NioEndpoint extends AbstractNetworkChannelEndpoint<NioChannel,Socke
}
/**
- * Add specified socket and associated pool to the poller. The socket will
- * be added to a temporary array, and polled first after a maximum amount
- * of time equal to pollTime (in most cases, latency will be much lower,
+ * Add specified socket and associated pool to the poller. The socket will be added to a temporary array, and
+ * polled first after a maximum amount of time equal to pollTime (in most cases, latency will be much lower,
* however).
*
* @param socketWrapper to add to the poller
- * @param interestOps Operations for which to register this socket with
- * the Poller
+ * @param interestOps Operations for which to register this socket with the Poller
*/
public void add(NioSocketWrapper socketWrapper, int interestOps) {
PollerEvent pollerEvent = createPollerEvent(socketWrapper, interestOps);
@@ -672,14 +691,13 @@ public class NioEndpoint extends AbstractNetworkChannelEndpoint<NioChannel,Socke
/**
* Processes events in the event queue of the Poller.
*
- * @return <code>true</code> if some events were processed,
- * <code>false</code> if queue was empty
+ * @return <code>true</code> if some events were processed, <code>false</code> if queue was empty
*/
public boolean events() {
boolean result = false;
PollerEvent pe;
- for (int i = 0, size = events.size(); i < size && (pe = events.poll()) != null; i++ ) {
+ for (int i = 0, size = events.size(); i < size && (pe = events.poll()) != null; i++) {
result = true;
NioSocketWrapper socketWrapper = pe.getSocketWrapper();
SocketChannel sc = socketWrapper.getSocket().getIOChannel();
@@ -735,15 +753,14 @@ public class NioEndpoint extends AbstractNetworkChannelEndpoint<NioChannel,Socke
* @param socketWrapper The socket wrapper
*/
public void register(final NioSocketWrapper socketWrapper) {
- socketWrapper.interestOps(SelectionKey.OP_READ);//this is what OP_REGISTER turns into.
+ socketWrapper.interestOps(SelectionKey.OP_READ);// this is what OP_REGISTER turns into.
PollerEvent pollerEvent = createPollerEvent(socketWrapper, OP_REGISTER);
addEvent(pollerEvent);
}
/**
- * The background thread that adds sockets to the Poller, checks the
- * poller for triggered events and hands the associated socket off to an
- * appropriate processor as events occur.
+ * The background thread that adds sockets to the Poller, checks the poller for triggered events and hands the
+ * associated socket off to an appropriate processor as events occur.
*/
@Override
public void run() {
@@ -784,8 +801,7 @@ public class NioEndpoint extends AbstractNetworkChannelEndpoint<NioChannel,Socke
continue;
}
- Iterator<SelectionKey> iterator =
- keyCount > 0 ? selector.selectedKeys().iterator() : null;
+ Iterator<SelectionKey> iterator = keyCount > 0 ? selector.selectedKeys().iterator() : null;
// Walk through the collection of ready keys and dispatch
// any active event.
while (iterator != null && iterator.hasNext()) {
@@ -800,7 +816,7 @@ public class NioEndpoint extends AbstractNetworkChannelEndpoint<NioChannel,Socke
}
// Process timeouts
- timeout(keyCount,hasEvents);
+ timeout(keyCount, hasEvents);
}
getStopLatch().countDown();
@@ -906,7 +922,7 @@ public class NioEndpoint extends AbstractNetworkChannelEndpoint<NioChannel,Socke
}
}
}
- if (sd.length <= 0 && sc.getOutboundRemaining()<=0) {
+ if (sd.length <= 0 && sc.getOutboundRemaining() <= 0) {
if (log.isTraceEnabled()) {
log.trace("Send file complete for: " + sd.fileName);
}
@@ -920,29 +936,29 @@ public class NioEndpoint extends AbstractNetworkChannelEndpoint<NioChannel,Socke
// appropriate event(s) if sendfile completes.
if (!calledByProcessor) {
switch (sd.keepAliveState) {
- case NONE: {
- if (log.isTraceEnabled()) {
- log.trace("Send file connection is being closed");
- }
- socketWrapper.close();
- break;
- }
- case PIPELINED: {
- if (log.isTraceEnabled()) {
- log.trace("Connection is keep alive, processing pipe-lined data");
- }
- if (!processSocket(socketWrapper, SocketEvent.OPEN_READ, true)) {
+ case NONE: {
+ if (log.isTraceEnabled()) {
+ log.trace("Send file connection is being closed");
+ }
socketWrapper.close();
+ break;
}
- break;
- }
- case OPEN: {
- if (log.isTraceEnabled()) {
- log.trace("Connection is keep alive, registering back for OP_READ");
+ case PIPELINED: {
+ if (log.isTraceEnabled()) {
+ log.trace("Connection is keep alive, processing pipe-lined data");
+ }
+ if (!processSocket(socketWrapper, SocketEvent.OPEN_READ, true)) {
+ socketWrapper.close();
+ }
+ break;
+ }
+ case OPEN: {
+ if (log.isTraceEnabled()) {
+ log.trace("Connection is keep alive, registering back for OP_READ");
+ }
+ reg(sk, socketWrapper, SelectionKey.OP_READ);
+ break;
}
- reg(sk, socketWrapper, SelectionKey.OP_READ);
- break;
- }
}
}
return SendfileState.DONE;
@@ -1013,7 +1029,7 @@ public class NioEndpoint extends AbstractNetworkChannelEndpoint<NioChannel,Socke
socketWrapper.interestOps(0);
socketWrapper.close();
} else if (socketWrapper.interestOpsHas(SelectionKey.OP_READ) ||
- socketWrapper.interestOpsHas(SelectionKey.OP_WRITE)) {
+ socketWrapper.interestOpsHas(SelectionKey.OP_WRITE)) {
boolean readTimeout = false;
boolean writeTimeout = false;
// Check for read timeout
@@ -1062,13 +1078,11 @@ public class NioEndpoint extends AbstractNetworkChannelEndpoint<NioChannel,Socke
}
// For logging purposes only
long prevExp = nextExpiration;
- nextExpiration = System.currentTimeMillis() +
- socketProperties.getTimeoutInterval();
+ nextExpiration = System.currentTimeMillis() + socketProperties.getTimeoutInterval();
if (log.isTraceEnabled()) {
- log.trace("timeout completed: keys processed=" + keycount +
- "; now=" + now + "; nextExpiration=" + prevExp +
- "; keyCount=" + keyCount + "; hasEvents=" + hasEvents +
- "; eval=" + ((now < prevExp) && (keyCount>0 || hasEvents) && (!close) ));
+ log.trace("timeout completed: keys processed=" + keycount + "; now=" + now + "; nextExpiration=" +
+ prevExp + "; keyCount=" + keyCount + "; hasEvents=" + hasEvents + "; eval=" +
+ ((now < prevExp) && (keyCount > 0 || hasEvents) && (!close)));
}
}
@@ -1109,20 +1123,46 @@ public class NioEndpoint extends AbstractNetworkChannelEndpoint<NioChannel,Socke
writeLock = (writePending == null) ? new Object() : writePending;
}
- public Poller getPoller() { return poller; }
- public int interestOps() { return interestOps; }
- public int interestOps(int ops) { this.interestOps = ops; return ops; }
+ public Poller getPoller() {
+ return poller;
+ }
+
+ public int interestOps() {
+ return interestOps;
+ }
+
+ public int interestOps(int ops) {
+ this.interestOps = ops;
+ return ops;
+ }
+
public boolean interestOpsHas(int targetOp) {
return (this.interestOps() & targetOp) == targetOp;
}
- public void setSendfileData(SendfileData sf) { this.sendfileData = sf;}
- public SendfileData getSendfileData() { return this.sendfileData; }
+ public void setSendfileData(SendfileData sf) {
+ this.sendfileData = sf;
+ }
+
+ public SendfileData getSendfileData() {
+ return this.sendfileData;
+ }
+
+ public void updateLastWrite() {
+ lastWrite = System.currentTimeMillis();
+ }
+
+ public long getLastWrite() {
+ return lastWrite;
+ }
- public void updateLastWrite() { lastWrite = System.currentTimeMillis(); }
- public long getLastWrite() { return lastWrite; }
- public void updateLastRead() { lastRead = System.currentTimeMillis(); }
- public long getLastRead() { return lastRead; }
+ public void updateLastRead() {
+ lastRead = System.currentTimeMillis();
+ }
+
+ public long getLastRead() {
+ return lastRead;
+ }
@Override
public boolean isReadyForRead() throws IOException {
@@ -1144,11 +1184,9 @@ public class NioEndpoint extends AbstractNetworkChannelEndpoint<NioChannel,Socke
if (nRead > 0) {
return nRead;
/*
- * Since more bytes may have arrived since the buffer was last
- * filled, it is an option at this point to perform a
- * non-blocking read. However, correctly handling the case if
- * that read returns end of stream adds complexity. Therefore,
- * at the moment, the preference is for simplicity.
+ * Since more bytes may have arrived since the buffer was last filled, it is an option at this point to
+ * perform a non-blocking read. However, correctly handling the case if that read returns end of stream
+ * adds complexity. Therefore, at the moment, the preference is for simplicity.
*/
}
@@ -1173,11 +1211,9 @@ public class NioEndpoint extends AbstractNetworkChannelEndpoint<NioChannel,Socke
if (nRead > 0) {
return nRead;
/*
- * Since more bytes may have arrived since the buffer was last
- * filled, it is an option at this point to perform a
- * non-blocking read. However, correctly handling the case if
- * that read returns end of stream adds complexity. Therefore,
- * at the moment, the preference is for simplicity.
+ * Since more bytes may have arrived since the buffer was last filled, it is an option at this point to
+ * perform a non-blocking read. However, correctly handling the case if that read returns end of stream
+ * adds complexity. Therefore, at the moment, the preference is for simplicity.
*/
}
@@ -1330,13 +1366,11 @@ public class NioEndpoint extends AbstractNetworkChannelEndpoint<NioChannel,Socke
/*
* https://bz.apache.org/bugzilla/show_bug.cgi?id=66076
*
- * When using TLS an additional buffer is used for the encrypted data
- * before it is written to the network. It is possible for this network
- * output buffer to contain data while the socket write buffer is empty.
+ * When using TLS an additional buffer is used for the encrypted data before it is written to the network. It is
+ * possible for this network output buffer to contain data while the socket write buffer is empty.
*
- * For NIO with non-blocking I/O, this case is handling by ensuring that
- * flush only returns false (i.e. no data left to flush) if all buffers
- * are empty.
+ * For NIO with non-blocking I/O, this case is handling by ensuring that flush only returns false (i.e. no data
+ * left to flush) if all buffers are empty.
*/
private boolean socketOrNetworkBufferHasDataLeft() {
return !socketBufferHandler.isWriteBufferEmpty() || getSocket().getOutboundRemaining() > 0;
@@ -1354,16 +1388,13 @@ public class NioEndpoint extends AbstractNetworkChannelEndpoint<NioChannel,Socke
/*
* Socket has previously timed out.
*
- * Blocking writes assume that buffer is always fully
- * written so there is no code checking for incomplete
- * writes, retaining the unwritten data and attempting to
- * write it as part of a subsequent write call.
+ * Blocking writes assume that buffer is always fully written so there is no code checking for
+ * incomplete writes, retaining the unwritten data and attempting to write it as part of a
+ * subsequent write call.
*
- * Because of the above, when a timeout is triggered we need
- * to skip subsequent attempts to write as otherwise it will
- * appear to the client as if some data was dropped just
- * before the connection is lost. It is better if the client
- * just sees the dropped connection.
+ * Because of the above, when a timeout is triggered we need to skip subsequent attempts to write as
+ * otherwise it will appear to the client as if some data was dropped just before the connection is
+ * lost. It is better if the client just sees the dropped connection.
*/
throw new IOException(previousIOException);
}
@@ -1557,23 +1588,23 @@ public class NioEndpoint extends AbstractNetworkChannelEndpoint<NioChannel,Socke
}
@Override
- protected <A> OperationState<A> newOperationState(boolean read,
- ByteBuffer[] buffers, int offset, int length,
- BlockingMode block, long timeout, TimeUnit unit, A attachment,
- CompletionCheck check, CompletionHandler<Long, ? super A> handler,
- Semaphore semaphore, VectoredIOCompletionHandler<A> completion) {
- return new NioOperationState<>(read, buffers, offset, length, block,
- timeout, unit, attachment, check, handler, semaphore, completion);
+ protected <A> OperationState<A> newOperationState(boolean read, ByteBuffer[] buffers, int offset, int length,
+ BlockingMode block, long timeout, TimeUnit unit, A attachment, CompletionCheck check,
+ CompletionHandler<Long,? super A> handler, Semaphore semaphore,
+ VectoredIOCompletionHandler<A> completion) {
+ return new NioOperationState<>(read, buffers, offset, length, block, timeout, unit, attachment, check,
+ handler, semaphore, completion);
}
private class NioOperationState<A> extends OperationState<A> {
private volatile boolean inline = true;
- private NioOperationState(boolean read, ByteBuffer[] buffers, int offset, int length,
- BlockingMode block, long timeout, TimeUnit unit, A attachment, CompletionCheck check,
- CompletionHandler<Long, ? super A> handler, Semaphore semaphore,
+
+ private NioOperationState(boolean read, ByteBuffer[] buffers, int offset, int length, BlockingMode block,
+ long timeout, TimeUnit unit, A attachment, CompletionCheck check,
+ CompletionHandler<Long,? super A> handler, Semaphore semaphore,
VectoredIOCompletionHandler<A> completion) {
- super(read, buffers, offset, length, block,
- timeout, unit, attachment, check, handler, semaphore, completion);
+ super(read, buffers, offset, length, block, timeout, unit, attachment, check, handler, semaphore,
+ completion);
}
@Override
@@ -1681,8 +1712,7 @@ public class NioEndpoint extends AbstractNetworkChannelEndpoint<NioChannel,Socke
// ---------------------------------------------- SocketProcessor Inner Class
/**
- * This class is the equivalent of the Worker, but will simply use in an
- * external Executor thread pool.
+ * This class is the equivalent of the Worker, but will simply use in an external Executor thread pool.
*/
protected class SocketProcessor extends SocketProcessorBase<NioChannel> {
@@ -1693,12 +1723,10 @@ public class NioEndpoint extends AbstractNetworkChannelEndpoint<NioChannel,Socke
@Override
protected void doRun() {
/*
- * Do not cache and re-use the value of socketWrapper.getSocket() in
- * this method. If the socket closes the value will be updated to
- * CLOSED_NIO_CHANNEL and the previous value potentially re-used for
- * a new connection. That can result in a stale cached value which
- * in turn can result in unintentionally closing currently active
- * connections.
+ * Do not cache and re-use the value of socketWrapper.getSocket() in this method. If the socket closes the
+ * value will be updated to CLOSED_NIO_CHANNEL and the previous value potentially re-used for a new
+ * connection. That can result in a stale cached value which in turn can result in unintentionally closing
+ * currently active connections.
*/
Poller poller = NioEndpoint.this.poller;
if (poller == null) {
@@ -1719,7 +1747,8 @@ public class NioEndpoint extends AbstractNetworkChannelEndpoint<NioChannel,Socke
// if the handshake failed.
handshake = -1;
} else {
- handshake = socketWrapper.getSocket().handshake(event == SocketEvent.OPEN_READ, event == SocketEvent.OPEN_WRITE);
+ handshake = socketWrapper.getSocket().handshake(event == SocketEvent.OPEN_READ,
+ event == SocketEvent.OPEN_WRITE);
// The handshake process reads/writes from/to the
// socket. status may therefore be OPEN_WRITE once
// the handshake completes. However, the handshake
@@ -1732,8 +1761,8 @@ public class NioEndpoint extends AbstractNetworkChannelEndpoint<NioChannel,Socke
} catch (IOException x) {
handshake = -1;
if (logHandshake.isDebugEnabled()) {
- logHandshake.debug(sm.getString("endpoint.err.handshake",
- socketWrapper.getRemoteAddr(), Integer.toString(socketWrapper.getRemotePort())), x);
+ logHandshake.debug(sm.getString("endpoint.err.handshake", socketWrapper.getRemoteAddr(),
+ Integer.toString(socketWrapper.getRemotePort())), x);
}
} catch (CancelledKeyException ckx) {
handshake = -1;
@@ -1741,16 +1770,17 @@ public class NioEndpoint extends AbstractNetworkChannelEndpoint<NioChannel,Socke
if (handshake == 0) {
SocketState state;
// Process the request from this socket
- state = getHandler().process(socketWrapper, Objects.requireNonNullElse(event, SocketEvent.OPEN_READ));
+ state = getHandler().process(socketWrapper,
+ Objects.requireNonNullElse(event, SocketEvent.OPEN_READ));
if (state == SocketState.CLOSED) {
socketWrapper.close();
}
- } else if (handshake == -1 ) {
+ } else if (handshake == -1) {
getHandler().process(socketWrapper, SocketEvent.CONNECT_FAIL);
socketWrapper.close();
- } else if (handshake == SelectionKey.OP_READ){
+ } else if (handshake == SelectionKey.OP_READ) {
socketWrapper.registerReadInterest();
- } else if (handshake == SelectionKey.OP_WRITE){
+ } else if (handshake == SelectionKey.OP_WRITE) {
socketWrapper.registerWriteInterest();
}
} catch (CancelledKeyException cx) {
@@ -1763,7 +1793,7 @@ public class NioEndpoint extends AbstractNetworkChannelEndpoint<NioChannel,Socke
} finally {
socketWrapper = null;
event = null;
- //return to cache
+ // return to cache
if (running && processorCache != null) {
processorCache.push(this);
}
diff --git a/java/org/apache/tomcat/util/net/SSLContext.java b/java/org/apache/tomcat/util/net/SSLContext.java
index 0074782c02..e6c022fd03 100644
--- a/java/org/apache/tomcat/util/net/SSLContext.java
+++ b/java/org/apache/tomcat/util/net/SSLContext.java
@@ -28,14 +28,12 @@ import javax.net.ssl.SSLSessionContext;
import javax.net.ssl.TrustManager;
/**
- * This interface is needed to override the default SSLContext class
- * to allow SSL implementation pluggability without having to use JCE. With
- * regular JSSE it will do nothing but delegate to the SSLContext.
+ * This interface is needed to override the default SSLContext class to allow SSL implementation pluggability without
+ * having to use JCE. With regular JSSE it will do nothing but delegate to the SSLContext.
*/
public interface SSLContext {
- void init(KeyManager[] kms, TrustManager[] tms,
- SecureRandom sr) throws KeyManagementException;
+ void init(KeyManager[] kms, TrustManager[] tms, SecureRandom sr) throws KeyManagementException;
void destroy();
diff --git a/java/org/apache/tomcat/util/net/SSLHostConfig.java b/java/org/apache/tomcat/util/net/SSLHostConfig.java
index fce3973bdc..00b7d4f2fa 100644
--- a/java/org/apache/tomcat/util/net/SSLHostConfig.java
+++ b/java/org/apache/tomcat/util/net/SSLHostConfig.java
@@ -61,8 +61,8 @@ public class SSLHostConfig implements Serializable {
public static final String DEFAULT_TLS_CIPHERS = "HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!kRSA";
static {
- /* Default used if protocols are not configured, also used if
- * protocols="All"
+ /*
+ * Default used if protocols are not configured, also used if protocols="All"
*/
SSL_PROTO_ALL_SET.add(Constants.SSL_PROTO_SSLv2Hello);
SSL_PROTO_ALL_SET.add(Constants.SSL_PROTO_TLSv1);
@@ -174,18 +174,18 @@ public class SSLHostConfig implements Serializable {
/**
* Set property which belongs to the specified configuration type.
- * @param name the property name
+ *
+ * @param name the property name
* @param configType the configuration type
- * @return true if the property belongs to the current configuration,
- * and false otherwise
+ *
+ * @return true if the property belongs to the current configuration, and false otherwise
*/
boolean setProperty(String name, Type configType) {
if (this.configType == null) {
this.configType = configType;
} else {
if (configType != this.configType) {
- log.warn(sm.getString("sslHostConfig.mismatch",
- name, getHostName(), configType, this.configType));
+ log.warn(sm.getString("sslHostConfig.mismatch", name, getHostName(), configType, this.configType));
return false;
}
}
@@ -239,8 +239,8 @@ public class SSLHostConfig implements Serializable {
private void registerDefaultCertificate() {
if (defaultCertificate == null) {
- SSLHostConfigCertificate defaultCertificate = new SSLHostConfigCertificate(
- this, SSLHostConfigCertificate.Type.UNDEFINED);
+ SSLHostConfigCertificate defaultCertificate =
+ new SSLHostConfigCertificate(this, SSLHostConfigCertificate.Type.UNDEFINED);
addCertificate(defaultCertificate);
this.defaultCertificate = defaultCertificate;
}
@@ -257,7 +257,7 @@ public class SSLHostConfig implements Serializable {
if (certificates.size() == 1 &&
certificates.iterator().next().getType() == SSLHostConfigCertificate.Type.UNDEFINED ||
- certificate.getType() == SSLHostConfigCertificate.Type.UNDEFINED) {
+ certificate.getType() == SSLHostConfigCertificate.Type.UNDEFINED) {
// Invalid config
throw new IllegalArgumentException(sm.getString("sslHostConfig.certificate.notype"));
}
@@ -309,8 +309,7 @@ public class SSLHostConfig implements Serializable {
public void setCertificateVerification(String certificateVerification) {
try {
- this.certificateVerification =
- CertificateVerification.fromString(certificateVerification);
+ this.certificateVerification = CertificateVerification.fromString(certificateVerification);
} catch (IllegalArgumentException iae) {
// If the specified value is not recognised, default to the
// strictest possible option.
@@ -352,8 +351,8 @@ public class SSLHostConfig implements Serializable {
/**
- * Set the new cipher configuration. Note: Regardless of the format used to
- * set the configuration, it is always stored in OpenSSL format.
+ * Set the new cipher configuration. Note: Regardless of the format used to set the configuration, it is always
+ * stored in OpenSSL format.
*
* @param ciphersList The new cipher configuration in OpenSSL or JSSE format
*/
@@ -405,9 +404,8 @@ public class SSLHostConfig implements Serializable {
/**
- * Obtain the list of JSSE cipher names for the current configuration.
- * Ciphers included in the configuration but not supported by JSSE will be
- * excluded from this list.
+ * Obtain the list of JSSE cipher names for the current configuration. Ciphers included in the configuration but not
+ * supported by JSSE will be excluded from this list.
*
* @return A list of the JSSE cipher names
*/
@@ -435,8 +433,7 @@ public class SSLHostConfig implements Serializable {
/**
- * @return The host name associated with this SSL configuration - always in
- * lower case.
+ * @return The host name associated with this SSL configuration - always in lower case.
*/
public String getHostName() {
return hostName;
@@ -458,7 +455,7 @@ public class SSLHostConfig implements Serializable {
// Split using a positive lookahead to keep the separator in
// the capture so we can check which case it is.
- for (String value: input.split("(?=[-+,])")) {
+ for (String value : input.split("(?=[-+,])")) {
String trimmed = value.trim();
// Ignore token which only consists of prefix character
if (trimmed.length() > 1) {
@@ -483,8 +480,7 @@ public class SSLHostConfig implements Serializable {
trimmed = trimmed.substring(1).trim();
}
if (!protocols.isEmpty()) {
- log.warn(sm.getString("sslHostConfig.prefix_missing",
- trimmed, getHostName()));
+ log.warn(sm.getString("sslHostConfig.prefix_missing", trimmed, getHostName()));
}
if (trimmed.equalsIgnoreCase(Constants.SSL_PROTO_ALL)) {
protocols.addAll(SSL_PROTO_ALL_SET);
@@ -658,19 +654,18 @@ public class SSLHostConfig implements Serializable {
public KeyStore getTruststore() throws IOException {
KeyStore result = truststore;
if (result == null) {
- if (truststoreFile != null){
+ if (truststoreFile != null) {
try {
- result = SSLUtilBase.getStore(getTruststoreType(), getTruststoreProvider(),
- getTruststoreFile(), getTruststorePassword(), null);
+ result = SSLUtilBase.getStore(getTruststoreType(), getTruststoreProvider(), getTruststoreFile(),
+ getTruststorePassword(), null);
} catch (IOException ioe) {
Throwable cause = ioe.getCause();
if (cause instanceof UnrecoverableKeyException) {
// Log a warning we had a password issue
- log.warn(sm.getString("sslHostConfig.invalid_truststore_password"),
- cause);
+ log.warn(sm.getString("sslHostConfig.invalid_truststore_password"), cause);
// Re-try
- result = SSLUtilBase.getStore(getTruststoreType(), getTruststoreProvider(),
- getTruststoreFile(), null, null);
+ result = SSLUtilBase.getStore(getTruststoreType(), getTruststoreProvider(), getTruststoreFile(),
+ null, null);
} else {
// Something else went wrong - re-throw
throw ioe;
@@ -794,7 +789,7 @@ public class SSLHostConfig implements Serializable {
}
String newPath = path;
File f = new File(newPath);
- if ( !f.isAbsolute()) {
+ if (!f.isAbsolute()) {
newPath = System.getProperty(Constants.CATALINA_BASE_PROP) + File.separator + newPath;
f = new File(newPath);
}
@@ -826,31 +821,25 @@ public class SSLHostConfig implements Serializable {
}
public boolean isOptional() {
- return optional;
+ return optional;
}
public static CertificateVerification fromString(String value) {
- if ("true".equalsIgnoreCase(value) ||
- "yes".equalsIgnoreCase(value) ||
- "require".equalsIgnoreCase(value) ||
+ if ("true".equalsIgnoreCase(value) || "yes".equalsIgnoreCase(value) || "require".equalsIgnoreCase(value) ||
"required".equalsIgnoreCase(value)) {
return REQUIRED;
- } else if ("optional".equalsIgnoreCase(value) ||
- "want".equalsIgnoreCase(value)) {
+ } else if ("optional".equalsIgnoreCase(value) || "want".equalsIgnoreCase(value)) {
return OPTIONAL;
- } else if ("optionalNoCA".equalsIgnoreCase(value) ||
- "optional_no_ca".equalsIgnoreCase(value)) {
+ } else if ("optionalNoCA".equalsIgnoreCase(value) || "optional_no_ca".equalsIgnoreCase(value)) {
return OPTIONAL_NO_CA;
- } else if ("false".equalsIgnoreCase(value) ||
- "no".equalsIgnoreCase(value) ||
+ } else if ("false".equalsIgnoreCase(value) || "no".equalsIgnoreCase(value) ||
"none".equalsIgnoreCase(value)) {
return NONE;
} else {
// Could be a typo. Don't default to NONE since that is not
// secure. Force user to fix config. Could default to REQUIRED
// instead.
- throw new IllegalArgumentException(
- sm.getString("sslHostConfig.certificateVerificationInvalid", value));
+ throw new IllegalArgumentException(sm.getString("sslHostConfig.certificateVerificationInvalid", value));
}
}
}
diff --git a/java/org/apache/tomcat/util/net/SSLHostConfigCertificate.java b/java/org/apache/tomcat/util/net/SSLHostConfigCertificate.java
index 0fd5a672b3..f4111ed981 100644
--- a/java/org/apache/tomcat/util/net/SSLHostConfigCertificate.java
+++ b/java/org/apache/tomcat/util/net/SSLHostConfigCertificate.java
@@ -45,16 +45,15 @@ public class SSLHostConfigCertificate implements Serializable {
static final String DEFAULT_KEYSTORE_PROVIDER = System.getProperty("javax.net.ssl.keyStoreProvider");
static final String DEFAULT_KEYSTORE_TYPE = System.getProperty("javax.net.ssl.keyStoreType", "JKS");
- private static final String DEFAULT_KEYSTORE_FILE =
- System.getProperty("user.home") + File.separator + ".keystore";
+ private static final String DEFAULT_KEYSTORE_FILE = System.getProperty("user.home") + File.separator + ".keystore";
// Internal
private ObjectName oname;
/*
- * OpenSSL can handle multiple certs in a single config so the reference to the context is at the virtual host
- * level. JSSE can't so the reference is held here on the certificate. Typically, the SSLContext is generated from
- * the configuration but, particularly in embedded scenarios, it can be provided directly.
+ * OpenSSL can handle multiple certs in a single config so the reference to the context is at the virtual host
+ * level. JSSE can't so the reference is held here on the certificate. Typically, the SSLContext is generated from
+ * the configuration but, particularly in embedded scenarios, it can be provided directly.
*/
private transient volatile SSLContext sslContextProvided;
private transient volatile SSLContext sslContextGenerated;
@@ -164,8 +163,7 @@ public class SSLHostConfigCertificate implements Serializable {
// JSSE
public void setCertificateKeyAlias(String certificateKeyAlias) {
- sslHostConfig.setProperty(
- "Certificate.certificateKeyAlias", SSLHostConfig.Type.JSSE);
+ sslHostConfig.setProperty("Certificate.certificateKeyAlias", SSLHostConfig.Type.JSSE);
this.certificateKeyAlias = certificateKeyAlias;
}
@@ -176,8 +174,7 @@ public class SSLHostConfigCertificate implements Serializable {
public void setCertificateKeystoreFile(String certificateKeystoreFile) {
- sslHostConfig.setProperty(
- "Certificate.certificateKeystoreFile", SSLHostConfig.Type.JSSE);
+ sslHostConfig.setProperty("Certificate.certificateKeystoreFile", SSLHostConfig.Type.JSSE);
setStoreType("Certificate.certificateKeystoreFile", StoreType.KEYSTORE);
this.certificateKeystoreFile = certificateKeystoreFile;
}
@@ -189,8 +186,7 @@ public class SSLHostConfigCertificate implements Serializable {
public void setCertificateKeystorePassword(String certificateKeystorePassword) {
- sslHostConfig.setProperty(
- "Certificate.certificateKeystorePassword", SSLHostConfig.Type.JSSE);
+ sslHostConfig.setProperty("Certificate.certificateKeystorePassword", SSLHostConfig.Type.JSSE);
setStoreType("Certificate.certificateKeystorePassword", StoreType.KEYSTORE);
this.certificateKeystorePassword = certificateKeystorePassword;
}
@@ -202,8 +198,7 @@ public class SSLHostConfigCertificate implements Serializable {
public void setCertificateKeystorePasswordFile(String certificateKeystorePasswordFile) {
- sslHostConfig.setProperty(
- "Certificate.certificateKeystorePasswordFile", SSLHostConfig.Type.JSSE);
+ sslHostConfig.setProperty("Certificate.certificateKeystorePasswordFile", SSLHostConfig.Type.JSSE);
setStoreType("Certificate.certificateKeystorePasswordFile", StoreType.KEYSTORE);
this.certificateKeystorePasswordFile = certificateKeystorePasswordFile;
}
@@ -215,8 +210,7 @@ public class SSLHostConfigCertificate implements Serializable {
public void setCertificateKeystoreProvider(String certificateKeystoreProvider) {
- sslHostConfig.setProperty(
- "Certificate.certificateKeystoreProvider", SSLHostConfig.Type.JSSE);
+ sslHostConfig.setProperty("Certificate.certificateKeystoreProvider", SSLHostConfig.Type.JSSE);
setStoreType("Certificate.certificateKeystoreProvider", StoreType.KEYSTORE);
this.certificateKeystoreProvider = certificateKeystoreProvider;
}
@@ -228,8 +222,7 @@ public class SSLHostConfigCertificate implements Serializable {
public void setCertificateKeystoreType(String certificateKeystoreType) {
- sslHostConfig.setProperty(
- "Certificate.certificateKeystoreType", SSLHostConfig.Type.JSSE);
+ sslHostConfig.setProperty("Certificate.certificateKeystoreType", SSLHostConfig.Type.JSSE);
setStoreType("Certificate.certificateKeystoreType", StoreType.KEYSTORE);
this.certificateKeystoreType = certificateKeystoreType;
}
@@ -252,9 +245,9 @@ public class SSLHostConfigCertificate implements Serializable {
KeyStore result = certificateKeystore;
if (result == null && storeType == StoreType.KEYSTORE) {
- result = SSLUtilBase.getStore(getCertificateKeystoreType(),
- getCertificateKeystoreProvider(), getCertificateKeystoreFile(),
- getCertificateKeystorePassword(), getCertificateKeystorePasswordFile());
+ result = SSLUtilBase.getStore(getCertificateKeystoreType(), getCertificateKeystoreProvider(),
+ getCertificateKeystoreFile(), getCertificateKeystorePassword(),
+ getCertificateKeystorePasswordFile());
}
return result;
@@ -310,8 +303,8 @@ public class SSLHostConfigCertificate implements Serializable {
if (storeType == null) {
storeType = type;
} else if (storeType != type) {
- log.warn(sm.getString("sslHostConfigCertificate.mismatch",
- name, sslHostConfig.getHostName(), type, this.storeType));
+ log.warn(sm.getString("sslHostConfigCertificate.mismatch", name, sslHostConfig.getHostName(), type,
+ this.storeType));
}
}
diff --git a/java/org/apache/tomcat/util/net/SSLImplementation.java b/java/org/apache/tomcat/util/net/SSLImplementation.java
index 692523d3c2..e497c9992c 100644
--- a/java/org/apache/tomcat/util/net/SSLImplementation.java
+++ b/java/org/apache/tomcat/util/net/SSLImplementation.java
@@ -27,9 +27,8 @@ import org.apache.tomcat.util.net.jsse.JSSEImplementation;
import org.apache.tomcat.util.res.StringManager;
/**
- * Provides a factory and base implementation for the Tomcat specific mechanism
- * that allows alternative SSL/TLS implementations to be used without requiring
- * the implementation of a full JSSE provider.
+ * Provides a factory and base implementation for the Tomcat specific mechanism that allows alternative SSL/TLS
+ * implementations to be used without requiring the implementation of a full JSSE provider.
*/
public abstract class SSLImplementation {
@@ -37,19 +36,16 @@ public abstract class SSLImplementation {
private static final StringManager sm = StringManager.getManager(SSLImplementation.class);
/**
- * Obtain an instance (not a singleton) of the implementation with the given
- * class name.
+ * Obtain an instance (not a singleton) of the implementation with the given class name.
*
- * @param className The class name of the required implementation or null to
- * use the default (currently {@link JSSEImplementation}).
+ * @param className The class name of the required implementation or null to use the default (currently
+ * {@link JSSEImplementation}).
*
* @return An instance of the required implementation
*
- * @throws ClassNotFoundException If an instance of the requested class
- * cannot be created
+ * @throws ClassNotFoundException If an instance of the requested class cannot be created
*/
- public static SSLImplementation getInstance(String className)
- throws ClassNotFoundException {
+ public static SSLImplementation getInstance(String className) throws ClassNotFoundException {
if (className == null) {
return new JSSEImplementation();
}
@@ -69,12 +65,10 @@ public abstract class SSLImplementation {
/**
* Obtain an instance of SSLSupport.
*
- * @param session The SSL session
- * @param additionalAttributes Additional SSL attributes that are not
- * available from the session.
+ * @param session The SSL session
+ * @param additionalAttributes Additional SSL attributes that are not available from the session.
*
- * @return An instance of SSLSupport based on the given session and the
- * provided additional attributes
+ * @return An instance of SSLSupport based on the given session and the provided additional attributes
*/
public abstract SSLSupport getSSLSupport(SSLSession session, Map<String,List<String>> additionalAttributes);
diff --git a/java/org/apache/tomcat/util/net/SSLSessionManager.java b/java/org/apache/tomcat/util/net/SSLSessionManager.java
index 17e1dd94f2..9a48eb963b 100644
--- a/java/org/apache/tomcat/util/net/SSLSessionManager.java
+++ b/java/org/apache/tomcat/util/net/SSLSessionManager.java
@@ -17,8 +17,7 @@
package org.apache.tomcat.util.net;
/**
- * Defines an interface used to manage SSL sessions. The manager operates on a
- * single session.
+ * Defines an interface used to manage SSL sessions. The manager operates on a single session.
*/
public interface SSLSessionManager {
/**
diff --git a/java/org/apache/tomcat/util/net/SSLSupport.java b/java/org/apache/tomcat/util/net/SSLSupport.java
index fae379e944..d99c2b82cd 100644
--- a/java/org/apache/tomcat/util/net/SSLSupport.java
+++ b/java/org/apache/tomcat/util/net/SSLSupport.java
@@ -26,15 +26,13 @@ public interface SSLSupport {
/**
* The Request attribute key for the cipher suite.
*/
- String SECURE_PROTOCOL_KEY =
- "jakarta.servlet.request.secure_protocol";
+ String SECURE_PROTOCOL_KEY = "jakarta.servlet.request.secure_protocol";
/**
* The Request attribute key for the cipher suite.
*/
- String CIPHER_SUITE_KEY =
- "jakarta.servlet.request.cipher_suite";
+ String CIPHER_SUITE_KEY = "jakarta.servlet.request.cipher_suite";
/**
* The Request attribute key for the key size.
@@ -44,42 +42,32 @@ public interface SSLSupport {
/**
* The Request attribute key for the client certificate chain.
*/
- String CERTIFICATE_KEY =
- "jakarta.servlet.request.X509Certificate";
+ String CERTIFICATE_KEY = "jakarta.servlet.request.X509Certificate";
/**
- * The Request attribute key for the session id.
- * This one is a Tomcat extension to the Servlet spec.
+ * The Request attribute key for the session id. This one is a Tomcat extension to the Servlet spec.
*/
- String SESSION_ID_KEY =
- "jakarta.servlet.request.ssl_session_id";
+ String SESSION_ID_KEY = "jakarta.servlet.request.ssl_session_id";
/**
- * The request attribute key for the session manager.
- * This one is a Tomcat extension to the Servlet spec.
+ * The request attribute key for the session manager. This one is a Tomcat extension to the Servlet spec.
*/
- String SESSION_MGR =
- "jakarta.servlet.request.ssl_session_mgr";
+ String SESSION_MGR = "jakarta.servlet.request.ssl_session_mgr";
/**
- * The request attribute key under which the String indicating the ciphers
- * requested by the client are recorded.
+ * The request attribute key under which the String indicating the ciphers requested by the client are recorded.
*/
- String REQUESTED_CIPHERS_KEY =
- "org.apache.tomcat.util.net.secure_requested_ciphers";
+ String REQUESTED_CIPHERS_KEY = "org.apache.tomcat.util.net.secure_requested_ciphers";
/**
- * The request attribute key under which the String indicating the protocols
- * requested by the client are recorded.
+ * The request attribute key under which the String indicating the protocols requested by the client are recorded.
*/
- String REQUESTED_PROTOCOL_VERSIONS_KEY =
- "org.apache.tomcat.util.net.secure_requested_protocol_versions";
+ String REQUESTED_PROTOCOL_VERSIONS_KEY = "org.apache.tomcat.util.net.secure_requested_protocol_versions";
/**
* The cipher suite being used on this connection.
*
- * @return The name of the cipher suite as returned by the SSL/TLS
- * implementation
+ * @return The name of the cipher suite as returned by the SSL/TLS implementation
*
* @throws IOException If an error occurs trying to obtain the cipher suite
*/
@@ -88,36 +76,28 @@ public interface SSLSupport {
/**
* The client certificate chain (if any).
*
- * @return The certificate chain presented by the client with the peer's
- * certificate first, followed by those of any certificate
- * authorities
+ * @return The certificate chain presented by the client with the peer's certificate first, followed by those of any
+ * certificate authorities
*
- * @throws IOException If an error occurs trying to obtain the certificate
- * chain
+ * @throws IOException If an error occurs trying to obtain the certificate chain
*/
X509Certificate[] getPeerCertificateChain() throws IOException;
/**
* The server certificate chain (if any) that were sent to the peer.
*
- * @return The certificate chain sent with the server
- * certificate first, followed by those of any certificate
- * authorities
+ * @return The certificate chain sent with the server certificate first, followed by those of any certificate
+ * authorities
*/
default X509Certificate[] getLocalCertificateChain() {
return null;
}
/**
- * Get the key size.
- * What we're supposed to put here is ill-defined by the
- * Servlet spec (S 4.7 again). There are at least 4 potential
- * values that might go here:
- * (a) The size of the encryption key
- * (b) The size of the MAC key
- * (c) The size of the key-exchange key
- * (d) The size of the signature key used by the server
- * Unfortunately, all of these values are nonsensical.
+ * Get the key size. What we're supposed to put here is ill-defined by the Servlet spec (S 4.7 again). There are at
+ * least 4 potential values that might go here: (a) The size of the encryption key (b) The size of the MAC key (c)
+ * The size of the key-exchange key (d) The size of the signature key used by the server Unfortunately, all of these
+ * values are nonsensical.
*
* @return The effective key size for the current cipher suite
*
@@ -135,27 +115,23 @@ public interface SSLSupport {
String getSessionId() throws IOException;
/**
- * @return the protocol String indicating how the SSL socket was created
- * e.g. TLSv1 or TLSv1.2 etc.
+ * @return the protocol String indicating how the SSL socket was created e.g. TLSv1 or TLSv1.2 etc.
*
- * @throws IOException If an error occurs trying to obtain the protocol
- * information from the socket
+ * @throws IOException If an error occurs trying to obtain the protocol information from the socket
*/
String getProtocol() throws IOException;
/**
* @return the list of SSL/TLS protocol versions requested by the client
*
- * @throws IOException If an error occurs trying to obtain the client
- * requested protocol information from the socket
+ * @throws IOException If an error occurs trying to obtain the client requested protocol information from the socket
*/
String getRequestedProtocols() throws IOException;
/**
- * @return the list of SSL/TLS ciphers requested by the client
- *
- * @throws IOException If an error occurs trying to obtain the client
- * request cipher information from the socket
- */
- String getRequestedCiphers() throws IOException;
+ * @return the list of SSL/TLS ciphers requested by the client
+ *
+ * @throws IOException If an error occurs trying to obtain the client request cipher information from the socket
+ */
+ String getRequestedCiphers() throws IOException;
}
diff --git a/java/org/apache/tomcat/util/net/SSLUtil.java b/java/org/apache/tomcat/util/net/SSLUtil.java
index d85655e3c9..da89dddb20 100644
--- a/java/org/apache/tomcat/util/net/SSLUtil.java
+++ b/java/org/apache/tomcat/util/net/SSLUtil.java
@@ -25,9 +25,8 @@ import javax.net.ssl.X509KeyManager;
import javax.net.ssl.X509TrustManager;
/**
- * Provides a common interface for {@link SSLImplementation}s to create the
- * necessary JSSE implementation objects for TLS connections created via the
- * JSSE API.
+ * Provides a common interface for {@link SSLImplementation}s to create the necessary JSSE implementation objects for
+ * TLS connections created via the JSSE API.
*/
public interface SSLUtil {
@@ -56,43 +55,37 @@ public interface SSLUtil {
void configureSessionContext(SSLSessionContext sslSessionContext);
/**
- * The set of enabled protocols is the intersection of the implemented
- * protocols and the configured protocols. If no protocols are explicitly
- * configured, then all of the implemented protocols will be included in the
- * returned array.
+ * The set of enabled protocols is the intersection of the implemented protocols and the configured protocols. If no
+ * protocols are explicitly configured, then all of the implemented protocols will be included in the returned
+ * array.
*
- * @return The protocols currently enabled and available for clients to
- * select from for the associated connection
+ * @return The protocols currently enabled and available for clients to select from for the associated connection
*
- * @throws IllegalArgumentException If there is no intersection between the
- * implemented and configured protocols
+ * @throws IllegalArgumentException If there is no intersection between the implemented and configured protocols
*/
String[] getEnabledProtocols() throws IllegalArgumentException;
/**
- * The set of enabled ciphers is the intersection of the implemented ciphers
- * and the configured ciphers. If no ciphers are explicitly configured, then
- * the default ciphers will be included in the returned array.
+ * The set of enabled ciphers is the intersection of the implemented ciphers and the configured ciphers. If no
+ * ciphers are explicitly configured, then the default ciphers will be included in the returned array.
* <p>
- * The ciphers used during the TLS handshake may be further restricted by
- * the {@link #getEnabledProtocols()} and the certificates.
+ * The ciphers used during the TLS handshake may be further restricted by the {@link #getEnabledProtocols()} and the
+ * certificates.
*
- * @return The ciphers currently enabled and available for clients to select
- * from for the associated connection
+ * @return The ciphers currently enabled and available for clients to select from for the associated connection
*
- * @throws IllegalArgumentException If there is no intersection between the
- * implemented and configured ciphers
+ * @throws IllegalArgumentException If there is no intersection between the implemented and configured ciphers
*/
String[] getEnabledCiphers() throws IllegalArgumentException;
/**
- * Optional interface that can be implemented by
- * {@link javax.net.ssl.SSLEngine}s to indicate that they support ALPN and
- * can provide the protocol agreed with the client.
+ * Optional interface that can be implemented by {@link javax.net.ssl.SSLEngine}s to indicate that they support ALPN
+ * and can provide the protocol agreed with the client.
*/
interface ProtocolInfo {
/**
* ALPN information.
+ *
* @return the protocol selected using ALPN
*/
String getNegotiatedProtocol();
diff --git a/java/org/apache/tomcat/util/net/SSLUtilBase.java b/java/org/apache/tomcat/util/net/SSLUtilBase.java
index c7e9359752..484d0c7c29 100644
--- a/java/org/apache/tomcat/util/net/SSLUtilBase.java
+++ b/java/org/apache/tomcat/util/net/SSLUtilBase.java
@@ -116,8 +116,7 @@ public abstract class SSLUtilBase implements SSLUtil {
this.enabledProtocols = enabledProtocols.toArray(new String[0]);
if (enabledProtocols.contains(Constants.SSL_PROTO_TLSv1_3) &&
- sslHostConfig.getCertificateVerification().isOptional() &&
- !isTls13RenegAuthAvailable() && warnTls13) {
+ sslHostConfig.getCertificateVerification().isOptional() && !isTls13RenegAuthAvailable() && warnTls13) {
log.warn(sm.getString("sslUtilBase.tls13.auth"));
}
@@ -159,8 +158,7 @@ public abstract class SSLUtilBase implements SSLUtil {
// Don't use the defaults in this case. They may be less secure
// than the configuration the user intended.
// Force the failure of the connector
- throw new IllegalArgumentException(
- sm.getString("sslUtilBase.noneSupported", name, configured));
+ throw new IllegalArgumentException(sm.getString("sslUtilBase.noneSupported", name, configured));
}
if (log.isDebugEnabled()) {
log.debug(sm.getString("sslUtilBase.active", name, enabled));
@@ -186,8 +184,8 @@ public abstract class SSLUtilBase implements SSLUtil {
/*
* Gets the key- or truststore with the specified type, path, password and password file.
*/
- static KeyStore getStore(String type, String provider, String path,
- String pass, String passFile) throws IOException {
+ static KeyStore getStore(String type, String provider, String path, String pass, String passFile)
+ throws IOException {
KeyStore ks;
InputStream istream = null;
@@ -203,9 +201,7 @@ public abstract class SSLUtilBase implements SSLUtil {
} else {
// Some key store types (e.g. hardware) expect the InputStream
// to be null
- if(!("PKCS11".equalsIgnoreCase(type) ||
- path.isEmpty() ||
- "NONE".equalsIgnoreCase(path))) {
+ if (!("PKCS11".equalsIgnoreCase(type) || path.isEmpty() || "NONE".equalsIgnoreCase(path))) {
istream = ConfigFileLoader.getSource().getResource(path).getInputStream();
}
@@ -218,22 +214,21 @@ public abstract class SSLUtilBase implements SSLUtil {
// Therefore:
// - generally use null if pass is null or ""
// - for JKS or PKCS12 only use null if pass is null
- // (because JKS will auto-switch to PKCS12)
+ // (because JKS will auto-switch to PKCS12)
char[] storePass = null;
String passToUse;
if (passFile != null) {
- try (BufferedReader reader =
- new BufferedReader(new InputStreamReader(
- ConfigFileLoader.getSource().getResource(passFile).getInputStream(),
- StandardCharsets.UTF_8))) {
+ try (BufferedReader reader = new BufferedReader(
+ new InputStreamReader(ConfigFileLoader.getSource().getResource(passFile).getInputStream(),
+ StandardCharsets.UTF_8))) {
passToUse = reader.readLine();
}
} else {
passToUse = pass;
}
- if (passToUse != null && (!passToUse.isEmpty() ||
- "JKS".equalsIgnoreCase(type) || "PKCS12".equalsIgnoreCase(type))) {
+ if (passToUse != null &&
+ (!passToUse.isEmpty() || "JKS".equalsIgnoreCase(type) || "PKCS12".equalsIgnoreCase(type))) {
storePass = passToUse.toCharArray();
}
ks.load(istream, storePass);
@@ -242,9 +237,8 @@ public abstract class SSLUtilBase implements SSLUtil {
// May be expected when working with a trust store
// Re-throw. Caller will catch and log as required
throw ioe;
- } catch(Exception ex) {
- String msg = sm.getString("sslUtilBase.keystore_load_failed", type, path,
- ex.getMessage());
+ } catch (Exception ex) {
+ String msg = sm.getString("sslUtilBase.keystore_load_failed", type, path, ex.getMessage());
log.error(msg, ex);
throw new IOException(msg);
} finally {
@@ -308,23 +302,17 @@ public abstract class SSLUtilBase implements SSLUtil {
KeyStore ksUsed = ks;
/*
- * Use an in memory key store where possible.
- * For PEM format keys and certificates, it allows them to be imported
- * into the expected format.
- * For Java key stores with PKCS8 encoded keys (e.g. JKS files), it
- * enables Tomcat to handle the case where multiple keys exist in the
- * key store, each with a different password. The KeyManagerFactory
- * can't handle that so using an in memory key store with just the
- * required key works around that.
- * Other keys stores (hardware, MS, etc.) will be used as is.
+ * Use an in memory key store where possible. For PEM format keys and certificates, it allows them to be
+ * imported into the expected format. For Java key stores with PKCS8 encoded keys (e.g. JKS files), it enables
+ * Tomcat to handle the case where multiple keys exist in the key store, each with a different password. The
+ * KeyManagerFactory can't handle that so using an in memory key store with just the required key works around
+ * that. Other keys stores (hardware, MS, etc.) will be used as is.
*/
char[] keyPassArray = new char[0];
String keyPassToUse;
if (keyPassFile != null) {
- try (BufferedReader reader =
- new BufferedReader(new InputStreamReader(
- ConfigFileLoader.getSource().getResource(keyPassFile).getInputStream(),
- StandardCharsets.UTF_8))) {
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(
+ ConfigFileLoader.getSource().getResource(keyPassFile).getInputStream(), StandardCharsets.UTF_8))) {
keyPassToUse = reader.readLine();
}
} else {
@@ -350,9 +338,9 @@ public abstract class SSLUtilBase implements SSLUtil {
throw new IOException(sm.getString("sslUtilBase.noCertFile"));
}
- PEMFile privateKeyFile = new PEMFile(
- certificate.getCertificateKeyFile() != null ? certificate.getCertificateKeyFile() : certificate.getCertificateFile(),
- keyPass, keyPassFile, null);
+ PEMFile privateKeyFile =
+ new PEMFile(certificate.getCertificateKeyFile() != null ? certificate.getCertificateKeyFile() :
+ certificate.getCertificateFile(), keyPass, keyPassFile, null);
PEMFile certificateFile = new PEMFile(certificate.getCertificateFile());
Collection<Certificate> chain = new ArrayList<>(certificateFile.getCertificates());
@@ -367,7 +355,7 @@ public abstract class SSLUtilBase implements SSLUtil {
// Switch to in-memory key store
ksUsed = KeyStore.getInstance("JKS");
- ksUsed.load(null, null);
+ ksUsed.load(null, null);
ksUsed.setKeyEntry(keyAlias, privateKeyFile.getPrivateKey(), keyPassArray,
chain.toArray(new Certificate[0]));
} else {
@@ -397,10 +385,9 @@ public abstract class SSLUtilBase implements SSLUtil {
if (provider == null) {
ksUsed = KeyStore.getInstance(certificate.getCertificateKeystoreType());
} else {
- ksUsed = KeyStore.getInstance(certificate.getCertificateKeystoreType(),
- provider);
+ ksUsed = KeyStore.getInstance(certificate.getCertificateKeystoreType(), provider);
}
- ksUsed.load(null, null);
+ ksUsed.load(null, null);
ksUsed.setKeyEntry(keyAlias, k, keyPassArray, ks.getCertificateChain(keyAlias));
}
// Non-PKCS#8 key stores will use the original key store
@@ -420,8 +407,8 @@ public abstract class SSLUtilBase implements SSLUtil {
if ("JKS".equals(certificate.getCertificateKeystoreType())) {
alias = alias.toLowerCase(Locale.ENGLISH);
}
- for(int i = 0; i < kms.length; i++) {
- kms[i] = new JSSEKeyManager((X509KeyManager)kms[i], alias);
+ for (int i = 0; i < kms.length; i++) {
+ kms[i] = new JSSEKeyManager((X509KeyManager) kms[i], alias);
}
}
@@ -445,16 +432,15 @@ public abstract class SSLUtilBase implements SSLUtil {
public TrustManager[] getTrustManagers() throws Exception {
String className = sslHostConfig.getTrustManagerClassName();
- if(className != null && !className.isEmpty()) {
- ClassLoader classLoader = getClass().getClassLoader();
- Class<?> clazz = classLoader.loadClass(className);
- if(!(TrustManager.class.isAssignableFrom(clazz))){
- throw new InstantiationException(sm.getString(
- "sslUtilBase.invalidTrustManagerClassName", className));
- }
- Object trustManagerObject = clazz.getConstructor().newInstance();
- TrustManager trustManager = (TrustManager) trustManagerObject;
- return new TrustManager[]{ trustManager };
+ if (className != null && !className.isEmpty()) {
+ ClassLoader classLoader = getClass().getClassLoader();
+ Class<?> clazz = classLoader.loadClass(className);
+ if (!(TrustManager.class.isAssignableFrom(clazz))) {
+ throw new InstantiationException(sm.getString("sslUtilBase.invalidTrustManagerClassName", className));
+ }
+ Object trustManagerObject = clazz.getConstructor().newInstance();
+ TrustManager trustManager = (TrustManager) trustManagerObject;
+ return new TrustManager[] { trustManager };
}
TrustManager[] tms = null;
@@ -521,23 +507,23 @@ public abstract class SSLUtilBase implements SSLUtil {
/**
- * Return the initialization parameters for the TrustManager.
- * Currently, only the default <code>PKIX</code> is supported.
+ * Return the initialization parameters for the TrustManager. Currently, only the default <code>PKIX</code> is
+ * supported.
+ *
+ * @param crlf The path to the CRL file.
+ * @param trustStore The configured TrustStore.
+ * @param revocationEnabled Should the JSSE provider perform revocation checks? Ignored if {@code crlf} is non-null.
+ * Configuration of revocation checks are expected to be via proprietary JSSE provider
+ * methods.
*
- * @param crlf The path to the CRL file.
- * @param trustStore The configured TrustStore.
- * @param revocationEnabled Should the JSSE provider perform revocation
- * checks? Ignored if {@code crlf} is non-null.
- * Configuration of revocation checks are expected
- * to be via proprietary JSSE provider methods.
* @return The parameters including the CRLs and TrustStore.
+ *
* @throws Exception An error occurred
*/
- protected CertPathParameters getParameters(String crlf, KeyStore trustStore,
- boolean revocationEnabled) throws Exception {
+ protected CertPathParameters getParameters(String crlf, KeyStore trustStore, boolean revocationEnabled)
+ throws Exception {
- PKIXBuilderParameters xparams =
- new PKIXBuilderParameters(trustStore, new X509CertSelector());
+ PKIXBuilderParameters xparams = new PKIXBuilderParameters(trustStore, new X509CertSelector());
if (crlf != null && !crlf.isEmpty()) {
Collection<? extends CRL> crls = getCRLs(crlf);
CertStoreParameters csp = new CollectionCertStoreParameters(crls);
@@ -554,14 +540,16 @@ public abstract class SSLUtilBase implements SSLUtil {
/**
* Load the collection of CRLs.
+ *
* @param crlf The path to the CRL file.
+ *
* @return the CRLs collection
- * @throws IOException Error reading CRL file
- * @throws CRLException CRL error
+ *
+ * @throws IOException Error reading CRL file
+ * @throws CRLException CRL error
* @throws CertificateException Error processing certificate
*/
- protected Collection<? extends CRL> getCRLs(String crlf)
- throws IOException, CRLException, CertificateException {
+ protected Collection<? extends CRL> getCRLs(String crlf) throws IOException, CRLException, CertificateException {
Collection<? extends CRL> crls;
CertificateFactory cf = CertificateFactory.getInstance("X.509");
@@ -573,8 +561,12 @@ public abstract class SSLUtilBase implements SSLUtil {
protected abstract Set<String> getImplementedProtocols();
+
protected abstract Set<String> getImplementedCiphers();
+
protected abstract Log getLog();
+
protected abstract boolean isTls13RenegAuthAvailable();
+
protected abstract SSLContext createSSLContextInternal(List<String> negotiableProtocols) throws Exception;
}
diff --git a/java/org/apache/tomcat/util/net/SecureNioChannel.java b/java/org/apache/tomcat/util/net/SecureNioChannel.java
index 981dda8cb0..7fafff3dcd 100644
--- a/java/org/apache/tomcat/util/net/SecureNioChannel.java
+++ b/java/org/apache/tomcat/util/net/SecureNioChannel.java
@@ -66,7 +66,7 @@ public class SecureNioChannel extends NioChannel {
protected boolean handshakeComplete = false;
protected boolean needHandshakeWrap = false;
- protected HandshakeStatus handshakeStatus; //gets set by handshake
+ protected HandshakeStatus handshakeStatus; // gets set by handshake
protected boolean closed = false;
protected boolean closing = false;
@@ -108,14 +108,17 @@ public class SecureNioChannel extends NioChannel {
}
}
-//===========================================================================================
-// NIO SSL METHODS
-//===========================================================================================
+ // ===========================================================================================
+ // NIO SSL METHODS
+ // ===========================================================================================
/**
* Flushes the buffer to the network, non-blocking
+ *
* @param buf ByteBuffer
+ *
* @return boolean true if the buffer has been emptied out, false otherwise
+ *
* @throws IOException An IO error occurred writing data
*/
protected boolean flush(ByteBuffer buf) throws IOException {
@@ -128,26 +131,23 @@ public class SecureNioChannel extends NioChannel {
}
/**
- * Performs SSL handshake, non-blocking, but performs NEED_TASK on the same
- * thread. Hence, you should never call this method using your Acceptor
- * thread, as you would slow down your system significantly. If the return
- * value from this method is positive, the selection key should be
- * registered interestOps given by the return value.
+ * Performs SSL handshake, non-blocking, but performs NEED_TASK on the same thread. Hence, you should never call
+ * this method using your Acceptor thread, as you would slow down your system significantly. If the return value
+ * from this method is positive, the selection key should be registered interestOps given by the return value.
*
- * @param read boolean - true if the underlying channel is readable
+ * @param read boolean - true if the underlying channel is readable
* @param write boolean - true if the underlying channel is writable
*
- * @return 0 if handshake is complete, -1 if an error (other than an
- * IOException) occurred, otherwise it returns a SelectionKey
- * interestOps value
+ * @return 0 if handshake is complete, -1 if an error (other than an IOException) occurred, otherwise it returns a
+ * SelectionKey interestOps value
*
- * @throws IOException If an I/O error occurs during the handshake or if the
- * handshake fails during wrapping or unwrapping
+ * @throws IOException If an I/O error occurs during the handshake or if the handshake fails during wrapping or
+ * unwrapping
*/
@Override
public int handshake(boolean read, boolean write) throws IOException {
if (handshakeComplete) {
- return 0; //we have done our initial handshake
+ return 0; // we have done our initial handshake
}
if (!sniComplete) {
@@ -160,7 +160,7 @@ public class SecureNioChannel extends NioChannel {
}
if (!flush(netOutBuffer)) {
- return SelectionKey.OP_WRITE; //we still have data to write
+ return SelectionKey.OP_WRITE; // we still have data to write
}
SSLEngineResult handshake;
@@ -168,23 +168,23 @@ public class SecureNioChannel extends NioChannel {
while (!handshakeComplete) {
switch (handshakeStatus) {
case NOT_HANDSHAKING:
- //should never happen
+ // should never happen
throw new IOException(sm.getString("channel.nio.ssl.notHandshaking"));
case FINISHED:
if (endpoint.hasNegotiableProtocols()) {
if (sslEngine instanceof SSLUtil.ProtocolInfo) {
- socketWrapper.setNegotiatedProtocol(
- ((SSLUtil.ProtocolInfo) sslEngine).getNegotiatedProtocol());
+ socketWrapper
+ .setNegotiatedProtocol(((SSLUtil.ProtocolInfo) sslEngine).getNegotiatedProtocol());
} else {
socketWrapper.setNegotiatedProtocol(sslEngine.getApplicationProtocol());
}
}
- //we are complete if we have delivered the last package
+ // we are complete if we have delivered the last package
handshakeComplete = !netOutBuffer.hasRemaining();
- //return 0 if we are complete, otherwise we still have data to write
+ // return 0 if we are complete, otherwise we still have data to write
return handshakeComplete ? 0 : SelectionKey.OP_WRITE;
case NEED_WRAP:
- //perform the wrap function
+ // perform the wrap function
try {
handshake = handshakeWrap(write);
} catch (SSLException e) {
@@ -199,28 +199,30 @@ public class SecureNioChannel extends NioChannel {
flush(netOutBuffer);
return -1;
} else {
- //wrap should always work with our buffers
- throw new IOException(sm.getString("channel.nio.ssl.unexpectedStatusDuringWrap", handshake.getStatus()));
+ // wrap should always work with our buffers
+ throw new IOException(
+ sm.getString("channel.nio.ssl.unexpectedStatusDuringWrap", handshake.getStatus()));
}
if (handshakeStatus != HandshakeStatus.NEED_UNWRAP || (!flush(netOutBuffer))) {
- //should actually return OP_READ if we have NEED_UNWRAP
+ // should actually return OP_READ if we have NEED_UNWRAP
return SelectionKey.OP_WRITE;
}
- //fall down to NEED_UNWRAP on the same call, will result in a
- //BUFFER_UNDERFLOW if it needs data
- //$FALL-THROUGH$
+ // fall down to NEED_UNWRAP on the same call, will result in a
+ // BUFFER_UNDERFLOW if it needs data
+ //$FALL-THROUGH$
case NEED_UNWRAP:
- //perform the unwrap function
+ // perform the unwrap function
handshake = handshakeUnwrap(read);
if (handshake.getStatus() == Status.OK) {
if (handshakeStatus == HandshakeStatus.NEED_TASK) {
handshakeStatus = tasks();
}
- } else if ( handshake.getStatus() == Status.BUFFER_UNDERFLOW ){
- //read more data, register again for OP_READ
+ } else if (handshake.getStatus() == Status.BUFFER_UNDERFLOW) {
+ // read more data, register again for OP_READ
return SelectionKey.OP_READ;
} else {
- throw new IOException(sm.getString("channel.nio.ssl.unexpectedStatusDuringWrap", handshake.getStatus()));
+ throw new IOException(
+ sm.getString("channel.nio.ssl.unexpectedStatusDuringWrap", handshake.getStatus()));
}
break;
case NEED_TASK:
@@ -236,13 +238,11 @@ public class SecureNioChannel extends NioChannel {
/*
- * Peeks at the initial network bytes to determine if the SNI extension is
- * present and, if it is, what host name has been requested. Based on the
- * provided host name, configure the SSLEngine for this connection.
+ * Peeks at the initial network bytes to determine if the SNI extension is present and, if it is, what host name has
+ * been requested. Based on the provided host name, configure the SSLEngine for this connection.
*
- * @return 0 if SNI processing is complete, -1 if an error (other than an
- * IOException) occurred, otherwise it returns a SelectionKey
- * interestOps value
+ * @return 0 if SNI processing is complete, -1 if an error (other than an IOException) occurred, otherwise it
+ * returns a SelectionKey interestOps value
*
* @throws IOException If an I/O error occurs during the SNI processing
*/
@@ -260,8 +260,7 @@ public class SecureNioChannel extends NioChannel {
// extractor needed more data to process but netInBuffer was full so
// expand the buffer and read some more data.
int newLimit = Math.min(netInBuffer.capacity() * 2, endpoint.getSniParseLimit());
- log.info(sm.getString("channel.nio.ssl.expandNetInBuffer",
- Integer.toString(newLimit)));
+ log.info(sm.getString("channel.nio.ssl.expandNetInBuffer", Integer.toString(newLimit)));
netInBuffer = ByteBufferUtils.expand(netInBuffer, newLimit);
if (sc.read(netInBuffer) < 0) {
@@ -274,45 +273,42 @@ public class SecureNioChannel extends NioChannel {
List<Cipher> clientRequestedCiphers = null;
List<String> clientRequestedApplicationProtocols = null;
switch (extractor.getResult()) {
- case COMPLETE:
- hostName = extractor.getSNIValue();
- clientRequestedApplicationProtocols =
- extractor.getClientRequestedApplicationProtocols();
- //$FALL-THROUGH$ to set the client requested ciphers
- case NOT_PRESENT:
- clientRequestedCiphers = extractor.getClientRequestedCiphers();
- break;
- case NEED_READ:
- return SelectionKey.OP_READ;
- case UNDERFLOW:
- // Unable to buffer enough data to read SNI extension data
- if (log.isDebugEnabled()) {
- log.debug(sm.getString("channel.nio.ssl.sniDefault"));
- }
- hostName = endpoint.getDefaultSSLHostConfigName();
- clientRequestedCiphers = Collections.emptyList();
- break;
- case NON_SECURE:
- netOutBuffer.clear();
- netOutBuffer.put(TLSClientHelloExtractor.USE_TLS_RESPONSE);
- netOutBuffer.flip();
- flushOutbound();
- throw new IOException(sm.getString("channel.nio.ssl.foundHttp"));
+ case COMPLETE:
+ hostName = extractor.getSNIValue();
+ clientRequestedApplicationProtocols = extractor.getClientRequestedApplicationProtocols();
+ //$FALL-THROUGH$ to set the client requested ciphers
+ case NOT_PRESENT:
+ clientRequestedCiphers = extractor.getClientRequestedCiphers();
+ break;
+ case NEED_READ:
+ return SelectionKey.OP_READ;
+ case UNDERFLOW:
+ // Unable to buffer enough data to read SNI extension data
+ if (log.isDebugEnabled()) {
+ log.debug(sm.getString("channel.nio.ssl.sniDefault"));
+ }
+ hostName = endpoint.getDefaultSSLHostConfigName();
+ clientRequestedCiphers = Collections.emptyList();
+ break;
+ case NON_SECURE:
+ netOutBuffer.clear();
+ netOutBuffer.put(TLSClientHelloExtractor.USE_TLS_RESPONSE);
+ netOutBuffer.flip();
+ flushOutbound();
+ throw new IOException(sm.getString("channel.nio.ssl.foundHttp"));
}
if (log.isTraceEnabled()) {
log.trace(sm.getString("channel.nio.ssl.sniHostName", sc, hostName));
}
- createSSLEngine(hostName, clientRequestedCiphers,
- clientRequestedApplicationProtocols);
+ createSSLEngine(hostName, clientRequestedCiphers, clientRequestedApplicationProtocols);
// Populate additional TLS attributes obtained from the handshake that
// aren't available from the session
additionalTlsAttributes.put(SSLSupport.REQUESTED_PROTOCOL_VERSIONS_KEY,
extractor.getClientRequestedProtocols());
- additionalTlsAttributes.put(SSLSupport.REQUESTED_CIPHERS_KEY,
- extractor.getClientRequestedCipherNames());
+ additionalTlsAttributes.put(SSLSupport.REQUESTED_CIPHERS_KEY, extractor.getClientRequestedCipherNames());
// Ensure the application buffers (which have to be created earlier) are
// big enough.
@@ -338,16 +334,17 @@ public class SecureNioChannel extends NioChannel {
/**
- * Force a blocking handshake to take place for this key.
- * This requires that both network and application buffers have been emptied out prior to this call taking place, or a
- * IOException will be thrown.
+ * Force a blocking handshake to take place for this key. This requires that both network and application buffers
+ * have been emptied out prior to this call taking place, or a IOException will be thrown.
+ *
* @param timeout - timeout in milliseconds for each socket operation
- * @throws IOException - if an IO exception occurs or if application or network buffers contain data
+ *
+ * @throws IOException - if an IO exception occurs or if application or network buffers contain data
* @throws SocketTimeoutException - if a socket operation timed out
*/
@SuppressWarnings("null") // key cannot be null
public void rehandshake(long timeout) throws IOException {
- //validate the network buffers are empty
+ // validate the network buffers are empty
if (netInBuffer.position() > 0 && netInBuffer.position() < netInBuffer.limit()) {
throw new IOException(sm.getString("channel.nio.ssl.netInputNotEmpty"));
}
@@ -372,12 +369,12 @@ public class SecureNioChannel extends NioChannel {
while (handshaking) {
int hsStatus = this.handshake(isReadable, isWritable);
switch (hsStatus) {
- case -1 :
+ case -1:
throw new EOFException(sm.getString("channel.nio.ssl.eofDuringHandshake"));
- case 0 :
+ case 0:
handshaking = false;
break;
- default :
+ default:
long now = System.currentTimeMillis();
if (selector == null) {
selector = Selector.open();
@@ -386,7 +383,7 @@ public class SecureNioChannel extends NioChannel {
key.interestOps(hsStatus); // null warning suppressed
}
int keyCount = selector.select(timeout);
- if (keyCount == 0 && ((System.currentTimeMillis()-now) >= timeout)) {
+ if (keyCount == 0 && ((System.currentTimeMillis() - now) >= timeout)) {
throw new SocketTimeoutException(sm.getString("channel.nio.ssl.timeoutDuringHandshake"));
}
isReadable = key.isReadable();
@@ -416,9 +413,9 @@ public class SecureNioChannel extends NioChannel {
}
-
/**
* Executes all the tasks needed on the same thread.
+ *
* @return the status
*/
protected SSLEngineResult.HandshakeStatus tasks() {
@@ -431,22 +428,25 @@ public class SecureNioChannel extends NioChannel {
/**
* Performs the WRAP function
+ *
* @param doWrite boolean
+ *
* @return the result
+ *
* @throws IOException An IO error occurred
*/
protected SSLEngineResult handshakeWrap(boolean doWrite) throws IOException {
- //this should never be called with a network buffer that contains data
- //so we can clear it here.
+ // this should never be called with a network buffer that contains data
+ // so we can clear it here.
netOutBuffer.clear();
- //perform the wrap
+ // perform the wrap
getBufHandler().configureWriteBufferForRead();
SSLEngineResult result = sslEngine.wrap(getBufHandler().getWriteBuffer(), netOutBuffer);
- //prepare the results to be written
+ // prepare the results to be written
netOutBuffer.flip();
- //set the status
+ // set the status
handshakeStatus = result.getHandshakeStatus();
- //optimization, if we do have a writable channel, write it now
+ // optimization, if we do have a writable channel, write it now
if (doWrite) {
flush(netOutBuffer);
}
@@ -455,14 +455,17 @@ public class SecureNioChannel extends NioChannel {
/**
* Perform handshake unwrap
+ *
* @param doread boolean
+ *
* @return the result
+ *
* @throws IOException An IO error occurred
*/
protected SSLEngineResult handshakeUnwrap(boolean doread) throws IOException {
- if (doread) {
- //if we have data to read, read it
+ if (doread) {
+ // if we have data to read, read it
int read = sc.read(netInBuffer);
if (read == -1) {
throw new IOException(sm.getString("channel.nio.ssl.eofDuringHandshake"));
@@ -470,30 +473,29 @@ public class SecureNioChannel extends NioChannel {
}
SSLEngineResult result;
boolean cont;
- //loop while we can perform pure SSLEngine data
+ // loop while we can perform pure SSLEngine data
do {
- //prepare the buffer with the incoming data
+ // prepare the buffer with the incoming data
netInBuffer.flip();
- //call unwrap
+ // call unwrap
getBufHandler().configureReadBufferForWrite();
result = sslEngine.unwrap(netInBuffer, getBufHandler().getReadBuffer());
/*
* ByteBuffer.compact() is an optional method but netInBuffer is created from either ByteBuffer.allocate()
- * or ByteBuffer.allocateDirect() and the ByteBuffers returned by those methods do implement compact().
- * The ByteBuffer must be in 'read from' mode when compact() is called and will be in 'write to' mode
+ * or ByteBuffer.allocateDirect() and the ByteBuffers returned by those methods do implement compact(). The
+ * ByteBuffer must be in 'read from' mode when compact() is called and will be in 'write to' mode
* afterwards.
*/
netInBuffer.compact();
- //read in the status
+ // read in the status
handshakeStatus = result.getHandshakeStatus();
if (result.getStatus() == SSLEngineResult.Status.OK &&
- result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
- //execute tasks if we need to
+ result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
+ // execute tasks if we need to
handshakeStatus = tasks();
}
- //perform another unwrap?
- cont = result.getStatus() == SSLEngineResult.Status.OK &&
- handshakeStatus == HandshakeStatus.NEED_UNWRAP;
+ // perform another unwrap?
+ cont = result.getStatus() == SSLEngineResult.Status.OK && handshakeStatus == HandshakeStatus.NEED_UNWRAP;
} while (cont);
return result;
}
@@ -507,16 +509,19 @@ public class SecureNioChannel extends NioChannel {
}
/**
- * Sends an SSL close message, will not physically close the connection here.
- * <br>To close the connection, you could do something like
- * <pre><code>
+ * Sends an SSL close message, will not physically close the connection here. <br>
+ * To close the connection, you could do something like
+ *
+ * <pre>
+ * <code>
* close();
* while (isOpen() && !myTimeoutFunction()) Thread.sleep(25);
* if ( isOpen() ) close(true); //forces a close if you timed out
- * </code></pre>
+ * </code>
+ * </pre>
+ *
* @throws IOException if an I/O error occurs
- * @throws IOException if there is data on the outgoing network buffer, and
- * we are unable to flush it
+ * @throws IOException if there is data on the outgoing network buffer, and we are unable to flush it
*/
@Override
public void close() throws IOException {
@@ -534,20 +539,20 @@ public class SecureNioChannel extends NioChannel {
if (!flush(netOutBuffer)) {
throw new IOException(sm.getString("channel.nio.ssl.remainingDataDuringClose"));
}
- //prep the buffer for the close message
+ // prep the buffer for the close message
netOutBuffer.clear();
- //perform the close, since we called sslEngine.closeOutbound
+ // perform the close, since we called sslEngine.closeOutbound
SSLEngineResult handshake = sslEngine.wrap(getEmptyBuf(), netOutBuffer);
- //we should be in a close state
+ // we should be in a close state
if (handshake.getStatus() != SSLEngineResult.Status.CLOSED) {
throw new IOException(sm.getString("channel.nio.ssl.invalidCloseState"));
}
- //prepare the buffer for writing
+ // prepare the buffer for writing
netOutBuffer.flip();
- //if there is data to be written
+ // if there is data to be written
flush(netOutBuffer);
- //is the channel closed?
+ // is the channel closed?
closed = (!netOutBuffer.hasRemaining() && (handshake.getHandshakeStatus() != HandshakeStatus.NEED_WRAP));
}
@@ -580,45 +585,46 @@ public class SecureNioChannel extends NioChannel {
* Reads a sequence of bytes from this channel into the given buffer.
*
* @param dst The buffer into which bytes are to be transferred
- * @return The number of bytes read, possibly zero, or <code>-1</code> if
- * the channel has reached end-of-stream
- * @throws IOException If some other I/O error occurs
+ *
+ * @return The number of bytes read, possibly zero, or <code>-1</code> if the channel has reached end-of-stream
+ *
+ * @throws IOException If some other I/O error occurs
* @throws IllegalStateException if the handshake was not completed
*/
@Override
public int read(ByteBuffer dst) throws IOException {
- //are we in the middle of closing or closed?
+ // are we in the middle of closing or closed?
if (closing || closed) {
return -1;
}
- //did we finish our handshake?
+ // did we finish our handshake?
if (!handshakeComplete) {
throw new IllegalStateException(sm.getString("channel.nio.ssl.incompleteHandshake"));
}
- //read from the network
+ // read from the network
int netread = sc.read(netInBuffer);
- //did we reach EOF? if so send EOF up one layer.
+ // did we reach EOF? if so send EOF up one layer.
if (netread == -1) {
return -1;
}
- //the data read
+ // the data read
int read = 0;
- //the SSL engine result
+ // the SSL engine result
SSLEngineResult unwrap;
do {
- //prepare the buffer
+ // prepare the buffer
netInBuffer.flip();
- //unwrap the data
+ // unwrap the data
unwrap = sslEngine.unwrap(netInBuffer, dst);
- //compact the buffer
+ // compact the buffer
netInBuffer.compact();
if (unwrap.getStatus() == Status.OK || unwrap.getStatus() == Status.BUFFER_UNDERFLOW) {
- //we did receive some data, add it to our total
+ // we did receive some data, add it to our total
read += unwrap.bytesProduced();
- //perform any tasks if needed
+ // perform any tasks if needed
if (unwrap.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
tasks();
} else if (unwrap.getHandshakeStatus() == HandshakeStatus.NEED_WRAP) {
@@ -630,7 +636,7 @@ public class SecureNioChannel extends NioChannel {
needHandshakeWrap = true;
}
}
- //if we need more network data, then bail out for now.
+ // if we need more network data, then bail out for now.
if (unwrap.getStatus() == Status.BUFFER_UNDERFLOW) {
break;
}
@@ -653,8 +659,7 @@ public class SecureNioChannel extends NioChannel {
} else {
// Can't expand the buffer as there is no way to signal
// to the caller that the buffer has been replaced.
- throw new IOException(
- sm.getString("channel.nio.ssl.unwrapFailResize", unwrap.getStatus()));
+ throw new IOException(sm.getString("channel.nio.ssl.unwrapFailResize", unwrap.getStatus()));
}
}
} else if (unwrap.getStatus() == Status.CLOSED && netInBuffer.position() == 0 && read > 0) {
@@ -669,53 +674,52 @@ public class SecureNioChannel extends NioChannel {
// Something else went wrong
throw new IOException(sm.getString("channel.nio.ssl.unwrapFail", unwrap.getStatus()));
}
- } while (netInBuffer.position() != 0); //continue unwrapping as long as the input buffer has stuff
+ } while (netInBuffer.position() != 0); // continue unwrapping as long as the input buffer has stuff
return read;
}
@Override
- public long read(ByteBuffer[] dsts, int offset, int length)
- throws IOException {
- //are we in the middle of closing or closed?
+ public long read(ByteBuffer[] dsts, int offset, int length) throws IOException {
+ // are we in the middle of closing or closed?
if (closing || closed) {
return -1;
}
- //did we finish our handshake?
+ // did we finish our handshake?
if (!handshakeComplete) {
throw new IllegalStateException(sm.getString("channel.nio.ssl.incompleteHandshake"));
}
- //read from the network
+ // read from the network
int netread = sc.read(netInBuffer);
- //did we reach EOF? if so send EOF up one layer.
+ // did we reach EOF? if so send EOF up one layer.
if (netread == -1) {
return -1;
}
- //the data read
+ // the data read
int read = 0;
- //the SSL engine result
+ // the SSL engine result
SSLEngineResult unwrap;
OverflowState overflowState = OverflowState.NONE;
do {
if (overflowState == OverflowState.PROCESSING) {
overflowState = OverflowState.DONE;
}
- //prepare the buffer
+ // prepare the buffer
netInBuffer.flip();
- //unwrap the data
+ // unwrap the data
unwrap = sslEngine.unwrap(netInBuffer, dsts, offset, length);
- //compact the buffer
+ // compact the buffer
netInBuffer.compact();
if (unwrap.getStatus() == Status.OK || unwrap.getStatus() == Status.BUFFER_UNDERFLOW) {
- //we did receive some data, add it to our total
+ // we did receive some data, add it to our total
read += unwrap.bytesProduced();
if (overflowState == OverflowState.DONE) {
// Remove the data read into the overflow buffer
read -= getBufHandler().getReadBuffer().position();
}
- //perform any tasks if needed
+ // perform any tasks if needed
if (unwrap.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
tasks();
} else if (unwrap.getHandshakeStatus() == HandshakeStatus.NEED_WRAP) {
@@ -727,7 +731,7 @@ public class SecureNioChannel extends NioChannel {
needHandshakeWrap = true;
}
}
- //if we need more network data, then bail out for now.
+ // if we need more network data, then bail out for now.
if (unwrap.getStatus() == Status.BUFFER_UNDERFLOW) {
break;
}
@@ -751,7 +755,8 @@ public class SecureNioChannel extends NioChannel {
}
dsts[offset + i] = getBufHandler().getReadBuffer();
found = true;
- } else if (getAppReadBufHandler() != null && dsts[offset + i] == getAppReadBufHandler().getByteBuffer()) {
+ } else if (getAppReadBufHandler() != null &&
+ dsts[offset + i] == getAppReadBufHandler().getByteBuffer()) {
getAppReadBufHandler().expand(sslEngine.getSession().getApplicationBufferSize());
if (dsts[offset + i] == getAppReadBufHandler().getByteBuffer()) {
resized = false;
@@ -795,7 +800,9 @@ public class SecureNioChannel extends NioChannel {
* Writes a sequence of bytes to this channel from the given buffer.
*
* @param src The buffer from which bytes are to be retrieved
+ *
* @return The number of bytes written, possibly zero
+ *
* @throws IOException If some other I/O error occurs
*/
@Override
@@ -845,8 +852,7 @@ public class SecureNioChannel extends NioChannel {
}
@Override
- public long write(ByteBuffer[] srcs, int offset, int length)
- throws IOException {
+ public long write(ByteBuffer[] srcs, int offset, int length) throws IOException {
checkInterruptStatus();
// Are we closing or closed?
if (closing || closed) {
@@ -911,9 +917,9 @@ public class SecureNioChannel extends NioChannel {
return emptyBuf;
}
- protected void createSSLEngine(String hostName, List<Cipher> clientRequestedCiphers, List<String> clientRequestedApplicationProtocols) {
- sslEngine = endpoint.createSSLEngine(hostName, clientRequestedCiphers,
- clientRequestedApplicationProtocols);
+ protected void createSSLEngine(String hostName, List<Cipher> clientRequestedCiphers,
+ List<String> clientRequestedApplicationProtocols) {
+ sslEngine = endpoint.createSSLEngine(hostName, clientRequestedCiphers, clientRequestedApplicationProtocols);
}
diff --git a/java/org/apache/tomcat/util/net/SendfileDataBase.java b/java/org/apache/tomcat/util/net/SendfileDataBase.java
index d69e6dbc90..37736432c7 100644
--- a/java/org/apache/tomcat/util/net/SendfileDataBase.java
+++ b/java/org/apache/tomcat/util/net/SendfileDataBase.java
@@ -19,30 +19,26 @@ package org.apache.tomcat.util.net;
public abstract class SendfileDataBase {
/**
- * Is the current request being processed on a keep-alive connection? This
- * determines if the socket is closed once the send file completes or if
- * processing continues with the next request on the connection or waiting
- * for that next request to arrive.
+ * Is the current request being processed on a keep-alive connection? This determines if the socket is closed once
+ * the send file completes or if processing continues with the next request on the connection or waiting for that
+ * next request to arrive.
*/
public SendfileKeepAliveState keepAliveState = SendfileKeepAliveState.NONE;
/**
- * The full path to the file that contains the data to be written to the
- * socket.
+ * The full path to the file that contains the data to be written to the socket.
*/
public final String fileName;
/**
- * The position of the next byte in the file to be written to the socket.
- * This is initialised to the start point and then updated as the file is
- * written.
+ * The position of the next byte in the file to be written to the socket. This is initialised to the start point and
+ * then updated as the file is written.
*/
public long pos;
/**
- * The number of bytes remaining to be written from the file (from the
- * current {@link #pos}). This is initialised to the end point - the start
- * point and then updated as the file is written.
+ * The number of bytes remaining to be written from the file (from the current {@link #pos}). This is initialised to
+ * the end point - the start point and then updated as the file is written.
*/
public long length;
diff --git a/java/org/apache/tomcat/util/net/SendfileKeepAliveState.java b/java/org/apache/tomcat/util/net/SendfileKeepAliveState.java
index b27a9f142b..1674d3161a 100644
--- a/java/org/apache/tomcat/util/net/SendfileKeepAliveState.java
+++ b/java/org/apache/tomcat/util/net/SendfileKeepAliveState.java
@@ -19,21 +19,19 @@ package org.apache.tomcat.util.net;
public enum SendfileKeepAliveState {
/**
- * Keep-alive is not in use. The socket can be closed when the response has
- * been written.
+ * Keep-alive is not in use. The socket can be closed when the response has been written.
*/
NONE,
/**
- * Keep-alive is in use and there is pipelined data in the input buffer to
- * be read as soon as the current response has been written.
+ * Keep-alive is in use and there is pipelined data in the input buffer to be read as soon as the current response
+ * has been written.
*/
PIPELINED,
/**
- * Keep-alive is in use. The socket should be added to the poller (or
- * equivalent) to await more data as soon as the current response has been
- * written.
+ * Keep-alive is in use. The socket should be added to the poller (or equivalent) to await more data as soon as the
+ * current response has been written.
*/
OPEN
}
diff --git a/java/org/apache/tomcat/util/net/SendfileState.java b/java/org/apache/tomcat/util/net/SendfileState.java
index b354e2fc28..640beccbb7 100644
--- a/java/org/apache/tomcat/util/net/SendfileState.java
+++ b/java/org/apache/tomcat/util/net/SendfileState.java
@@ -19,8 +19,7 @@ package org.apache.tomcat.util.net;
public enum SendfileState {
/**
- * The sending of the file has started but has not completed. Sendfile is
- * still using the socket.
+ * The sending of the file has started but has not completed. Sendfile is still using the socket.
*/
PENDING,
@@ -30,8 +29,7 @@ public enum SendfileState {
DONE,
/**
- * Something went wrong. The file may or may not have been sent. The socket
- * is in an unknown state.
+ * Something went wrong. The file may or may not have been sent. The socket is in an unknown state.
*/
ERROR
}
diff --git a/java/org/apache/tomcat/util/net/ServletConnectionImpl.java b/java/org/apache/tomcat/util/net/ServletConnectionImpl.java
index a2cb426b45..4105e4b962 100644
--- a/java/org/apache/tomcat/util/net/ServletConnectionImpl.java
+++ b/java/org/apache/tomcat/util/net/ServletConnectionImpl.java
@@ -18,8 +18,8 @@ package org.apache.tomcat.util.net;
import jakarta.servlet.ServletConnection;
-public record ServletConnectionImpl(String connectionId, String protocol, String protocolConnectionId,
- boolean secure) implements ServletConnection {
+public record ServletConnectionImpl(String connectionId, String protocol, String protocolConnectionId, boolean secure)
+ implements ServletConnection {
@Override
public String getConnectionId() {
return connectionId;
diff --git a/java/org/apache/tomcat/util/net/SocketBufferHandler.java b/java/org/apache/tomcat/util/net/SocketBufferHandler.java
index 78adf30632..91b421a7b3 100644
--- a/java/org/apache/tomcat/util/net/SocketBufferHandler.java
+++ b/java/org/apache/tomcat/util/net/SocketBufferHandler.java
@@ -27,13 +27,12 @@ public class SocketBufferHandler {
@Override
public void expand(int newSize) {
}
+
/*
- * Http2AsyncParser$FrameCompletionHandler will return incomplete
- * frame(s) to the buffer. If the previous frame (or concurrent write to
- * a stream) triggered a connection close this call would fail with a
- * BufferOverflowException as data can't be returned to a buffer of zero
- * length. Override the method and make it a NO-OP to avoid triggering
- * the exception.
+ * Http2AsyncParser$FrameCompletionHandler will return incomplete frame(s) to the buffer. If the previous frame
+ * (or concurrent write to a stream) triggered a connection close this call would fail with a
+ * BufferOverflowException as data can't be returned to a buffer of zero length. Override the method and make it
+ * a NO-OP to avoid triggering the exception.
*/
@Override
public void unReadReadBuffer(ByteBuffer returnedData) {
@@ -48,8 +47,7 @@ public class SocketBufferHandler {
private final boolean direct;
- public SocketBufferHandler(int readBufferSize, int writeBufferSize,
- boolean direct) {
+ public SocketBufferHandler(int readBufferSize, int writeBufferSize, boolean direct) {
this.direct = direct;
if (direct) {
readBuffer = ByteBuffer.allocateDirect(readBufferSize);
diff --git a/java/org/apache/tomcat/util/net/SocketEvent.java b/java/org/apache/tomcat/util/net/SocketEvent.java
index 4d70e98f6c..5eb6274ae6 100644
--- a/java/org/apache/tomcat/util/net/SocketEvent.java
+++ b/java/org/apache/tomcat/util/net/SocketEvent.java
@@ -17,9 +17,8 @@
package org.apache.tomcat.util.net;
/**
- * Defines events that occur per socket that require further processing by the
- * container. Usually these events are triggered by the socket implementation,
- * but they may be triggered by the container.
+ * Defines events that occur per socket that require further processing by the container. Usually these events are
+ * triggered by the socket implementation, but they may be triggered by the container.
*/
public enum SocketEvent {
@@ -34,14 +33,13 @@ public enum SocketEvent {
OPEN_WRITE,
/**
- * The associated Connector/Endpoint is stopping and the connection/socket
- * needs to be closed cleanly.
+ * The associated Connector/Endpoint is stopping and the connection/socket needs to be closed cleanly.
*/
STOP,
/**
- * A timeout has occurred and the connection needs to be closed cleanly.
- * Currently, this is only used by the Servlet 3.0 async processing.
+ * A timeout has occurred and the connection needs to be closed cleanly. Currently, this is only used by the Servlet
+ * 3.0 async processing.
*/
TIMEOUT,
@@ -51,20 +49,18 @@ public enum SocketEvent {
DISCONNECT,
/**
- * An error has occurred on a non-container thread and processing needs to
- * return to the container for any necessary clean-up. Examples of where
- * this is used include:
+ * An error has occurred on a non-container thread and processing needs to return to the container for any necessary
+ * clean-up. Examples of where this is used include:
* <ul>
* <li>by NIO2 to signal the failure of a completion handler</li>
- * <li>by the container to signal an I/O error on a non-container thread
- * during Servlet 3.0 asynchronous processing.</li>
+ * <li>by the container to signal an I/O error on a non-container thread during Servlet 3.0 asynchronous
+ * processing.</li>
* </ul>
*/
ERROR,
/**
- * A client attempted to establish a connection but failed. Examples of
- * where this is used include:
+ * A client attempted to establish a connection but failed. Examples of where this is used include:
* <ul>
* <li>TLS handshake failures</li>
* </ul>
diff --git a/java/org/apache/tomcat/util/net/SocketProperties.java b/java/org/apache/tomcat/util/net/SocketProperties.java
index 9fdd494700..76a5ce6e9d 100644
--- a/java/org/apache/tomcat/util/net/SocketProperties.java
+++ b/java/org/apache/tomcat/util/net/SocketProperties.java
@@ -31,9 +31,8 @@ import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.util.res.StringManager;
/**
- * Properties that can be set in the <Connector> element
- * in server.xml. All properties are prefixed with "socket."
- * and are currently only working for the Nio connector
+ * Properties that can be set in the <Connector> element in server.xml. All properties are prefixed with
+ * "socket." and are currently only working for the Nio connector
*/
public class SocketProperties {
@@ -41,8 +40,7 @@ public class SocketProperties {
private static final StringManager sm = StringManager.getManager(SocketProperties.class);
/**
- * Enable/disable socket processor cache, this bounded cache stores
- * SocketProcessor objects to reduce GC.
+ * Enable/disable socket processor cache, this bounded cache stores SocketProcessor objects to reduce GC.
* <p>
* Default is 0<br>
* -1 is unlimited<br>
@@ -51,8 +49,7 @@ public class SocketProperties {
protected int processorCache = 0;
/**
- * Enable/disable poller event cache, this bounded cache stores
- * PollerEvent objects to reduce GC for the poller
+ * Enable/disable poller event cache, this bounded cache stores PollerEvent objects to reduce GC for the poller
* <p>
* Default is 0<br>
* -1 is unlimited<br>
@@ -62,44 +59,37 @@ public class SocketProperties {
protected int eventCache = 0;
/**
- * Enable/disable direct buffers for the network buffers.
- * Default value is disabled.
+ * Enable/disable direct buffers for the network buffers. Default value is disabled.
*/
protected boolean directBuffer = false;
/**
- * Enable/disable direct buffers for the network buffers for SSL.
- * Default value is disabled.
+ * Enable/disable direct buffers for the network buffers for SSL. Default value is disabled.
*/
protected boolean directSslBuffer = false;
/**
- * Socket receive buffer size in bytes (SO_RCVBUF).
- * JVM default used if not set.
+ * Socket receive buffer size in bytes (SO_RCVBUF). JVM default used if not set.
*/
protected Integer rxBufSize = null;
/**
- * Socket send buffer size in bytes (SO_SNDBUF).
- * JVM default used if not set.
+ * Socket send buffer size in bytes (SO_SNDBUF). JVM default used if not set.
*/
protected Integer txBufSize = null;
/**
- * The application read buffer size in bytes.
- * Default value is 8192.
+ * The application read buffer size in bytes. Default value is 8192.
*/
protected int appReadBufSize = 8192;
/**
- * The application write buffer size in bytes.
- * Default value is 8192.
+ * The application write buffer size in bytes. Default value is 8192.
*/
protected int appWriteBufSize = 8192;
/**
- * NioChannel pool size for the endpoint,
- * this value is how many channels.
+ * NioChannel pool size for the endpoint, this value is how many channels.
* <p>
* 0 means no cache<br>
* -1 means unlimited cached<br>
@@ -113,9 +103,8 @@ public class SocketProperties {
* <p>
* -1 means unlimited<br>
* 0 means no cache<br>
- * Default value is based on the max memory reported by the JVM,
- * if less than 1GB, then 0, else the value divided by 32. This value
- * will then be used to compute bufferPool if its value is -2
+ * Default value is based on the max memory reported by the JVM, if less than 1GB, then 0, else the value divided by
+ * 32. This value will then be used to compute bufferPool if its value is -2
*/
protected int bufferPoolSize = -2;
@@ -140,14 +129,14 @@ public class SocketProperties {
protected Boolean soReuseAddress = null;
/**
- * SO_LINGER option, paired with the <code>soLingerTime</code> value.
- * JVM defaults used unless both attributes are set.
+ * SO_LINGER option, paired with the <code>soLingerTime</code> value. JVM defaults used unless both attributes are
+ * set.
*/
protected Boolean soLingerOn = null;
/**
- * SO_LINGER option, paired with the <code>soLingerOn</code> value.
- * JVM defaults used unless both attributes are set.
+ * SO_LINGER option, paired with the <code>soLingerOn</code> value. JVM defaults used unless both attributes are
+ * set.
*/
protected Integer soLingerTime = null;
@@ -157,32 +146,28 @@ public class SocketProperties {
protected Integer soTimeout = Integer.valueOf(20000);
/**
- * Performance preferences according to
- * <a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/net/Socket.html#setPerformancePreferences(int,int,int)">setPerformancePreferences</a>
- * All three performance attributes must be set or the JVM defaults will be
- * used.
+ * Performance preferences according to <a href=
+ * "https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/net/Socket.html#setPerformancePreferences(int,int,int)">setPerformancePreferences</a>
+ * All three performance attributes must be set or the JVM defaults will be used.
*/
protected Integer performanceConnectionTime = null;
/**
- * Performance preferences according to
- * <a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/net/Socket.html#setPerformancePreferences(int,int,int)">setPerformancePreferences</a>
- * All three performance attributes must be set or the JVM defaults will be
- * used.
+ * Performance preferences according to <a href=
+ * "https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/net/Socket.html#setPerformancePreferences(int,int,int)">setPerformancePreferences</a>
+ * All three performance attributes must be set or the JVM defaults will be used.
*/
protected Integer performanceLatency = null;
/**
- * Performance preferences according to
- * <a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/net/Socket.html#setPerformancePreferences(int,int,int)">setPerformancePreferences</a>
- * All three performance attributes must be set or the JVM defaults will be
- * used.
+ * Performance preferences according to <a href=
+ * "https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/net/Socket.html#setPerformancePreferences(int,int,int)">setPerformancePreferences</a>
+ * All three performance attributes must be set or the JVM defaults will be used.
*/
protected Integer performanceBandwidth = null;
/**
- * The minimum frequency of the timeout interval to avoid excess load from
- * the poller during high traffic
+ * The minimum frequency of the timeout interval to avoid excess load from the poller during high traffic
*/
protected long timeoutInterval = 1000;
@@ -194,32 +179,28 @@ public class SocketProperties {
private ObjectName oname = null;
- public void setProperties(Socket socket) throws SocketException{
+ public void setProperties(Socket socket) throws SocketException {
if (rxBufSize != null) {
socket.setReceiveBufferSize(rxBufSize.intValue());
}
if (txBufSize != null) {
socket.setSendBufferSize(txBufSize.intValue());
}
- if (ooBInline !=null) {
+ if (ooBInline != null) {
socket.setOOBInline(ooBInline.booleanValue());
}
if (soKeepAlive != null) {
socket.setKeepAlive(soKeepAlive.booleanValue());
}
- if (performanceConnectionTime != null && performanceLatency != null &&
- performanceBandwidth != null) {
- socket.setPerformancePreferences(
- performanceConnectionTime.intValue(),
- performanceLatency.intValue(),
+ if (performanceConnectionTime != null && performanceLatency != null && performanceBandwidth != null) {
+ socket.setPerformancePreferences(performanceConnectionTime.intValue(), performanceLatency.intValue(),
performanceBandwidth.intValue());
}
if (soReuseAddress != null) {
socket.setReuseAddress(soReuseAddress.booleanValue());
}
if (soLingerOn != null && soLingerTime != null) {
- socket.setSoLinger(soLingerOn.booleanValue(),
- soLingerTime.intValue());
+ socket.setSoLinger(soLingerOn.booleanValue(), soLingerTime.intValue());
}
if (soTimeout != null && soTimeout.intValue() >= 0) {
socket.setSoTimeout(soTimeout.intValue());
@@ -233,15 +214,12 @@ public class SocketProperties {
}
}
- public void setProperties(ServerSocket socket) throws SocketException{
+ public void setProperties(ServerSocket socket) throws SocketException {
if (rxBufSize != null) {
socket.setReceiveBufferSize(rxBufSize.intValue());
}
- if (performanceConnectionTime != null && performanceLatency != null &&
- performanceBandwidth != null) {
- socket.setPerformancePreferences(
- performanceConnectionTime.intValue(),
- performanceLatency.intValue(),
+ if (performanceConnectionTime != null && performanceLatency != null && performanceBandwidth != null) {
+ socket.setPerformancePreferences(performanceConnectionTime.intValue(), performanceLatency.intValue(),
performanceBandwidth.intValue());
}
if (soReuseAddress != null) {
@@ -371,8 +349,7 @@ public class SocketProperties {
}
public void setPerformanceConnectionTime(int performanceConnectionTime) {
- this.performanceConnectionTime =
- Integer.valueOf(performanceConnectionTime);
+ this.performanceConnectionTime = Integer.valueOf(performanceConnectionTime);
}
public void setTxBufSize(int txBufSize) {
@@ -473,8 +450,10 @@ public class SocketProperties {
/**
* Get the actual buffer pool size to use.
- * @param bufferOverhead When TLS is enabled, additional network buffers
- * are needed and will be added to the application buffer size
+ *
+ * @param bufferOverhead When TLS is enabled, additional network buffers are needed and will be added to the
+ * application buffer size
+ *
* @return the actual buffer pool size that will be used
*/
public int getActualBufferPool(int bufferOverhead) {
diff --git a/java/org/apache/tomcat/util/net/SocketWrapperBase.java b/java/org/apache/tomcat/util/net/SocketWrapperBase.java
index a911938a09..d3b134e2b3 100644
--- a/java/org/apache/tomcat/util/net/SocketWrapperBase.java
+++ b/java/org/apache/tomcat/util/net/SocketWrapperBase.java
@@ -47,14 +47,12 @@ public abstract class SocketWrapperBase<E> {
protected static final StringManager sm = StringManager.getManager(SocketWrapperBase.class);
/*
- * At 100,000 connections a second there are enough IDs here for ~3,000,000
- * years before it overflows (and then we have another 3,000,000 years
- * before it gets back to zero).
+ * At 100,000 connections a second there are enough IDs here for ~3,000,000 years before it overflows (and then we
+ * have another 3,000,000 years before it gets back to zero).
*
- * Local testing shows that 5 threads can obtain 60,000,000+ IDs a second
- * from a single AtomicLong. That is about 17ns per request. It does
- * not appear that the introduction of this counter will cause a bottleneck
- * for connection processing.
+ * Local testing shows that 5 threads can obtain 60,000,000+ IDs a second from a single AtomicLong. That is about
+ * 17ns per request. It does not appear that the introduction of this counter will cause a bottleneck for connection
+ * processing.
*/
private static final AtomicLong connectionIdGenerator = new AtomicLong(0);
@@ -88,9 +86,8 @@ public abstract class SocketWrapperBase<E> {
protected volatile ServletConnection servletConnection = null;
/**
- * Used to record the first IOException that occurs during non-blocking
- * read/writes that can't be usefully propagated up the stack since there is
- * no user code or appropriate container code in the stack to handle it.
+ * Used to record the first IOException that occurs during non-blocking read/writes that can't be usefully
+ * propagated up the stack since there is no user code or appropriate container code in the stack to handle it.
*/
private volatile IOException error = null;
@@ -105,13 +102,10 @@ public abstract class SocketWrapperBase<E> {
protected int bufferedWriteSize = 64 * 1024; // 64k default write buffer
/**
- * Additional buffer used for non-blocking writes. Non-blocking writes need
- * to return immediately even if the data cannot be written immediately but
- * the socket buffer may not be big enough to hold all of the unwritten
- * data. This structure provides an additional buffer to hold the data until
- * it can be written.
- * Not that while the Servlet API only allows one non-blocking write at a
- * time, due to buffering and the possible need to write HTTP headers, this
+ * Additional buffer used for non-blocking writes. Non-blocking writes need to return immediately even if the data
+ * cannot be written immediately but the socket buffer may not be big enough to hold all of the unwritten data. This
+ * structure provides an additional buffer to hold the data until it can be written. Not that while the Servlet API
+ * only allows one non-blocking write at a time, due to buffering and the possible need to write HTTP headers, this
* layer may see multiple writes.
*/
protected final WriteBuffer nonBlockingWriteBuffer = new WriteBuffer(bufferedWriteSize);
@@ -125,9 +119,8 @@ public abstract class SocketWrapperBase<E> {
protected volatile OperationState<?> writeOperation = null;
/**
- * The org.apache.coyote.Processor instance currently associated with the
- * wrapper. Only populated when required to maintain wrapper<->Processor
- * mapping between calls to
+ * The org.apache.coyote.Processor instance currently associated with the wrapper. Only populated when required to
+ * maintain wrapper<->Processor mapping between calls to
* {@link AbstractEndpoint.Handler#process(SocketWrapperBase, SocketEvent)}.
*/
private final AtomicReference<Object> currentProcessor = new AtomicReference<>();
@@ -188,7 +181,10 @@ public abstract class SocketWrapperBase<E> {
executor.execute(runnable);
}
- public IOException getError() { return error; }
+ public IOException getError() {
+ return error;
+ }
+
public void setError(IOException error) {
// Not perfectly thread-safe but good enough. Just needs to ensure that
// once this.error is non-null, it can never be null.
@@ -197,23 +193,25 @@ public abstract class SocketWrapperBase<E> {
}
this.error = error;
}
+
public void checkError() throws IOException {
if (error != null) {
throw error;
}
}
- public String getNegotiatedProtocol() { return negotiatedProtocol; }
+ public String getNegotiatedProtocol() {
+ return negotiatedProtocol;
+ }
+
public void setNegotiatedProtocol(String negotiatedProtocol) {
this.negotiatedProtocol = negotiatedProtocol;
}
/**
- * Set the timeout for reading. Values of zero or less will be changed to
- * -1.
+ * Set the timeout for reading. Values of zero or less will be changed to -1.
*
- * @param readTimeout The timeout in milliseconds. A value of -1 indicates
- * an infinite timeout.
+ * @param readTimeout The timeout in milliseconds. A value of -1 indicates an infinite timeout.
*/
public void setReadTimeout(long readTimeout) {
if (readTimeout > 0) {
@@ -228,11 +226,9 @@ public abstract class SocketWrapperBase<E> {
}
/**
- * Set the timeout for writing. Values of zero or less will be changed to
- * -1.
+ * Set the timeout for writing. Values of zero or less will be changed to -1.
*
- * @param writeTimeout The timeout in milliseconds. A value of zero or less
- * indicates an infinite timeout.
+ * @param writeTimeout The timeout in milliseconds. A value of zero or less indicates an infinite timeout.
*/
public void setWriteTimeout(long writeTimeout) {
if (writeTimeout > 0) {
@@ -247,8 +243,13 @@ public abstract class SocketWrapperBase<E> {
}
- public void setKeepAliveLeft(int keepAliveLeft) { this.keepAliveLeft = keepAliveLeft; }
- public int decrementKeepAlive() { return (--keepAliveLeft); }
+ public void setKeepAliveLeft(int keepAliveLeft) {
+ this.keepAliveLeft = keepAliveLeft;
+ }
+
+ public int decrementKeepAlive() {
+ return (--keepAliveLeft);
+ }
public String getRemoteHost() {
if (remoteHost == null) {
@@ -256,6 +257,7 @@ public abstract class SocketWrapperBase<E> {
}
return remoteHost;
}
+
protected abstract void populateRemoteHost();
public String getRemoteAddr() {
@@ -264,6 +266,7 @@ public abstract class SocketWrapperBase<E> {
}
return remoteAddr;
}
+
protected abstract void populateRemoteAddr();
public int getRemotePort() {
@@ -272,6 +275,7 @@ public abstract class SocketWrapperBase<E> {
}
return remotePort;
}
+
protected abstract void populateRemotePort();
public String getLocalName() {
@@ -280,6 +284,7 @@ public abstract class SocketWrapperBase<E> {
}
return localName;
}
+
protected abstract void populateLocalName();
public String getLocalAddr() {
@@ -288,6 +293,7 @@ public abstract class SocketWrapperBase<E> {
}
return localAddr;
}
+
protected abstract void populateLocalAddr();
public int getLocalPort() {
@@ -296,9 +302,12 @@ public abstract class SocketWrapperBase<E> {
}
return localPort;
}
+
protected abstract void populateLocalPort();
- public SocketBufferHandler getSocketBufferHandler() { return socketBufferHandler; }
+ public SocketBufferHandler getSocketBufferHandler() {
+ return socketBufferHandler;
+ }
public boolean hasDataToRead() {
// Return true because it is always safe to make a read attempt
@@ -310,18 +319,14 @@ public abstract class SocketWrapperBase<E> {
}
/**
- * Checks to see if there are any writes pending and if there are calls
- * {@link #registerWriteInterest()} to trigger a callback once the pending
- * writes have completed.
+ * Checks to see if there are any writes pending and if there are calls {@link #registerWriteInterest()} to trigger
+ * a callback once the pending writes have completed.
* <p>
- * Note: Once this method has returned <code>false</code> it <b>MUST NOT</b>
- * be called again until the pending write has completed and the
- * callback has been fired.
- * TODO: Modify {@link #registerWriteInterest()} so the above
- * restriction is enforced there rather than relying on the caller.
+ * Note: Once this method has returned <code>false</code> it <b>MUST NOT</b> be called again until the pending write
+ * has completed and the callback has been fired. TODO: Modify {@link #registerWriteInterest()} so the above
+ * restriction is enforced there rather than relying on the caller.
*
- * @return <code>true</code> if no writes are pending and data can be
- * written otherwise <code>false</code>
+ * @return <code>true</code> if no writes are pending and data can be written otherwise <code>false</code>
*/
public boolean isReadyForWrite() {
boolean result = canWrite();
@@ -341,8 +346,8 @@ public abstract class SocketWrapperBase<E> {
/**
- * Overridden for debug purposes. No guarantees are made about the format of
- * this message which may vary significantly between point releases.
+ * Overridden for debug purposes. No guarantees are made about the format of this message which may vary
+ * significantly between point releases.
* <p>
* {@inheritDoc}
*/
@@ -353,8 +358,11 @@ public abstract class SocketWrapperBase<E> {
public abstract int read(boolean block, byte[] b, int off, int len) throws IOException;
+
public abstract int read(boolean block, ByteBuffer to) throws IOException;
+
public abstract boolean isReadyForRead() throws IOException;
+
public abstract void setAppReadBufHandler(ApplicationBufferHandler handler);
protected int populateReadBuffer(byte[] b, int off, int len) {
@@ -390,13 +398,11 @@ public abstract class SocketWrapperBase<E> {
/**
- * Return input that has been read to the input buffer for re-reading by the
- * correct component. There are times when a component may read more data
- * than it needs before it passes control to another component. One example
- * of this is during HTTP upgrade. If an (arguably misbehaving client) sends
- * data associated with the upgraded protocol before the HTTP upgrade
- * completes, the HTTP handler may read it. This method provides a way for
- * that data to be returned so it can be processed by the correct component.
+ * Return input that has been read to the input buffer for re-reading by the correct component. There are times when
+ * a component may read more data than it needs before it passes control to another component. One example of this
+ * is during HTTP upgrade. If an (arguably misbehaving client) sends data associated with the upgraded protocol
+ * before the HTTP upgrade completes, the HTTP handler may read it. This method provides a way for that data to be
+ * returned so it can be processed by the correct component.
*
* @param returnedInput The input to return to the input buffer.
*/
@@ -427,8 +433,7 @@ public abstract class SocketWrapperBase<E> {
}
/**
- * Perform the actual close. The closed atomic boolean guarantees this will
- * be called only once per wrapper.
+ * Perform the actual close. The closed atomic boolean guarantees this will be called only once per wrapper.
*/
protected abstract void doClose();
@@ -441,25 +446,19 @@ public abstract class SocketWrapperBase<E> {
/**
- * Writes the provided data to the socket write buffer. If the socket write
- * buffer fills during the write, the content of the socket write buffer is
- * written to the network and this method starts to fill the socket write
- * buffer again. Depending on the size of the data to write, there may be
- * multiple writes to the network.
+ * Writes the provided data to the socket write buffer. If the socket write buffer fills during the write, the
+ * content of the socket write buffer is written to the network and this method starts to fill the socket write
+ * buffer again. Depending on the size of the data to write, there may be multiple writes to the network.
* <p>
- * Non-blocking writes must return immediately and the byte array holding
- * the data to be written must be immediately available for re-use. It may
- * not be possible to write sufficient data to the network to allow this to
- * happen. In this case data that cannot be written to the network and
- * cannot be held by the socket buffer is stored in the non-blocking write
- * buffer.
+ * Non-blocking writes must return immediately and the byte array holding the data to be written must be immediately
+ * available for re-use. It may not be possible to write sufficient data to the network to allow this to happen. In
+ * this case data that cannot be written to the network and cannot be held by the socket buffer is stored in the
+ * non-blocking write buffer.
* <p>
- * Note: There is an implementation assumption that, before switching from
- * non-blocking writes to blocking writes, any data remaining in the
- * non-blocking write buffer will have been written to the network.
+ * Note: There is an implementation assumption that, before switching from non-blocking writes to blocking writes,
+ * any data remaining in the non-blocking write buffer will have been written to the network.
*
- * @param block <code>true</code> if a blocking write should be used,
- * otherwise a non-blocking write will be used
+ * @param block <code>true</code> if a blocking write should be used, otherwise a non-blocking write will be used
* @param buf The byte array containing the data to be written
* @param off The offset within the byte array of the data to be written
* @param len The length of the data to be written
@@ -472,14 +471,11 @@ public abstract class SocketWrapperBase<E> {
}
/*
- * While the implementations for blocking and non-blocking writes are
- * very similar they have been split into separate methods:
- * - To allow subclasses to override them individually. NIO2, for
- * example, overrides the non-blocking write but not the blocking
- * write.
- * - To enable a marginally more efficient implemented for blocking
- * writes which do not require the additional checks related to the
- * use of the non-blocking write buffer
+ * While the implementations for blocking and non-blocking writes are very similar they have been split into
+ * separate methods: - To allow subclasses to override them individually. NIO2, for example, overrides the
+ * non-blocking write but not the blocking write. - To enable a marginally more efficient implemented for
+ * blocking writes which do not require the additional checks related to the use of the non-blocking write
+ * buffer
*/
if (block) {
writeBlocking(buf, off, len);
@@ -490,26 +486,20 @@ public abstract class SocketWrapperBase<E> {
/**
- * Writes the provided data to the socket write buffer. If the socket write
- * buffer fills during the write, the content of the socket write buffer is
- * written to the network and this method starts to fill the socket write
- * buffer again. Depending on the size of the data to write, there may be
- * multiple writes to the network.
+ * Writes the provided data to the socket write buffer. If the socket write buffer fills during the write, the
+ * content of the socket write buffer is written to the network and this method starts to fill the socket write
+ * buffer again. Depending on the size of the data to write, there may be multiple writes to the network.
* <p>
- * Non-blocking writes must return immediately and the ByteBuffer holding
- * the data to be written must be immediately available for re-use. It may
- * not be possible to write sufficient data to the network to allow this to
- * happen. In this case data that cannot be written to the network and
- * cannot be held by the socket buffer is stored in the non-blocking write
- * buffer.
+ * Non-blocking writes must return immediately and the ByteBuffer holding the data to be written must be immediately
+ * available for re-use. It may not be possible to write sufficient data to the network to allow this to happen. In
+ * this case data that cannot be written to the network and cannot be held by the socket buffer is stored in the
+ * non-blocking write buffer.
* <p>
- * Note: There is an implementation assumption that, before switching from
- * non-blocking writes to blocking writes, any data remaining in the
- * non-blocking write buffer will have been written to the network.
+ * Note: There is an implementation assumption that, before switching from non-blocking writes to blocking writes,
+ * any data remaining in the non-blocking write buffer will have been written to the network.
*
- * @param block <code>true</code> if a blocking write should be used,
- * otherwise a non-blocking write will be used
- * @param from The ByteBuffer containing the data to be written
+ * @param block <code>true</code> if a blocking write should be used, otherwise a non-blocking write will be used
+ * @param from The ByteBuffer containing the data to be written
*
* @throws IOException If an IO error occurs during the write
*/
@@ -519,14 +509,11 @@ public abstract class SocketWrapperBase<E> {
}
/*
- * While the implementations for blocking and non-blocking writes are
- * very similar they have been split into separate methods:
- * - To allow subclasses to override them individually. NIO2, for
- * example, overrides the non-blocking write but not the blocking
- * write.
- * - To enable a marginally more efficient implemented for blocking
- * writes which do not require the additional checks related to the
- * use of the non-blocking write buffer
+ * While the implementations for blocking and non-blocking writes are very similar they have been split into
+ * separate methods: - To allow subclasses to override them individually. NIO2, for example, overrides the
+ * non-blocking write but not the blocking write. - To enable a marginally more efficient implemented for
+ * blocking writes which do not require the additional checks related to the use of the non-blocking write
+ * buffer
*/
if (block) {
writeBlocking(from);
@@ -537,17 +524,15 @@ public abstract class SocketWrapperBase<E> {
/**
- * Writes the provided data to the socket write buffer. If the socket write
- * buffer fills during the write, the content of the socket write buffer is
- * written to the network using a blocking write. Once that blocking write
- * is complete, this method starts to fill the socket write buffer again.
- * Depending on the size of the data to write, there may be multiple writes
- * to the network. On completion of this method there will always be space
- * remaining in the socket write buffer.
+ * Writes the provided data to the socket write buffer. If the socket write buffer fills during the write, the
+ * content of the socket write buffer is written to the network using a blocking write. Once that blocking write is
+ * complete, this method starts to fill the socket write buffer again. Depending on the size of the data to write,
+ * there may be multiple writes to the network. On completion of this method there will always be space remaining in
+ * the socket write buffer.
*
- * @param buf The byte array containing the data to be written
- * @param off The offset within the byte array of the data to be written
- * @param len The length of the data to be written
+ * @param buf The byte array containing the data to be written
+ * @param off The offset within the byte array of the data to be written
+ * @param len The length of the data to be written
*
* @throws IOException If an IO error occurs during the write
*/
@@ -568,13 +553,11 @@ public abstract class SocketWrapperBase<E> {
/**
- * Writes the provided data to the socket write buffer. If the socket write
- * buffer fills during the write, the content of the socket write buffer is
- * written to the network using a blocking write. Once that blocking write
- * is complete, this method starts to fill the socket write buffer again.
- * Depending on the size of the data to write, there may be multiple writes
- * to the network. On completion of this method there will always be space
- * remaining in the socket write buffer.
+ * Writes the provided data to the socket write buffer. If the socket write buffer fills during the write, the
+ * content of the socket write buffer is written to the network using a blocking write. Once that blocking write is
+ * complete, this method starts to fill the socket write buffer again. Depending on the size of the data to write,
+ * there may be multiple writes to the network. On completion of this method there will always be space remaining in
+ * the socket write buffer.
*
* @param from The ByteBuffer containing the data to be written
*
@@ -594,25 +577,21 @@ public abstract class SocketWrapperBase<E> {
/**
- * Transfers the data to the socket write buffer (writing that data to the
- * socket if the buffer fills up using a non-blocking write) until either
- * all the data has been transferred and space remains in the socket write
- * buffer or a non-blocking write leaves data in the socket write buffer.
- * After an incomplete write, any data remaining to be transferred to the
- * socket write buffer will be copied to the socket write buffer. If the
- * remaining data is too big for the socket write buffer, the socket write
- * buffer will be filled and the additional data written to the non-blocking
- * write buffer.
+ * Transfers the data to the socket write buffer (writing that data to the socket if the buffer fills up using a
+ * non-blocking write) until either all the data has been transferred and space remains in the socket write buffer
+ * or a non-blocking write leaves data in the socket write buffer. After an incomplete write, any data remaining to
+ * be transferred to the socket write buffer will be copied to the socket write buffer. If the remaining data is too
+ * big for the socket write buffer, the socket write buffer will be filled and the additional data written to the
+ * non-blocking write buffer.
*
- * @param buf The byte array containing the data to be written
- * @param off The offset within the byte array of the data to be written
- * @param len The length of the data to be written
+ * @param buf The byte array containing the data to be written
+ * @param off The offset within the byte array of the data to be written
+ * @param len The length of the data to be written
*
* @throws IOException If an IO error occurs during the write
*/
protected void writeNonBlocking(byte[] buf, int off, int len) throws IOException {
- if (len > 0 && nonBlockingWriteBuffer.isEmpty()
- && socketBufferHandler.isWriteBufferWritable()) {
+ if (len > 0 && nonBlockingWriteBuffer.isEmpty() && socketBufferHandler.isWriteBufferWritable()) {
socketBufferHandler.configureWriteBufferForWrite();
int thisTime = transfer(buf, off, len, socketBufferHandler.getWriteBuffer());
len -= thisTime;
@@ -640,25 +619,20 @@ public abstract class SocketWrapperBase<E> {
/**
- * Transfers the data to the socket write buffer (writing that data to the
- * socket if the buffer fills up using a non-blocking write) until either
- * all the data has been transferred and space remains in the socket write
- * buffer or a non-blocking write leaves data in the socket write buffer.
- * After an incomplete write, any data remaining to be transferred to the
- * socket write buffer will be copied to the socket write buffer. If the
- * remaining data is too big for the socket write buffer, the socket write
- * buffer will be filled and the additional data written to the non-blocking
- * write buffer.
+ * Transfers the data to the socket write buffer (writing that data to the socket if the buffer fills up using a
+ * non-blocking write) until either all the data has been transferred and space remains in the socket write buffer
+ * or a non-blocking write leaves data in the socket write buffer. After an incomplete write, any data remaining to
+ * be transferred to the socket write buffer will be copied to the socket write buffer. If the remaining data is too
+ * big for the socket write buffer, the socket write buffer will be filled and the additional data written to the
+ * non-blocking write buffer.
*
* @param from The ByteBuffer containing the data to be written
*
* @throws IOException If an IO error occurs during the write
*/
- protected void writeNonBlocking(ByteBuffer from)
- throws IOException {
+ protected void writeNonBlocking(ByteBuffer from) throws IOException {
- if (from.hasRemaining() && nonBlockingWriteBuffer.isEmpty()
- && socketBufferHandler.isWriteBufferWritable()) {
+ if (from.hasRemaining() && nonBlockingWriteBuffer.isEmpty() && socketBufferHandler.isWriteBufferWritable()) {
writeNonBlockingInternal(from);
}
@@ -670,8 +644,7 @@ public abstract class SocketWrapperBase<E> {
/**
- * Separate method so it can be re-used by the socket write buffer to write
- * data to the network
+ * Separate method so it can be re-used by the socket write buffer to write data to the network
*
* @param from The ByteBuffer containing the data to be written
*
@@ -695,12 +668,10 @@ public abstract class SocketWrapperBase<E> {
/**
* Writes as much data as possible from any that remains in the buffers.
*
- * @param block <code>true</code> if a blocking write should be used,
- * otherwise a non-blocking write will be used
+ * @param block <code>true</code> if a blocking write should be used, otherwise a non-blocking write will be used
*
- * @return <code>true</code> if data remains to be flushed after this method
- * completes, otherwise <code>false</code>. In blocking mode
- * therefore, the return value should always be <code>false</code>
+ * @return <code>true</code> if data remains to be flushed after this method completes, otherwise
+ * <code>false</code>. In blocking mode therefore, the return value should always be <code>false</code>
*
* @throws IOException If an IO error occurs during the write
*/
@@ -718,8 +689,7 @@ public abstract class SocketWrapperBase<E> {
/**
- * Writes all remaining data from the buffers and blocks until the write is
- * complete.
+ * Writes all remaining data from the buffers and blocks until the write is complete.
*
* @throws IOException If an IO error occurs during the write
*/
@@ -740,8 +710,8 @@ public abstract class SocketWrapperBase<E> {
/**
* Writes as much data as possible from any that remains in the buffers.
*
- * @return <code>true</code> if data remains to be flushed after this method
- * completes, otherwise <code>false</code>.
+ * @return <code>true</code> if data remains to be flushed after this method completes, otherwise
+ * <code>false</code>.
*
* @throws IOException If an IO error occurs during the write
*/
@@ -749,14 +719,12 @@ public abstract class SocketWrapperBase<E> {
/**
- * Write the contents of the socketWriteBuffer to the socket. For blocking
- * writes either then entire contents of the buffer will be written or an
- * IOException will be thrown. Partial blocking writes will not occur.
+ * Write the contents of the socketWriteBuffer to the socket. For blocking writes either then entire contents of the
+ * buffer will be written or an IOException will be thrown. Partial blocking writes will not occur.
*
* @param block Should the write be blocking or not?
*
- * @throws IOException If an I/O error such as a timeout occurs during the
- * write
+ * @throws IOException If an I/O error such as a timeout occurs during the write
*/
protected void doWrite(boolean block) throws IOException {
socketBufferHandler.configureWriteBufferForRead();
@@ -765,15 +733,13 @@ public abstract class SocketWrapperBase<E> {
/**
- * Write the contents of the ByteBuffer to the socket. For blocking writes
- * either then entire contents of the buffer will be written or an
- * IOException will be thrown. Partial blocking writes will not occur.
+ * Write the contents of the ByteBuffer to the socket. For blocking writes either then entire contents of the buffer
+ * will be written or an IOException will be thrown. Partial blocking writes will not occur.
*
* @param block Should the write be blocking or not?
- * @param from the ByteBuffer containing the data to be written
+ * @param from the ByteBuffer containing the data to be written
*
- * @throws IOException If an I/O error such as a timeout occurs during the
- * write
+ * @throws IOException If an I/O error such as a timeout occurs during the write
*/
protected abstract void doWrite(boolean block, ByteBuffer from) throws IOException;
@@ -790,10 +756,9 @@ public abstract class SocketWrapperBase<E> {
public abstract SendfileDataBase createSendfileData(String filename, long pos, long length);
/**
- * Starts the sendfile process. It is expected that if the sendfile process
- * does not complete during this call and does not report an error, that the
- * caller <b>will not</b> add the socket to the poller (or equivalent). That
- * is the responsibility of this method.
+ * Starts the sendfile process. It is expected that if the sendfile process does not complete during this call and
+ * does not report an error, that the caller <b>will not</b> add the socket to the poller (or equivalent). That is
+ * the responsibility of this method.
*
* @param sendfileData Data representing the file to send
*
@@ -802,16 +767,13 @@ public abstract class SocketWrapperBase<E> {
public abstract SendfileState processSendfile(SendfileDataBase sendfileData);
/**
- * Require the client to perform CLIENT-CERT authentication if it hasn't
- * already done so.
+ * Require the client to perform CLIENT-CERT authentication if it hasn't already done so.
*
- * @param sslSupport The SSL/TLS support instance currently being used by
- * the connection that may need updating after the client
- * authentication
+ * @param sslSupport The SSL/TLS support instance currently being used by the connection that may need updating
+ * after the client authentication
*
- * @throws IOException If authentication is required then there will be I/O
- * with the client and this exception will be thrown if
- * that goes wrong
+ * @throws IOException If authentication is required then there will be I/O with the client and this exception will
+ * be thrown if that goes wrong
*/
public abstract void doClientAuth(SSLSupport sslSupport) throws IOException;
@@ -828,18 +790,16 @@ public abstract class SocketWrapperBase<E> {
public enum BlockingMode {
/**
- * The operation will not block. If there are pending operations,
- * the operation will throw a pending exception.
+ * The operation will not block. If there are pending operations, the operation will throw a pending exception.
*/
CLASSIC,
/**
- * The operation will not block. If there are pending operations,
- * the operation will return CompletionState.NOT_DONE.
+ * The operation will not block. If there are pending operations, the operation will return
+ * CompletionState.NOT_DONE.
*/
NON_BLOCK,
/**
- * The operation will block until pending operations are completed, but
- * will not block after performing it.
+ * The operation will block until pending operations are completed, but will not block after performing it.
*/
SEMI_BLOCK,
/**
@@ -873,44 +833,36 @@ public abstract class SocketWrapperBase<E> {
public enum CompletionHandlerCall {
/**
- * Operation should continue, the completion handler shouldn't be
- * called.
+ * Operation should continue, the completion handler shouldn't be called.
*/
CONTINUE,
/**
- * The operation completed but the completion handler shouldn't be
- * called.
+ * The operation completed but the completion handler shouldn't be called.
*/
NONE,
/**
- * The operation is complete, the completion handler should be
- * called.
+ * The operation is complete, the completion handler should be called.
*/
DONE
}
public interface CompletionCheck {
/**
- * Determine what call, if any, should be made to the completion
- * handler.
+ * Determine what call, if any, should be made to the completion handler.
*
- * @param state of the operation (done or done in-line since the
- * IO call is done)
- * @param buffers ByteBuffer[] that has been passed to the
- * original IO call
- * @param offset that has been passed to the original IO call
- * @param length that has been passed to the original IO call
+ * @param state of the operation (done or done in-line since the IO call is done)
+ * @param buffers ByteBuffer[] that has been passed to the original IO call
+ * @param offset that has been passed to the original IO call
+ * @param length that has been passed to the original IO call
*
* @return The call, if any, to make to the completion handler
*/
- CompletionHandlerCall callHandler(CompletionState state, ByteBuffer[] buffers,
- int offset, int length);
+ CompletionHandlerCall callHandler(CompletionState state, ByteBuffer[] buffers, int offset, int length);
}
/**
- * This utility CompletionCheck will cause the write to fully write
- * all remaining data. If the operation completes inline, the
- * completion handler will not be called.
+ * This utility CompletionCheck will cause the write to fully write all remaining data. If the operation completes
+ * inline, the completion handler will not be called.
*/
public static final CompletionCheck COMPLETE_WRITE = (state, buffers, offset, length) -> {
for (int i = 0; i < length; i++) {
@@ -918,13 +870,12 @@ public abstract class SocketWrapperBase<E> {
return CompletionHandlerCall.CONTINUE;
}
}
- return (state == CompletionState.DONE) ? CompletionHandlerCall.DONE
- : CompletionHandlerCall.NONE;
+ return (state == CompletionState.DONE) ? CompletionHandlerCall.DONE : CompletionHandlerCall.NONE;
};
/**
- * This utility CompletionCheck will cause the write to fully write
- * all remaining data. The completion handler will then be called.
+ * This utility CompletionCheck will cause the write to fully write all remaining data. The completion handler will
+ * then be called.
*/
public static final CompletionCheck COMPLETE_WRITE_WITH_COMPLETION = (state, buffers, offset, length) -> {
for (int i = 0; i < length; i++) {
@@ -936,24 +887,21 @@ public abstract class SocketWrapperBase<E> {
};
/**
- * This utility CompletionCheck will cause the completion handler
- * to be called once some data has been read. If the operation
- * completes inline, the completion handler will not be called.
+ * This utility CompletionCheck will cause the completion handler to be called once some data has been read. If the
+ * operation completes inline, the completion handler will not be called.
*/
- public static final CompletionCheck READ_DATA = (state, buffers, offset, length) ->
- (state == CompletionState.DONE) ? CompletionHandlerCall.DONE : CompletionHandlerCall.NONE;
+ public static final CompletionCheck READ_DATA = (state, buffers, offset,
+ length) -> (state == CompletionState.DONE) ? CompletionHandlerCall.DONE : CompletionHandlerCall.NONE;
/**
- * This utility CompletionCheck will cause the completion handler
- * to be called once the given buffers are full. The completion
- * handler will then be called.
+ * This utility CompletionCheck will cause the completion handler to be called once the given buffers are full. The
+ * completion handler will then be called.
*/
public static final CompletionCheck COMPLETE_READ_WITH_COMPLETION = COMPLETE_WRITE_WITH_COMPLETION;
/**
- * This utility CompletionCheck will cause the completion handler
- * to be called once the given buffers are full. If the operation
- * completes inline, the completion handler will not be called.
+ * This utility CompletionCheck will cause the completion handler to be called once the given buffers are full. If
+ * the operation completes inline, the completion handler will not be called.
*/
public static final CompletionCheck COMPLETE_READ = COMPLETE_WRITE;
@@ -970,14 +918,15 @@ public abstract class SocketWrapperBase<E> {
protected final TimeUnit unit;
protected final BlockingMode block;
protected final CompletionCheck check;
- protected final CompletionHandler<Long, ? super A> handler;
+ protected final CompletionHandler<Long,? super A> handler;
protected final Semaphore semaphore;
protected final VectoredIOCompletionHandler<A> completion;
protected final AtomicBoolean callHandler;
- protected OperationState(boolean read, ByteBuffer[] buffers, int offset, int length,
- BlockingMode block, long timeout, TimeUnit unit, A attachment,
- CompletionCheck check, CompletionHandler<Long, ? super A> handler,
- Semaphore semaphore, VectoredIOCompletionHandler<A> completion) {
+
+ protected OperationState(boolean read, ByteBuffer[] buffers, int offset, int length, BlockingMode block,
+ long timeout, TimeUnit unit, A attachment, CompletionCheck check,
+ CompletionHandler<Long,? super A> handler, Semaphore semaphore,
+ VectoredIOCompletionHandler<A> completion) {
this.read = read;
this.buffers = buffers;
this.offset = offset;
@@ -992,13 +941,14 @@ public abstract class SocketWrapperBase<E> {
this.completion = completion;
callHandler = (handler != null) ? new AtomicBoolean(true) : null;
}
+
protected volatile long nBytes = 0;
protected volatile CompletionState state = CompletionState.PENDING;
protected boolean completionDone = true;
/**
- * @return true if the operation is still inline, false if the operation
- * is running on a thread that is not the original caller
+ * @return true if the operation is still inline, false if the operation is running on a thread that is not the
+ * original caller
*/
protected abstract boolean isInline();
@@ -1011,15 +961,15 @@ public abstract class SocketWrapperBase<E> {
/**
* Process the operation using the connector executor.
- * @return true if the operation was accepted, false if the executor
- * rejected execution
+ *
+ * @return true if the operation was accepted, false if the executor rejected execution
*/
protected boolean process() {
try {
getEndpoint().getExecutor().execute(this);
return true;
} catch (RejectedExecutionException ree) {
- log.warn(sm.getString("endpoint.executor.fail", SocketWrapperBase.this) , ree);
+ log.warn(sm.getString("endpoint.executor.fail", SocketWrapperBase.this), ree);
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
// This means we got an OOM or similar creating a thread, or that
@@ -1045,10 +995,10 @@ public abstract class SocketWrapperBase<E> {
}
/**
- * Completion handler for vectored operations. This will check the completion of the operation,
- * then either continue or call the user provided completion handler.
+ * Completion handler for vectored operations. This will check the completion of the operation, then either continue
+ * or call the user provided completion handler.
*/
- protected class VectoredIOCompletionHandler<A> implements CompletionHandler<Long, OperationState<A>> {
+ protected class VectoredIOCompletionHandler<A> implements CompletionHandler<Long,OperationState<A>> {
@Override
public void completed(Long nBytes, OperationState<A> state) {
if (nBytes.longValue() < 0) {
@@ -1059,7 +1009,8 @@ public abstract class SocketWrapperBase<E> {
boolean complete = true;
boolean completion = true;
if (state.check != null) {
- CompletionHandlerCall call = state.check.callHandler(currentState, state.buffers, state.offset, state.length);
+ CompletionHandlerCall call =
+ state.check.callHandler(currentState, state.buffers, state.offset, state.length);
if (call == CompletionHandlerCall.CONTINUE || (!state.read && state.hasOutboundRemaining())) {
complete = false;
} else if (call == CompletionHandlerCall.NONE) {
@@ -1102,6 +1053,7 @@ public abstract class SocketWrapperBase<E> {
}
}
}
+
@Override
public void failed(Throwable exc, OperationState<A> state) {
IOException ioe = null;
@@ -1172,8 +1124,9 @@ public abstract class SocketWrapperBase<E> {
/**
* Allows checking if an asynchronous read operation is currently pending.
- * @return <code>true</code> if the endpoint supports asynchronous IO and
- * a read operation is being processed asynchronously
+ *
+ * @return <code>true</code> if the endpoint supports asynchronous IO and a read operation is being processed
+ * asynchronously
*/
public boolean isReadPending() {
return false;
@@ -1181,30 +1134,30 @@ public abstract class SocketWrapperBase<E> {
/**
* Allows checking if an asynchronous write operation is currently pending.
- * @return <code>true</code> if the endpoint supports asynchronous IO and
- * a write operation is being processed asynchronously
+ *
+ * @return <code>true</code> if the endpoint supports asynchronous IO and a write operation is being processed
+ * asynchronously
*/
public boolean isWritePending() {
return false;
}
/**
- * Scatter read. The completion handler will be called once some
- * data has been read or an error occurred. The default NIO2
- * behavior is used: the completion handler will be called as soon
- * as some data has been read, even if the read has completed inline.
+ * Scatter read. The completion handler will be called once some data has been read or an error occurred. The
+ * default NIO2 behavior is used: the completion handler will be called as soon as some data has been read, even if
+ * the read has completed inline.
+ *
+ * @param timeout timeout duration for the read
+ * @param unit units for the timeout duration
+ * @param attachment an object to attach to the I/O operation that will be used when calling the completion handler
+ * @param handler to call when the IO is complete
+ * @param dsts buffers
+ * @param <A> The attachment type
*
- * @param timeout timeout duration for the read
- * @param unit units for the timeout duration
- * @param attachment an object to attach to the I/O operation that will be
- * used when calling the completion handler
- * @param handler to call when the IO is complete
- * @param dsts buffers
- * @param <A> The attachment type
* @return the completion state (done, done inline, or still pending)
*/
public final <A> CompletionState read(long timeout, TimeUnit unit, A attachment,
- CompletionHandler<Long, ? super A> handler, ByteBuffer... dsts) {
+ CompletionHandler<Long,? super A> handler, ByteBuffer... dsts) {
if (dsts == null) {
throw new IllegalArgumentException();
}
@@ -1212,28 +1165,24 @@ public abstract class SocketWrapperBase<E> {
}
/**
- * Scatter read. The completion handler will be called once some
- * data has been read or an error occurred. If a CompletionCheck
- * object has been provided, the completion handler will only be
- * called if the callHandler method returned true. If no
- * CompletionCheck object has been provided, the default NIO2
- * behavior is used: the completion handler will be called as soon
- * as some data has been read, even if the read has completed inline.
+ * Scatter read. The completion handler will be called once some data has been read or an error occurred. If a
+ * CompletionCheck object has been provided, the completion handler will only be called if the callHandler method
+ * returned true. If no CompletionCheck object has been provided, the default NIO2 behavior is used: the completion
+ * handler will be called as soon as some data has been read, even if the read has completed inline.
+ *
+ * @param block is the blocking mode that will be used for this operation
+ * @param timeout timeout duration for the read
+ * @param unit units for the timeout duration
+ * @param attachment an object to attach to the I/O operation that will be used when calling the completion handler
+ * @param check for the IO operation completion
+ * @param handler to call when the IO is complete
+ * @param dsts buffers
+ * @param <A> The attachment type
*
- * @param block is the blocking mode that will be used for this operation
- * @param timeout timeout duration for the read
- * @param unit units for the timeout duration
- * @param attachment an object to attach to the I/O operation that will be
- * used when calling the completion handler
- * @param check for the IO operation completion
- * @param handler to call when the IO is complete
- * @param dsts buffers
- * @param <A> The attachment type
* @return the completion state (done, done inline, or still pending)
*/
- public final <A> CompletionState read(BlockingMode block, long timeout,
- TimeUnit unit, A attachment, CompletionCheck check,
- CompletionHandler<Long, ? super A> handler, ByteBuffer... dsts) {
+ public final <A> CompletionState read(BlockingMode block, long timeout, TimeUnit unit, A attachment,
+ CompletionCheck check, CompletionHandler<Long,? super A> handler, ByteBuffer... dsts) {
if (dsts == null) {
throw new IllegalArgumentException();
}
@@ -1241,51 +1190,45 @@ public abstract class SocketWrapperBase<E> {
}
/**
- * Scatter read. The completion handler will be called once some
- * data has been read or an error occurred. If a CompletionCheck
- * object has been provided, the completion handler will only be
- * called if the callHandler method returned true. If no
- * CompletionCheck object has been provided, the default NIO2
- * behavior is used: the completion handler will be called as soon
- * as some data has been read, even if the read has completed inline.
+ * Scatter read. The completion handler will be called once some data has been read or an error occurred. If a
+ * CompletionCheck object has been provided, the completion handler will only be called if the callHandler method
+ * returned true. If no CompletionCheck object has been provided, the default NIO2 behavior is used: the completion
+ * handler will be called as soon as some data has been read, even if the read has completed inline.
+ *
+ * @param dsts buffers
+ * @param offset in the buffer array
+ * @param length in the buffer array
+ * @param block is the blocking mode that will be used for this operation
+ * @param timeout timeout duration for the read
+ * @param unit units for the timeout duration
+ * @param attachment an object to attach to the I/O operation that will be used when calling the completion handler
+ * @param check for the IO operation completion
+ * @param handler to call when the IO is complete
+ * @param <A> The attachment type
*
- * @param dsts buffers
- * @param offset in the buffer array
- * @param length in the buffer array
- * @param block is the blocking mode that will be used for this operation
- * @param timeout timeout duration for the read
- * @param unit units for the timeout duration
- * @param attachment an object to attach to the I/O operation that will be
- * used when calling the completion handler
- * @param check for the IO operation completion
- * @param handler to call when the IO is complete
- * @param <A> The attachment type
* @return the completion state (done, done inline, or still pending)
*/
- public final <A> CompletionState read(ByteBuffer[] dsts, int offset, int length,
- BlockingMode block, long timeout, TimeUnit unit, A attachment,
- CompletionCheck check, CompletionHandler<Long, ? super A> handler) {
+ public final <A> CompletionState read(ByteBuffer[] dsts, int offset, int length, BlockingMode block, long timeout,
+ TimeUnit unit, A attachment, CompletionCheck check, CompletionHandler<Long,? super A> handler) {
return vectoredOperation(true, dsts, offset, length, block, timeout, unit, attachment, check, handler);
}
/**
- * Gather write. The completion handler will be called once some
- * data has been written or an error occurred. The default NIO2
- * behavior is used: the completion handler will be called, even
- * if the write is incomplete and data remains in the buffers, or
- * if the write completed inline.
+ * Gather write. The completion handler will be called once some data has been written or an error occurred. The
+ * default NIO2 behavior is used: the completion handler will be called, even if the write is incomplete and data
+ * remains in the buffers, or if the write completed inline.
+ *
+ * @param timeout timeout duration for the write
+ * @param unit units for the timeout duration
+ * @param attachment an object to attach to the I/O operation that will be used when calling the completion handler
+ * @param handler to call when the IO is complete
+ * @param srcs buffers
+ * @param <A> The attachment type
*
- * @param timeout timeout duration for the write
- * @param unit units for the timeout duration
- * @param attachment an object to attach to the I/O operation that will be
- * used when calling the completion handler
- * @param handler to call when the IO is complete
- * @param srcs buffers
- * @param <A> The attachment type
* @return the completion state (done, done inline, or still pending)
*/
public final <A> CompletionState write(long timeout, TimeUnit unit, A attachment,
- CompletionHandler<Long, ? super A> handler, ByteBuffer... srcs) {
+ CompletionHandler<Long,? super A> handler, ByteBuffer... srcs) {
if (srcs == null) {
throw new IllegalArgumentException();
}
@@ -1293,29 +1236,25 @@ public abstract class SocketWrapperBase<E> {
}
/**
- * Gather write. The completion handler will be called once some
- * data has been written or an error occurred. If a CompletionCheck
- * object has been provided, the completion handler will only be
- * called if the callHandler method returned true. If no
- * CompletionCheck object has been provided, the default NIO2
- * behavior is used: the completion handler will be called, even
- * if the write is incomplete and data remains in the buffers, or
- * if the write completed inline.
+ * Gather write. The completion handler will be called once some data has been written or an error occurred. If a
+ * CompletionCheck object has been provided, the completion handler will only be called if the callHandler method
+ * returned true. If no CompletionCheck object has been provided, the default NIO2 behavior is used: the completion
+ * handler will be called, even if the write is incomplete and data remains in the buffers, or if the write
+ * completed inline.
+ *
+ * @param block is the blocking mode that will be used for this operation
+ * @param timeout timeout duration for the write
+ * @param unit units for the timeout duration
+ * @param attachment an object to attach to the I/O operation that will be used when calling the completion handler
+ * @param check for the IO operation completion
+ * @param handler to call when the IO is complete
+ * @param srcs buffers
+ * @param <A> The attachment type
*
- * @param block is the blocking mode that will be used for this operation
- * @param timeout timeout duration for the write
- * @param unit units for the timeout duration
- * @param attachment an object to attach to the I/O operation that will be
- * used when calling the completion handler
- * @param check for the IO operation completion
- * @param handler to call when the IO is complete
- * @param srcs buffers
- * @param <A> The attachment type
* @return the completion state (done, done inline, or still pending)
*/
- public final <A> CompletionState write(BlockingMode block, long timeout,
- TimeUnit unit, A attachment, CompletionCheck check,
- CompletionHandler<Long, ? super A> handler, ByteBuffer... srcs) {
+ public final <A> CompletionState write(BlockingMode block, long timeout, TimeUnit unit, A attachment,
+ CompletionCheck check, CompletionHandler<Long,? super A> handler, ByteBuffer... srcs) {
if (srcs == null) {
throw new IllegalArgumentException();
}
@@ -1323,62 +1262,54 @@ public abstract class SocketWrapperBase<E> {
}
/**
- * Gather write. The completion handler will be called once some
- * data has been written or an error occurred. If a CompletionCheck
- * object has been provided, the completion handler will only be
- * called if the callHandler method returned true. If no
- * CompletionCheck object has been provided, the default NIO2
- * behavior is used: the completion handler will be called, even
- * if the write is incomplete and data remains in the buffers, or
- * if the write completed inline.
+ * Gather write. The completion handler will be called once some data has been written or an error occurred. If a
+ * CompletionCheck object has been provided, the completion handler will only be called if the callHandler method
+ * returned true. If no CompletionCheck object has been provided, the default NIO2 behavior is used: the completion
+ * handler will be called, even if the write is incomplete and data remains in the buffers, or if the write
+ * completed inline.
+ *
+ * @param srcs buffers
+ * @param offset in the buffer array
+ * @param length in the buffer array
+ * @param block is the blocking mode that will be used for this operation
+ * @param timeout timeout duration for the write
+ * @param unit units for the timeout duration
+ * @param attachment an object to attach to the I/O operation that will be used when calling the completion handler
+ * @param check for the IO operation completion
+ * @param handler to call when the IO is complete
+ * @param <A> The attachment type
*
- * @param srcs buffers
- * @param offset in the buffer array
- * @param length in the buffer array
- * @param block is the blocking mode that will be used for this operation
- * @param timeout timeout duration for the write
- * @param unit units for the timeout duration
- * @param attachment an object to attach to the I/O operation that will be
- * used when calling the completion handler
- * @param check for the IO operation completion
- * @param handler to call when the IO is complete
- * @param <A> The attachment type
* @return the completion state (done, done inline, or still pending)
*/
- public final <A> CompletionState write(ByteBuffer[] srcs, int offset, int length,
- BlockingMode block, long timeout, TimeUnit unit, A attachment,
- CompletionCheck check, CompletionHandler<Long, ? super A> handler) {
+ public final <A> CompletionState write(ByteBuffer[] srcs, int offset, int length, BlockingMode block, long timeout,
+ TimeUnit unit, A attachment, CompletionCheck check, CompletionHandler<Long,? super A> handler) {
return vectoredOperation(false, srcs, offset, length, block, timeout, unit, attachment, check, handler);
}
/**
- * Vectored operation. The completion handler will be called once
- * the operation is complete or an error occurred. If a CompletionCheck
- * object has been provided, the completion handler will only be
- * called if the callHandler method returned true. If no
- * CompletionCheck object has been provided, the default NIO2
- * behavior is used: the completion handler will be called, even
- * if the operation is incomplete, or if the operation completed inline.
+ * Vectored operation. The completion handler will be called once the operation is complete or an error occurred. If
+ * a CompletionCheck object has been provided, the completion handler will only be called if the callHandler method
+ * returned true. If no CompletionCheck object has been provided, the default NIO2 behavior is used: the completion
+ * handler will be called, even if the operation is incomplete, or if the operation completed inline.
+ *
+ * @param read true if the operation is a read, false if it is a write
+ * @param buffers buffers
+ * @param offset in the buffer array
+ * @param length in the buffer array
+ * @param block is the blocking mode that will be used for this operation
+ * @param timeout timeout duration for the write
+ * @param unit units for the timeout duration
+ * @param attachment an object to attach to the I/O operation that will be used when calling the completion handler
+ * @param check for the IO operation completion
+ * @param handler to call when the IO is complete
+ * @param <A> The attachment type
*
- * @param read true if the operation is a read, false if it is a write
- * @param buffers buffers
- * @param offset in the buffer array
- * @param length in the buffer array
- * @param block is the blocking mode that will be used for this operation
- * @param timeout timeout duration for the write
- * @param unit units for the timeout duration
- * @param attachment an object to attach to the I/O operation that will be
- * used when calling the completion handler
- * @param check for the IO operation completion
- * @param handler to call when the IO is complete
- * @param <A> The attachment type
* @return the completion state (done, done inline, or still pending)
*/
- protected final <A> CompletionState vectoredOperation(boolean read,
- ByteBuffer[] buffers, int offset, int length,
- BlockingMode block, long timeout, TimeUnit unit, A attachment,
- CompletionCheck check, CompletionHandler<Long, ? super A> handler) {
+ protected final <A> CompletionState vectoredOperation(boolean read, ByteBuffer[] buffers, int offset, int length,
+ BlockingMode block, long timeout, TimeUnit unit, A attachment, CompletionCheck check,
+ CompletionHandler<Long,? super A> handler) {
IOException ioe = getError();
if (ioe != null) {
handler.failed(ioe, attachment);
@@ -1387,7 +1318,8 @@ public abstract class SocketWrapperBase<E> {
if (timeout == -1) {
timeout = AbstractEndpoint.toTimeout(read ? getReadTimeout() : getWriteTimeout());
unit = TimeUnit.MILLISECONDS;
- } else if (!hasPerOperationTimeout() && (unit.toMillis(timeout) != (read ? getReadTimeout() : getWriteTimeout()))) {
+ } else if (!hasPerOperationTimeout() &&
+ (unit.toMillis(timeout) != (read ? getReadTimeout() : getWriteTimeout()))) {
if (read) {
setReadTimeout(unit.toMillis(timeout));
} else {
@@ -1415,8 +1347,8 @@ public abstract class SocketWrapperBase<E> {
}
}
VectoredIOCompletionHandler<A> completion = new VectoredIOCompletionHandler<>();
- OperationState<A> state = newOperationState(read, buffers, offset, length, block, timeout, unit,
- attachment, check, handler, read ? readPending : writePending, completion);
+ OperationState<A> state = newOperationState(read, buffers, offset, length, block, timeout, unit, attachment,
+ check, handler, read ? readPending : writePending, completion);
if (read) {
readOperation = state;
} else {
@@ -1456,11 +1388,9 @@ public abstract class SocketWrapperBase<E> {
}
- protected abstract <A> OperationState<A> newOperationState(boolean read,
- ByteBuffer[] buffers, int offset, int length,
- BlockingMode block, long timeout, TimeUnit unit, A attachment,
- CompletionCheck check, CompletionHandler<Long, ? super A> handler,
- Semaphore semaphore, VectoredIOCompletionHandler<A> completion);
+ protected abstract <A> OperationState<A> newOperationState(boolean read, ByteBuffer[] buffers, int offset,
+ int length, BlockingMode block, long timeout, TimeUnit unit, A attachment, CompletionCheck check,
+ CompletionHandler<Long,? super A> handler, Semaphore semaphore, VectoredIOCompletionHandler<A> completion);
// --------------------------------------------------------- Utility methods
@@ -1498,8 +1428,8 @@ public abstract class SocketWrapperBase<E> {
public ServletConnection getServletConnection(String protocol, String protocolConnectionId) {
if (servletConnection == null) {
- servletConnection = new ServletConnectionImpl(
- connectionId, protocol, protocolConnectionId, endpoint.isSSLEnabled());
+ servletConnection =
+ new ServletConnectionImpl(connectionId, protocol, protocolConnectionId, endpoint.isSSLEnabled());
}
return servletConnection;
}
diff --git a/java/org/apache/tomcat/util/net/TLSClientHelloExtractor.java b/java/org/apache/tomcat/util/net/TLSClientHelloExtractor.java
index afa431e29d..002cee0ac8 100644
--- a/java/org/apache/tomcat/util/net/TLSClientHelloExtractor.java
+++ b/java/org/apache/tomcat/util/net/TLSClientHelloExtractor.java
@@ -32,8 +32,7 @@ import org.apache.tomcat.util.net.openssl.ciphers.Cipher;
import org.apache.tomcat.util.res.StringManager;
/**
- * This class extracts the SNI host name and ALPN protocols from a TLS
- * client-hello message.
+ * This class extracts the SNI host name and ALPN protocols from a TLS client-hello message.
*/
public class TLSClientHelloExtractor {
@@ -53,21 +52,19 @@ public class TLSClientHelloExtractor {
private static final int TLS_EXTENSION_ALPN = 16;
private static final int TLS_EXTENSION_SUPPORTED_VERSION = 43;
- public static byte[] USE_TLS_RESPONSE = ("HTTP/1.1 400 \r\n" +
- "Content-Type: text/plain;charset=UTF-8\r\n" +
- "Connection: close\r\n" +
- "\r\n" +
- "Bad Request\r\n" +
- "This combination of host and port requires TLS.\r\n").getBytes(StandardCharsets.UTF_8);
+ public static byte[] USE_TLS_RESPONSE =
+ ("HTTP/1.1 400 \r\n" + "Content-Type: text/plain;charset=UTF-8\r\n" + "Connection: close\r\n" + "\r\n" +
+ "Bad Request\r\n" + "This combination of host and port requires TLS.\r\n")
+ .getBytes(StandardCharsets.UTF_8);
/**
- * Creates the instance of the parser and processes the provided buffer. The
- * buffer position and limit will be modified during the execution of this
- * method, but they will be returned to the original values before the method
+ * Creates the instance of the parser and processes the provided buffer. The buffer position and limit will be
+ * modified during the execution of this method, but they will be returned to the original values before the method
* exits.
*
* @param netInBuffer The buffer containing the TLS data to process
+ *
* @throws IOException If the client hello message is malformed
*/
public TLSClientHelloExtractor(ByteBuffer netInBuffer) throws IOException {
@@ -150,26 +147,26 @@ public class TLSClientHelloExtractor {
skipBytes(netInBuffer, 2);
// Read the extensions until we run out of data or find the data
// we need
- while (netInBuffer.hasRemaining() && (sniValue == null ||
- clientRequestedApplicationProtocols.isEmpty() || clientRequestedProtocols.isEmpty())) {
+ while (netInBuffer.hasRemaining() && (sniValue == null || clientRequestedApplicationProtocols.isEmpty() ||
+ clientRequestedProtocols.isEmpty())) {
// Extension type is two byte
char extensionType = netInBuffer.getChar();
// Extension size is another two bytes
char extensionDataSize = netInBuffer.getChar();
switch (extensionType) {
- case TLS_EXTENSION_SERVER_NAME: {
- sniValue = readSniExtension(netInBuffer);
- break;
- }
- case TLS_EXTENSION_ALPN:
- readAlpnExtension(netInBuffer, clientRequestedApplicationProtocols);
- break;
- case TLS_EXTENSION_SUPPORTED_VERSION:
- readSupportedVersions(netInBuffer, clientRequestedProtocols);
- break;
- default: {
- skipBytes(netInBuffer, extensionDataSize);
- }
+ case TLS_EXTENSION_SERVER_NAME: {
+ sniValue = readSniExtension(netInBuffer);
+ break;
+ }
+ case TLS_EXTENSION_ALPN:
+ readAlpnExtension(netInBuffer, clientRequestedApplicationProtocols);
+ break;
+ case TLS_EXTENSION_SUPPORTED_VERSION:
+ readSupportedVersions(netInBuffer, clientRequestedProtocols);
+ break;
+ default: {
+ skipBytes(netInBuffer, extensionDataSize);
+ }
}
}
if (clientRequestedProtocols.isEmpty()) {
@@ -198,8 +195,7 @@ public class TLSClientHelloExtractor {
/**
- * @return The SNI value provided by the client converted to lower case if
- * not already lower case.
+ * @return The SNI value provided by the client converted to lower case if not already lower case.
*/
public String getSNIValue() {
if (result == ExtractorResult.COMPLETE) {
@@ -281,8 +277,8 @@ public class TLSClientHelloExtractor {
private static boolean isHttp(ByteBuffer bb) {
// Based on code in Http11InputBuffer
// Note: The actual request is not important. This code only checks that
- // the buffer contains a correctly formatted HTTP request line.
- // The method, target and protocol are not validated.
+ // the buffer contains a correctly formatted HTTP request line.
+ // The method, target and protocol are not validated.
byte chr;
bb.position(0);
diff --git a/java/org/apache/tomcat/util/net/WriteBuffer.java b/java/org/apache/tomcat/util/net/WriteBuffer.java
index fa6599d410..c812b46e8d 100644
--- a/java/org/apache/tomcat/util/net/WriteBuffer.java
+++ b/java/org/apache/tomcat/util/net/WriteBuffer.java
@@ -26,12 +26,10 @@ import java.util.concurrent.LinkedBlockingDeque;
import org.apache.tomcat.util.buf.ByteBufferHolder;
/**
- * Provides an expandable set of buffers for writes. Non-blocking writes can be
- * of any size and may not be able to be written immediately or wholly contained
- * in the buffer used to perform the writes to the next layer. This class
- * provides a buffering capability to allow such writes to return immediately
- * and also allows for the user provided buffers to be re-used / recycled as
- * required.
+ * Provides an expandable set of buffers for writes. Non-blocking writes can be of any size and may not be able to be
+ * written immediately or wholly contained in the buffer used to perform the writes to the next layer. This class
+ * provides a buffering capability to allow such writes to return immediately and also allows for the user provided
+ * buffers to be re-used / recycled as required.
*/
public class WriteBuffer {
@@ -76,14 +74,11 @@ public class WriteBuffer {
/**
- * Create an array of ByteBuffers from the current WriteBuffer, prefixing
- * that array with the provided ByteBuffers.
+ * Create an array of ByteBuffers from the current WriteBuffer, prefixing that array with the provided ByteBuffers.
*
- * @param prefixes The additional ByteBuffers to add to the start of the
- * array
+ * @param prefixes The additional ByteBuffers to add to the start of the array
*
- * @return an array of ByteBuffers from the current WriteBuffer prefixed by
- * the provided ByteBuffers
+ * @return an array of ByteBuffers from the current WriteBuffer prefixed by the provided ByteBuffers
*/
ByteBuffer[] toArray(ByteBuffer... prefixes) {
List<ByteBuffer> result = new ArrayList<>();
@@ -138,8 +133,7 @@ public class WriteBuffer {
/**
- * Interface implemented by clients of the WriteBuffer to enable data to be
- * written back out from the buffer.
+ * Interface implemented by clients of the WriteBuffer to enable data to be written back out from the buffer.
*/
public interface Sink {
boolean writeFromBuffer(ByteBuffer buffer, boolean block) throws IOException;
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org