[Bug 68533] New: Failed to load resource: net::ERR_HTTP2_PROTOCOL_ERROR

2024-01-24 Thread bugzilla
https://bz.apache.org/bugzilla/show_bug.cgi?id=68533

Bug ID: 68533
   Summary: Failed to load resource: net::ERR_HTTP2_PROTOCOL_ERROR
   Product: Tomcat 9
   Version: 9.0.83
  Hardware: PC
OS: Linux
Status: NEW
  Severity: critical
  Priority: P2
 Component: Catalina
  Assignee: dev@tomcat.apache.org
  Reporter: dev.devas...@gmail.com
  Target Milestone: -

In our application we use Embedded Tomcat v9.0.83 with 2 connectors - ssl and
non-ssl.

After 1 hour of user inactivity with an opened (application) page in a browser
(Chrome and Chromium based), our application redirects a user to a login page.

Starting from this moment some of static resources (css, fonts, js, images)
fails to be downloaded with the browser error- Failed to load resource:
net::ERR_HTTP2_PROTOCOL_ERROR (copied from a Network/Console tabs of DevTools).
Page refreshing doesn't solve the problem - previously failed resources may be
downloaded, but now another ones fail.

Only full cache cleaning in a browser lets downloading all static resources.
Here is the same topic on Stack Overflow, but no connector tuning tips didn't
help us.
https://stackoverflow.com/questions/60049290/closenowexception-this-stream-is-not-writeable

In the attachment you can find Tomcat logs with FINE level for
org.apache.coyote.http2. And here is the exception from Spring:

24.01.2024 08:04:57,117 WARN 
org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver
Failure in @ExceptionHandler
com.tibbo.linkserver.plugin.context.web.exception.RestExceptionHandler#handleError(Exception)
- [https-jsse-nio-443-exec-10]
org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver.doResolveHandlerMethodException
(ExceptionHandlerExceptionResolver.java:434)
org.apache.catalina.connector.ClientAbortException:
org.apache.coyote.CloseNowException: Connection [0], Stream [3], This stream is
in state [CLOSED_RST_RX] and is not writable
at
org.apache.catalina.connector.OutputBuffer.doFlush(OutputBuffer.java:309)
at
org.apache.catalina.connector.OutputBuffer.flush(OutputBuffer.java:271)
at
org.apache.catalina.connector.CoyoteOutputStream.flush(CoyoteOutputStream.java:120)
at
org.springframework.security.web.util.OnCommittedResponseWrapper$SaveContextServletOutputStream.flush(OnCommittedResponseWrapper.java:523)
at java.io.FilterOutputStream.flush(FilterOutputStream.java:140)
at
com.fasterxml.jackson.core.json.UTF8JsonGenerator.flush(UTF8JsonGenerator.java:1200)
at
com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:1063)
at
org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:456)
at
org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:104)
at
org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:290)
at
org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor.handleReturnValue(HttpEntityMethodProcessor.java:219)
at
org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:78)
at
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:135)
at
org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver.doResolveHandlerMethodException(ExceptionHandlerExceptionResolver.java:428)
at
org.springframework.web.servlet.handler.AbstractHandlerMethodExceptionResolver.doResolveException(AbstractHandlerMethodExceptionResolver.java:75)
at
org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver.resolveException(AbstractHandlerExceptionResolver.java:142)
at
org.springframework.web.servlet.handler.HandlerExceptionResolverComposite.resolveException(HandlerExceptionResolverComposite.java:80)
at
org.springframework.web.servlet.DispatcherServlet.processHandlerException(DispatcherServlet.java:1331)
at
org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1142)
at
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1088)
at
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:964)
at
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:529)
at
org

(tomcat) branch 10.1.x updated: Make asynchronous error handling more robust.

2024-01-24 Thread markt
This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 10.1.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/10.1.x by this push:
 new 015c4d5079 Make asynchronous error handling more robust.
015c4d5079 is described below

commit 015c4d50797731e45c1b7216fc09646891c725c4
Author: Mark Thomas 
AuthorDate: Wed Jan 24 14:55:06 2024 +

Make asynchronous error handling more robust.

Ensure that once a connection is marked to be closed, further
asynchronous processing cannot change that.
---
 java/org/apache/coyote/AbstractProcessorLight.java | 7 ++-
 webapps/docs/changelog.xml | 5 +
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/java/org/apache/coyote/AbstractProcessorLight.java 
b/java/org/apache/coyote/AbstractProcessorLight.java
index 21515c70d7..fdd0d194fe 100644
--- a/java/org/apache/coyote/AbstractProcessorLight.java
+++ b/java/org/apache/coyote/AbstractProcessorLight.java
@@ -74,7 +74,12 @@ public abstract class AbstractProcessorLight implements 
Processor {
 "Socket: [" + socketWrapper + "], Status in: [" + 
status + "], State out: [" + state + "]");
 }
 
-if (isAsync()) {
+/*
+ * If state is already CLOSED don't call asyncPostProcess() as 
that will likely change the the state to some
+ * other value causing processing to continue when it should 
cease. The AsyncStateMachine will be recycled
+ * as part of the Processor clean-up on CLOSED so it doesn't 
matter what state it is left in at this point.
+ */
+if (isAsync() && state != SocketState.CLOSED) {
 state = asyncPostProcess();
 if (getLog().isDebugEnabled()) {
 getLog().debug(
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 687590df61..44140d341f 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -126,6 +126,11 @@
 Setting a null value for a cookie attribute should remove
 the attribute. (markt)
   
+  
+Make asynchronous error handling more robust. Ensure that once a
+connection is marked to be closed, further asynchronous processing
+cannot change that. (markt)
+  
 
   
   


-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



(tomcat) branch main updated: Make asynchronous error handling more robust.

2024-01-24 Thread markt
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


The following commit(s) were added to refs/heads/main by this push:
 new 1013a74011 Make asynchronous error handling more robust.
1013a74011 is described below

commit 1013a74011fcc381df66426c4d6cb5f3909e5c2f
Author: Mark Thomas 
AuthorDate: Wed Jan 24 14:55:06 2024 +

Make asynchronous error handling more robust.

Ensure that once a connection is marked to be closed, further
asynchronous processing cannot change that.
---
 java/org/apache/coyote/AbstractProcessorLight.java | 7 ++-
 webapps/docs/changelog.xml | 5 +
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/java/org/apache/coyote/AbstractProcessorLight.java 
b/java/org/apache/coyote/AbstractProcessorLight.java
index f86fbc41a5..5a60dd2a54 100644
--- a/java/org/apache/coyote/AbstractProcessorLight.java
+++ b/java/org/apache/coyote/AbstractProcessorLight.java
@@ -74,7 +74,12 @@ public abstract class AbstractProcessorLight implements 
Processor {
 "Socket: [" + socketWrapper + "], Status in: [" + 
status + "], State out: [" + state + "]");
 }
 
-if (isAsync()) {
+/*
+ * If state is already CLOSED don't call asyncPostProcess() as 
that will likely change the the state to some
+ * other value causing processing to continue when it should 
cease. The AsyncStateMachine will be recycled
+ * as part of the Processor clean-up on CLOSED so it doesn't 
matter what state it is left in at this point.
+ */
+if (isAsync() && state != SocketState.CLOSED) {
 state = asyncPostProcess();
 if (getLog().isDebugEnabled()) {
 getLog().debug(
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 1366e546f5..756b40a1b7 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -137,6 +137,11 @@
 Optimize state handling for OpenSSL context callbacks with the FFM API.
 (remm)
   
+  
+Make asynchronous error handling more robust. Ensure that once a
+connection is marked to be closed, further asynchronous processing
+cannot change that. (markt)
+  
 
   
   


-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



(tomcat) branch 9.0.x updated: Make asynchronous error handling more robust.

2024-01-24 Thread markt
This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/9.0.x by this push:
 new b94ecd1b69 Make asynchronous error handling more robust.
b94ecd1b69 is described below

commit b94ecd1b69d0fa6a0568c0f10fd90baa235cf062
Author: Mark Thomas 
AuthorDate: Wed Jan 24 14:55:06 2024 +

Make asynchronous error handling more robust.

Ensure that once a connection is marked to be closed, further
asynchronous processing cannot change that.
---
 java/org/apache/coyote/AbstractProcessorLight.java |  7 ++-
 webapps/docs/changelog.xml | 11 ++-
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/java/org/apache/coyote/AbstractProcessorLight.java 
b/java/org/apache/coyote/AbstractProcessorLight.java
index 21515c70d7..fdd0d194fe 100644
--- a/java/org/apache/coyote/AbstractProcessorLight.java
+++ b/java/org/apache/coyote/AbstractProcessorLight.java
@@ -74,7 +74,12 @@ public abstract class AbstractProcessorLight implements 
Processor {
 "Socket: [" + socketWrapper + "], Status in: [" + 
status + "], State out: [" + state + "]");
 }
 
-if (isAsync()) {
+/*
+ * If state is already CLOSED don't call asyncPostProcess() as 
that will likely change the the state to some
+ * other value causing processing to continue when it should 
cease. The AsyncStateMachine will be recycled
+ * as part of the Processor clean-up on CLOSED so it doesn't 
matter what state it is left in at this point.
+ */
+if (isAsync() && state != SocketState.CLOSED) {
 state = asyncPostProcess();
 if (getLog().isDebugEnabled()) {
 getLog().debug(
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 50d81ad9ac..2b7e17db88 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -120,7 +120,16 @@
   
 
   
- 
+  
+
+  
+Make asynchronous error handling more robust. Ensure that once a
+connection is marked to be closed, further asynchronous processing
+cannot change that. (markt)
+  
+
+  
+  
 
   
 Correct a regression in the fix for 66508 that could cause 
an


-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



(tomcat) branch 8.5.x updated: Make asynchronous error handling more robust.

2024-01-24 Thread markt
This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 8.5.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/8.5.x by this push:
 new ac57ef1ae3 Make asynchronous error handling more robust.
ac57ef1ae3 is described below

commit ac57ef1ae3097f67a5eb4c56a69fbf3e8e926dc3
Author: Mark Thomas 
AuthorDate: Wed Jan 24 14:55:06 2024 +

Make asynchronous error handling more robust.

Ensure that once a connection is marked to be closed, further
asynchronous processing cannot change that.
---
 java/org/apache/coyote/AbstractProcessorLight.java |  7 ++-
 webapps/docs/changelog.xml | 11 ++-
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/java/org/apache/coyote/AbstractProcessorLight.java 
b/java/org/apache/coyote/AbstractProcessorLight.java
index 21515c70d7..fdd0d194fe 100644
--- a/java/org/apache/coyote/AbstractProcessorLight.java
+++ b/java/org/apache/coyote/AbstractProcessorLight.java
@@ -74,7 +74,12 @@ public abstract class AbstractProcessorLight implements 
Processor {
 "Socket: [" + socketWrapper + "], Status in: [" + 
status + "], State out: [" + state + "]");
 }
 
-if (isAsync()) {
+/*
+ * If state is already CLOSED don't call asyncPostProcess() as 
that will likely change the the state to some
+ * other value causing processing to continue when it should 
cease. The AsyncStateMachine will be recycled
+ * as part of the Processor clean-up on CLOSED so it doesn't 
matter what state it is left in at this point.
+ */
+if (isAsync() && state != SocketState.CLOSED) {
 state = asyncPostProcess();
 if (getLog().isDebugEnabled()) {
 getLog().debug(
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index ce5c7c1d2e..d64abaed8c 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -114,7 +114,16 @@
   
 
   
- 
+  
+
+  
+Make asynchronous error handling more robust. Ensure that once a
+connection is marked to be closed, further asynchronous processing
+cannot change that. (markt)
+  
+
+  
+  
 
   
 Correct a regression in the fix for 66508 that could cause 
an


-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



(tomcat) branch main updated: No need for package visibility. Can be final.

2024-01-24 Thread markt
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


The following commit(s) were added to refs/heads/main by this push:
 new 9addc690a6 No need for package visibility. Can be final.
9addc690a6 is described below

commit 9addc690a652a781c5d5781534d9d4ad668f51ba
Author: Mark Thomas 
AuthorDate: Wed Jan 24 15:03:28 2024 +

No need for package visibility. Can be final.
---
 java/org/apache/catalina/core/AsyncContextImpl.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/java/org/apache/catalina/core/AsyncContextImpl.java 
b/java/org/apache/catalina/core/AsyncContextImpl.java
index 0af2ffcf9b..626fb36c2c 100644
--- a/java/org/apache/catalina/core/AsyncContextImpl.java
+++ b/java/org/apache/catalina/core/AsyncContextImpl.java
@@ -73,7 +73,7 @@ public class AsyncContextImpl implements AsyncContext, 
AsyncContextCallback {
 private long timeout = -1;
 private AsyncEvent event = null;
 private volatile Request request;
-AtomicBoolean hasProcessedError = new AtomicBoolean(false);
+private final AtomicBoolean hasProcessedError = new AtomicBoolean(false);
 
 public AsyncContextImpl(Request request) {
 if (log.isDebugEnabled()) {


-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



(tomcat) branch 10.1.x updated: No need for package visibility. Can be final.

2024-01-24 Thread markt
This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 10.1.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/10.1.x by this push:
 new c2e1db47bc No need for package visibility. Can be final.
c2e1db47bc is described below

commit c2e1db47bc2b7395a38c81f0a925e63ab673f4d6
Author: Mark Thomas 
AuthorDate: Wed Jan 24 15:03:28 2024 +

No need for package visibility. Can be final.
---
 java/org/apache/catalina/core/AsyncContextImpl.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/java/org/apache/catalina/core/AsyncContextImpl.java 
b/java/org/apache/catalina/core/AsyncContextImpl.java
index 1e4b03741d..e77203ad21 100644
--- a/java/org/apache/catalina/core/AsyncContextImpl.java
+++ b/java/org/apache/catalina/core/AsyncContextImpl.java
@@ -74,7 +74,7 @@ public class AsyncContextImpl implements AsyncContext, 
AsyncContextCallback {
 private long timeout = -1;
 private AsyncEvent event = null;
 private volatile Request request;
-AtomicBoolean hasProcessedError = new AtomicBoolean(false);
+private final AtomicBoolean hasProcessedError = new AtomicBoolean(false);
 
 public AsyncContextImpl(Request request) {
 if (log.isDebugEnabled()) {


-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



(tomcat) branch 9.0.x updated: No need for package visibility. Can be final.

2024-01-24 Thread markt
This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/9.0.x by this push:
 new 79e52130ba No need for package visibility. Can be final.
79e52130ba is described below

commit 79e52130ba1417b271876ab56707a6ec3289896e
Author: Mark Thomas 
AuthorDate: Wed Jan 24 15:03:28 2024 +

No need for package visibility. Can be final.
---
 java/org/apache/catalina/core/AsyncContextImpl.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/java/org/apache/catalina/core/AsyncContextImpl.java 
b/java/org/apache/catalina/core/AsyncContextImpl.java
index e4466c7d08..ebf71f008d 100644
--- a/java/org/apache/catalina/core/AsyncContextImpl.java
+++ b/java/org/apache/catalina/core/AsyncContextImpl.java
@@ -73,7 +73,7 @@ public class AsyncContextImpl implements AsyncContext, 
AsyncContextCallback {
 private long timeout = -1;
 private AsyncEvent event = null;
 private volatile Request request;
-AtomicBoolean hasProcessedError = new AtomicBoolean(false);
+private final AtomicBoolean hasProcessedError = new AtomicBoolean(false);
 
 public AsyncContextImpl(Request request) {
 if (log.isDebugEnabled()) {


-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



(tomcat) branch 8.5.x updated: No need for package visibility. Can be final.

2024-01-24 Thread markt
This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 8.5.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/8.5.x by this push:
 new 4e1bd11b86 No need for package visibility. Can be final.
4e1bd11b86 is described below

commit 4e1bd11b86b14097d44a5dff8a3ecc750630b62c
Author: Mark Thomas 
AuthorDate: Wed Jan 24 15:03:28 2024 +

No need for package visibility. Can be final.
---
 java/org/apache/catalina/core/AsyncContextImpl.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/java/org/apache/catalina/core/AsyncContextImpl.java 
b/java/org/apache/catalina/core/AsyncContextImpl.java
index ba982cbff1..0f1b3694de 100644
--- a/java/org/apache/catalina/core/AsyncContextImpl.java
+++ b/java/org/apache/catalina/core/AsyncContextImpl.java
@@ -73,7 +73,7 @@ public class AsyncContextImpl implements AsyncContext, 
AsyncContextCallback {
 private long timeout = -1;
 private AsyncEvent event = null;
 private volatile Request request;
-AtomicBoolean hasProcessedError = new AtomicBoolean(false);
+private final AtomicBoolean hasProcessedError = new AtomicBoolean(false);
 
 public AsyncContextImpl(Request request) {
 if (log.isDebugEnabled()) {


-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



(tomcat) branch main updated: Avoid using APR strings since the connector has been removed

2024-01-24 Thread remm
This is an automated email from the ASF dual-hosted git repository.

remm pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/main by this push:
 new 025cb59362 Avoid using APR strings since the connector has been removed
025cb59362 is described below

commit 025cb59362f08bd74a2135a4e8fed630b482b0d7
Author: remm 
AuthorDate: Wed Jan 24 21:12:20 2024 +0100

Avoid using APR strings since the connector has been removed
---
 .../org/apache/tomcat/util/net/openssl/LocalStrings.properties |  2 ++
 java/org/apache/tomcat/util/net/openssl/OpenSSLContext.java| 10 ++
 2 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/java/org/apache/tomcat/util/net/openssl/LocalStrings.properties 
b/java/org/apache/tomcat/util/net/openssl/LocalStrings.properties
index db09d853fd..7823c29050 100644
--- a/java/org/apache/tomcat/util/net/openssl/LocalStrings.properties
+++ b/java/org/apache/tomcat/util/net/openssl/LocalStrings.properties
@@ -46,6 +46,8 @@ openssl.errApplyConf=Could not apply OpenSSLConf to SSL 
context
 openssl.errCheckConf=Error during OpenSSLConf check
 openssl.errMakeConf=Could not create OpenSSLConf context
 openssl.errorSSLCtxInit=Error initializing SSL context
+openssl.failSslContextMake=Unable to create SSLContext. Check that SSLEngine 
is enabled in the AprLifecycleListener, the AprLifecycleListener has 
initialised correctly and that a valid SSLProtocol has been specified
+openssl.invalidSslProtocol=An invalid value [{0}] was provided for the 
SSLProtocol attribute
 openssl.keyManagerMissing=No key manager found
 openssl.keyManagerMissing.warn=No key manager found. TLS will work but the 
certificate will not be visible to Tomcat so management/monitoring features 
will not work for this certificate
 openssl.makeConf=Creating OpenSSLConf context
diff --git a/java/org/apache/tomcat/util/net/openssl/OpenSSLContext.java 
b/java/org/apache/tomcat/util/net/openssl/OpenSSLContext.java
index 00b3ddacc3..11f15589e5 100644
--- a/java/org/apache/tomcat/util/net/openssl/OpenSSLContext.java
+++ b/java/org/apache/tomcat/util/net/openssl/OpenSSLContext.java
@@ -50,7 +50,6 @@ import org.apache.tomcat.jni.Pool;
 import org.apache.tomcat.jni.SSL;
 import org.apache.tomcat.jni.SSLConf;
 import org.apache.tomcat.jni.SSLContext;
-import org.apache.tomcat.util.net.AbstractEndpoint;
 import org.apache.tomcat.util.net.Constants;
 import org.apache.tomcat.util.net.SSLHostConfig;
 import org.apache.tomcat.util.net.SSLHostConfig.CertificateVerification;
@@ -62,9 +61,6 @@ import org.apache.tomcat.util.res.StringManager;
 public class OpenSSLContext implements org.apache.tomcat.util.net.SSLContext {
 
 private static final Log log = LogFactory.getLog(OpenSSLContext.class);
-
-// Note: this uses the main "net" package strings as many are common with 
APR
-private static final StringManager netSm = 
StringManager.getManager(AbstractEndpoint.class);
 private static final StringManager sm = 
StringManager.getManager(OpenSSLContext.class);
 
 private static final String defaultProtocol = "TLS";
@@ -144,8 +140,7 @@ public class OpenSSLContext implements 
org.apache.tomcat.util.net.SSLContext {
 } else {
 // Should not happen since filtering to build
 // enabled protocols removes invalid values.
-throw new Exception(netSm.getString(
-"endpoint.apr.invalidSslProtocol", protocol));
+throw new 
Exception(sm.getString("openssl.invalidSslProtocol", protocol));
 }
 }
 
@@ -156,8 +151,7 @@ public class OpenSSLContext implements 
org.apache.tomcat.util.net.SSLContext {
 // If the sslEngine is disabled on the AprLifecycleListener
 // there will be an Exception here but there is no way to check
 // the AprLifecycleListener settings from here
-throw new Exception(
-netSm.getString("endpoint.apr.failSslContextMake"), e);
+throw new 
Exception(sm.getString("openssl.failSslContextMake"), e);
 }
 
 this.negotiableProtocols = negotiableProtocols;


-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



(tomcat) branch main updated: Avoid APR strings

2024-01-24 Thread remm
This is an automated email from the ASF dual-hosted git repository.

remm pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/main by this push:
 new d275d15a19 Avoid APR strings
d275d15a19 is described below

commit d275d15a19e84bc30151be9d0f7c6a718ed9e003
Author: remm 
AuthorDate: Wed Jan 24 21:12:57 2024 +0100

Avoid APR strings
---
 .../apache/tomcat/util/net/openssl/panama/LocalStrings.properties   | 1 +
 java/org/apache/tomcat/util/net/openssl/panama/OpenSSLContext.java  | 6 +-
 2 files changed, 2 insertions(+), 5 deletions(-)

diff --git 
a/java/org/apache/tomcat/util/net/openssl/panama/LocalStrings.properties 
b/java/org/apache/tomcat/util/net/openssl/panama/LocalStrings.properties
index 4a36782136..4a46900aa2 100644
--- a/java/org/apache/tomcat/util/net/openssl/panama/LocalStrings.properties
+++ b/java/org/apache/tomcat/util/net/openssl/panama/LocalStrings.properties
@@ -57,6 +57,7 @@ openssl.errorLoadingPrivateKey=Error loading private key: 
[{0}]
 openssl.errorLoadingCertificateRevocationListWithError=Error loading 
certificate revocation [{0}] with error [{1}]
 openssl.errorPrivateKeyCheck=Private key does not match the certificate public 
key: [{0}]
 openssl.errorSSLCtxInit=Error initializing SSL context
+openssl.invalidSslProtocol=An invalid value [{0}] was provided for the 
SSLProtocol attribute
 openssl.keyManagerMissing=No key manager found
 openssl.makeConf=Creating OpenSSLConf context
 openssl.noCACerts=No CA certificates were configured
diff --git a/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLContext.java 
b/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLContext.java
index c6e24ee760..1939e465a8 100644
--- a/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLContext.java
+++ b/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLContext.java
@@ -55,7 +55,6 @@ import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
 import org.apache.tomcat.util.file.ConfigFileLoader;
 import org.apache.tomcat.util.file.ConfigurationSource.Resource;
-import org.apache.tomcat.util.net.AbstractEndpoint;
 import org.apache.tomcat.util.net.Constants;
 import org.apache.tomcat.util.net.SSLHostConfig;
 import org.apache.tomcat.util.net.SSLHostConfig.CertificateVerification;
@@ -77,8 +76,6 @@ import org.apache.tomcat.util.res.StringManager;
 public class OpenSSLContext implements org.apache.tomcat.util.net.SSLContext {
 
 private static final Log log = LogFactory.getLog(OpenSSLContext.class);
-
-private static final StringManager netSm = 
StringManager.getManager(AbstractEndpoint.class);
 private static final StringManager sm = 
StringManager.getManager(OpenSSLContext.class);
 
 private static final Cleaner cleaner = Cleaner.create();
@@ -216,8 +213,7 @@ public class OpenSSLContext implements 
org.apache.tomcat.util.net.SSLContext {
 } else {
 // Should not happen since filtering to build
 // enabled protocols removes invalid values.
-throw new Exception(netSm.getString(
-"endpoint.apr.invalidSslProtocol", 
enabledProtocol));
+throw new 
Exception(sm.getString("openssl.invalidSslProtocol", enabledProtocol));
 }
 }
 // Set maximum and minimum protocol versions


-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



(tomcat) branch 10.1.x updated: Avoid using APR strings since the connector has been removed

2024-01-24 Thread remm
This is an automated email from the ASF dual-hosted git repository.

remm pushed a commit to branch 10.1.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/10.1.x by this push:
 new 2d7ade8716 Avoid using APR strings since the connector has been removed
2d7ade8716 is described below

commit 2d7ade8716d6e273438f0bde1638b35141a7868b
Author: remm 
AuthorDate: Wed Jan 24 21:12:20 2024 +0100

Avoid using APR strings since the connector has been removed
---
 .../org/apache/tomcat/util/net/openssl/LocalStrings.properties |  2 ++
 java/org/apache/tomcat/util/net/openssl/OpenSSLContext.java| 10 ++
 2 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/java/org/apache/tomcat/util/net/openssl/LocalStrings.properties 
b/java/org/apache/tomcat/util/net/openssl/LocalStrings.properties
index db09d853fd..7823c29050 100644
--- a/java/org/apache/tomcat/util/net/openssl/LocalStrings.properties
+++ b/java/org/apache/tomcat/util/net/openssl/LocalStrings.properties
@@ -46,6 +46,8 @@ openssl.errApplyConf=Could not apply OpenSSLConf to SSL 
context
 openssl.errCheckConf=Error during OpenSSLConf check
 openssl.errMakeConf=Could not create OpenSSLConf context
 openssl.errorSSLCtxInit=Error initializing SSL context
+openssl.failSslContextMake=Unable to create SSLContext. Check that SSLEngine 
is enabled in the AprLifecycleListener, the AprLifecycleListener has 
initialised correctly and that a valid SSLProtocol has been specified
+openssl.invalidSslProtocol=An invalid value [{0}] was provided for the 
SSLProtocol attribute
 openssl.keyManagerMissing=No key manager found
 openssl.keyManagerMissing.warn=No key manager found. TLS will work but the 
certificate will not be visible to Tomcat so management/monitoring features 
will not work for this certificate
 openssl.makeConf=Creating OpenSSLConf context
diff --git a/java/org/apache/tomcat/util/net/openssl/OpenSSLContext.java 
b/java/org/apache/tomcat/util/net/openssl/OpenSSLContext.java
index 00b3ddacc3..11f15589e5 100644
--- a/java/org/apache/tomcat/util/net/openssl/OpenSSLContext.java
+++ b/java/org/apache/tomcat/util/net/openssl/OpenSSLContext.java
@@ -50,7 +50,6 @@ import org.apache.tomcat.jni.Pool;
 import org.apache.tomcat.jni.SSL;
 import org.apache.tomcat.jni.SSLConf;
 import org.apache.tomcat.jni.SSLContext;
-import org.apache.tomcat.util.net.AbstractEndpoint;
 import org.apache.tomcat.util.net.Constants;
 import org.apache.tomcat.util.net.SSLHostConfig;
 import org.apache.tomcat.util.net.SSLHostConfig.CertificateVerification;
@@ -62,9 +61,6 @@ import org.apache.tomcat.util.res.StringManager;
 public class OpenSSLContext implements org.apache.tomcat.util.net.SSLContext {
 
 private static final Log log = LogFactory.getLog(OpenSSLContext.class);
-
-// Note: this uses the main "net" package strings as many are common with 
APR
-private static final StringManager netSm = 
StringManager.getManager(AbstractEndpoint.class);
 private static final StringManager sm = 
StringManager.getManager(OpenSSLContext.class);
 
 private static final String defaultProtocol = "TLS";
@@ -144,8 +140,7 @@ public class OpenSSLContext implements 
org.apache.tomcat.util.net.SSLContext {
 } else {
 // Should not happen since filtering to build
 // enabled protocols removes invalid values.
-throw new Exception(netSm.getString(
-"endpoint.apr.invalidSslProtocol", protocol));
+throw new 
Exception(sm.getString("openssl.invalidSslProtocol", protocol));
 }
 }
 
@@ -156,8 +151,7 @@ public class OpenSSLContext implements 
org.apache.tomcat.util.net.SSLContext {
 // If the sslEngine is disabled on the AprLifecycleListener
 // there will be an Exception here but there is no way to check
 // the AprLifecycleListener settings from here
-throw new Exception(
-netSm.getString("endpoint.apr.failSslContextMake"), e);
+throw new 
Exception(sm.getString("openssl.failSslContextMake"), e);
 }
 
 this.negotiableProtocols = negotiableProtocols;


-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



(tomcat) branch 10.1.x updated: Further improvements to asynchronous error handling.

2024-01-24 Thread markt
This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 10.1.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/10.1.x by this push:
 new 9873b0bbb9 Further improvements to asynchronous error handling.
9873b0bbb9 is described below

commit 9873b0bbb95eb76da094f34ee70c3c80f71edcdb
Author: Mark Thomas 
AuthorDate: Wed Jan 24 20:47:21 2024 +

Further improvements to asynchronous error handling.

Ensure that application threads cannot access the AsyncContext once the
call to AsyncListener.onError() has returned to the container. This
protects against various race conditions.
---
 java/org/apache/catalina/core/AsyncContextImpl.java   | 19 ---
 java/org/apache/catalina/core/LocalStrings.properties |  1 +
 webapps/docs/changelog.xml|  7 +++
 3 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/java/org/apache/catalina/core/AsyncContextImpl.java 
b/java/org/apache/catalina/core/AsyncContextImpl.java
index e77203ad21..b713f71f10 100644
--- a/java/org/apache/catalina/core/AsyncContextImpl.java
+++ b/java/org/apache/catalina/core/AsyncContextImpl.java
@@ -74,7 +74,8 @@ public class AsyncContextImpl implements AsyncContext, 
AsyncContextCallback {
 private long timeout = -1;
 private AsyncEvent event = null;
 private volatile Request request;
-private final AtomicBoolean hasProcessedError = new AtomicBoolean(false);
+private final AtomicBoolean hasErrorProcessingStarted = new 
AtomicBoolean(false);
+private final AtomicBoolean hasOnErrorReturned = new AtomicBoolean(false);
 
 public AsyncContextImpl(Request request) {
 if (log.isDebugEnabled()) {
@@ -281,7 +282,8 @@ public class AsyncContextImpl implements AsyncContext, 
AsyncContextCallback {
 request = null;
 clearServletRequestResponse();
 timeout = -1;
-hasProcessedError.set(false);
+hasErrorProcessingStarted.set(false);
+hasOnErrorReturned.set(false);
 }
 
 private void clearServletRequestResponse() {
@@ -380,7 +382,7 @@ public class AsyncContextImpl implements AsyncContext, 
AsyncContextCallback {
 
 
 public void setErrorState(Throwable t, boolean fireOnError) {
-if (!hasProcessedError.compareAndSet(false, true)) {
+if (!hasErrorProcessingStarted.compareAndSet(false, true)) {
 // Skip duplicate error processing
 return;
 }
@@ -402,6 +404,8 @@ public class AsyncContextImpl implements AsyncContext, 
AsyncContextCallback {
 } catch (Throwable t2) {
 ExceptionUtils.handleThrowable(t2);
 log.warn(sm.getString("asyncContextImpl.onErrorError", 
listener.getClass().getName()), t2);
+} finally {
+hasOnErrorReturned.set(true);
 }
 }
 }
@@ -501,10 +505,19 @@ public class AsyncContextImpl implements AsyncContext, 
AsyncContextCallback {
 }
 
 private void check() {
+Request request = this.request;
 if (request == null) {
 // AsyncContext has been recycled and should not be being used
 throw new 
IllegalStateException(sm.getString("asyncContextImpl.requestEnded"));
 }
+if (hasOnErrorReturned.get() && 
!request.getCoyoteRequest().isRequestThread()) {
+/*
+ * Non-container thread is trying to use the AsyncContext after an 
error has occurred and the call to
+ * AsyncListener.onError() has returned. At this point, the 
non-container thread should not be trying to use
+ * the AsyncContext due to possible race conditions.
+ */
+throw new 
IllegalStateException(sm.getString("asyncContextImpl.afterOnError"));
+}
 }
 
 private static class DebugException extends Exception {
diff --git a/java/org/apache/catalina/core/LocalStrings.properties 
b/java/org/apache/catalina/core/LocalStrings.properties
index a43dfd9f25..ec1126d4bf 100644
--- a/java/org/apache/catalina/core/LocalStrings.properties
+++ b/java/org/apache/catalina/core/LocalStrings.properties
@@ -93,6 +93,7 @@ aprListener.tooLateForSSLRandomSeed=Cannot setSSLRandomSeed: 
SSL has already bee
 aprListener.usingFIPSProvider=Using OpenSSL with the FIPS provider as the 
default provider
 aprListener.wrongFIPSMode=Unexpected value of FIPSMode option of 
AprLifecycleListener: [{0}]
 
+asyncContextImpl.afterOnError=A non-container (application) thread attempted 
to use the AsyncContext after an error had occurred and the call to 
AsyncListener.onError() had returned. This is not allowed to avoid race 
conditions.
 asyncContextImpl.asyncDispatchError=Error during asynchronous dispatch
 asyncContextImpl.asyncRunnableError=Error during processing of asynchronous 
Runnable via AsyncContext.start()
 asyncContextImpl.dispatchingStar

(tomcat) branch main updated: Further improvements to asynchronous error handling.

2024-01-24 Thread markt
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


The following commit(s) were added to refs/heads/main by this push:
 new 591fe624d2 Further improvements to asynchronous error handling.
591fe624d2 is described below

commit 591fe624d2f5e26355475c2f32c2ad67d297c364
Author: Mark Thomas 
AuthorDate: Wed Jan 24 20:47:21 2024 +

Further improvements to asynchronous error handling.

Ensure that application threads cannot access the AsyncContext once the
call to AsyncListener.onError() has returned to the container. This
protects against various race conditions.
---
 java/org/apache/catalina/core/AsyncContextImpl.java   | 19 ---
 java/org/apache/catalina/core/LocalStrings.properties |  1 +
 webapps/docs/changelog.xml|  7 +++
 3 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/java/org/apache/catalina/core/AsyncContextImpl.java 
b/java/org/apache/catalina/core/AsyncContextImpl.java
index 626fb36c2c..ae41532aca 100644
--- a/java/org/apache/catalina/core/AsyncContextImpl.java
+++ b/java/org/apache/catalina/core/AsyncContextImpl.java
@@ -73,7 +73,8 @@ public class AsyncContextImpl implements AsyncContext, 
AsyncContextCallback {
 private long timeout = -1;
 private AsyncEvent event = null;
 private volatile Request request;
-private final AtomicBoolean hasProcessedError = new AtomicBoolean(false);
+private final AtomicBoolean hasErrorProcessingStarted = new 
AtomicBoolean(false);
+private final AtomicBoolean hasOnErrorReturned = new AtomicBoolean(false);
 
 public AsyncContextImpl(Request request) {
 if (log.isDebugEnabled()) {
@@ -280,7 +281,8 @@ public class AsyncContextImpl implements AsyncContext, 
AsyncContextCallback {
 request = null;
 clearServletRequestResponse();
 timeout = -1;
-hasProcessedError.set(false);
+hasErrorProcessingStarted.set(false);
+hasOnErrorReturned.set(false);
 }
 
 private void clearServletRequestResponse() {
@@ -379,7 +381,7 @@ public class AsyncContextImpl implements AsyncContext, 
AsyncContextCallback {
 
 
 public void setErrorState(Throwable t, boolean fireOnError) {
-if (!hasProcessedError.compareAndSet(false, true)) {
+if (!hasErrorProcessingStarted.compareAndSet(false, true)) {
 // Skip duplicate error processing
 return;
 }
@@ -401,6 +403,8 @@ public class AsyncContextImpl implements AsyncContext, 
AsyncContextCallback {
 } catch (Throwable t2) {
 ExceptionUtils.handleThrowable(t2);
 log.warn(sm.getString("asyncContextImpl.onErrorError", 
listener.getClass().getName()), t2);
+} finally {
+hasOnErrorReturned.set(true);
 }
 }
 }
@@ -500,10 +504,19 @@ public class AsyncContextImpl implements AsyncContext, 
AsyncContextCallback {
 }
 
 private void check() {
+Request request = this.request;
 if (request == null) {
 // AsyncContext has been recycled and should not be being used
 throw new 
IllegalStateException(sm.getString("asyncContextImpl.requestEnded"));
 }
+if (hasOnErrorReturned.get() && 
!request.getCoyoteRequest().isRequestThread()) {
+/*
+ * Non-container thread is trying to use the AsyncContext after an 
error has occurred and the call to
+ * AsyncListener.onError() has returned. At this point, the 
non-container thread should not be trying to use
+ * the AsyncContext due to possible race conditions.
+ */
+throw new 
IllegalStateException(sm.getString("asyncContextImpl.afterOnError"));
+}
 }
 
 private static class DebugException extends Exception {
diff --git a/java/org/apache/catalina/core/LocalStrings.properties 
b/java/org/apache/catalina/core/LocalStrings.properties
index d65120a9fa..e323b57b37 100644
--- a/java/org/apache/catalina/core/LocalStrings.properties
+++ b/java/org/apache/catalina/core/LocalStrings.properties
@@ -90,6 +90,7 @@ aprListener.tooLateForSSLRandomSeed=Cannot setSSLRandomSeed: 
SSL has already bee
 aprListener.usingFIPSProvider=Using OpenSSL with the FIPS provider as the 
default provider
 aprListener.wrongFIPSMode=Unexpected value of FIPSMode option of 
AprLifecycleListener: [{0}]
 
+asyncContextImpl.afterOnError=A non-container (application) thread attempted 
to use the AsyncContext after an error had occurred and the call to 
AsyncListener.onError() had returned. This is not allowed to avoid race 
conditions.
 asyncContextImpl.asyncDispatchError=Error during asynchronous dispatch
 asyncContextImpl.asyncRunnableError=Error during processing of asynchronous 
Runnable via AsyncContext.start()
 asyncContextImpl.dispatchingStarted=

(tomcat) branch 9.0.x updated: Further improvements to asynchronous error handling.

2024-01-24 Thread markt
This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/9.0.x by this push:
 new 1035ff1b7a Further improvements to asynchronous error handling.
1035ff1b7a is described below

commit 1035ff1b7ae5709cd65f1f4ad00ff2878db58d10
Author: Mark Thomas 
AuthorDate: Wed Jan 24 20:47:21 2024 +

Further improvements to asynchronous error handling.

Ensure that application threads cannot access the AsyncContext once the
call to AsyncListener.onError() has returned to the container. This
protects against various race conditions.
---
 java/org/apache/catalina/core/AsyncContextImpl.java   | 19 ---
 java/org/apache/catalina/core/LocalStrings.properties |  1 +
 webapps/docs/changelog.xml|  7 +++
 3 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/java/org/apache/catalina/core/AsyncContextImpl.java 
b/java/org/apache/catalina/core/AsyncContextImpl.java
index ebf71f008d..621053a09c 100644
--- a/java/org/apache/catalina/core/AsyncContextImpl.java
+++ b/java/org/apache/catalina/core/AsyncContextImpl.java
@@ -73,7 +73,8 @@ public class AsyncContextImpl implements AsyncContext, 
AsyncContextCallback {
 private long timeout = -1;
 private AsyncEvent event = null;
 private volatile Request request;
-private final AtomicBoolean hasProcessedError = new AtomicBoolean(false);
+private final AtomicBoolean hasErrorProcessingStarted = new 
AtomicBoolean(false);
+private final AtomicBoolean hasOnErrorReturned = new AtomicBoolean(false);
 
 public AsyncContextImpl(Request request) {
 if (log.isDebugEnabled()) {
@@ -280,7 +281,8 @@ public class AsyncContextImpl implements AsyncContext, 
AsyncContextCallback {
 request = null;
 clearServletRequestResponse();
 timeout = -1;
-hasProcessedError.set(false);
+hasErrorProcessingStarted.set(false);
+hasOnErrorReturned.set(false);
 }
 
 private void clearServletRequestResponse() {
@@ -379,7 +381,7 @@ public class AsyncContextImpl implements AsyncContext, 
AsyncContextCallback {
 
 
 public void setErrorState(Throwable t, boolean fireOnError) {
-if (!hasProcessedError.compareAndSet(false, true)) {
+if (!hasErrorProcessingStarted.compareAndSet(false, true)) {
 // Skip duplicate error processing
 return;
 }
@@ -401,6 +403,8 @@ public class AsyncContextImpl implements AsyncContext, 
AsyncContextCallback {
 } catch (Throwable t2) {
 ExceptionUtils.handleThrowable(t2);
 log.warn(sm.getString("asyncContextImpl.onErrorError", 
listener.getClass().getName()), t2);
+} finally {
+hasOnErrorReturned.set(true);
 }
 }
 }
@@ -500,10 +504,19 @@ public class AsyncContextImpl implements AsyncContext, 
AsyncContextCallback {
 }
 
 private void check() {
+Request request = this.request;
 if (request == null) {
 // AsyncContext has been recycled and should not be being used
 throw new 
IllegalStateException(sm.getString("asyncContextImpl.requestEnded"));
 }
+if (hasOnErrorReturned.get() && 
!request.getCoyoteRequest().isRequestThread()) {
+/*
+ * Non-container thread is trying to use the AsyncContext after an 
error has occurred and the call to
+ * AsyncListener.onError() has returned. At this point, the 
non-container thread should not be trying to use
+ * the AsyncContext due to possible race conditions.
+ */
+throw new 
IllegalStateException(sm.getString("asyncContextImpl.afterOnError"));
+}
 }
 
 private static class DebugException extends Exception {
diff --git a/java/org/apache/catalina/core/LocalStrings.properties 
b/java/org/apache/catalina/core/LocalStrings.properties
index 0430811c3f..9eea586608 100644
--- a/java/org/apache/catalina/core/LocalStrings.properties
+++ b/java/org/apache/catalina/core/LocalStrings.properties
@@ -95,6 +95,7 @@ aprListener.tooLateForSSLRandomSeed=Cannot setSSLRandomSeed: 
SSL has already bee
 aprListener.usingFIPSProvider=Using OpenSSL with the FIPS provider as the 
default provider
 aprListener.wrongFIPSMode=Unexpected value of FIPSMode option of 
AprLifecycleListener: [{0}]
 
+asyncContextImpl.afterOnError=A non-container (application) thread attempted 
to use the AsyncContext after an error had occurred and the call to 
AsyncListener.onError() had returned. This is not allowed to avoid race 
conditions.
 asyncContextImpl.asyncDispatchError=Error during asynchronous dispatch
 asyncContextImpl.asyncRunnableError=Error during processing of asynchronous 
Runnable via AsyncContext.start()
 asyncContextImpl.dispatchingStarte

(tomcat) branch 8.5.x updated: Further improvements to asynchronous error handling.

2024-01-24 Thread markt
This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 8.5.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/8.5.x by this push:
 new f07875c1fb Further improvements to asynchronous error handling.
f07875c1fb is described below

commit f07875c1fbf63b7130f6bf3775f6b51d568c8d78
Author: Mark Thomas 
AuthorDate: Wed Jan 24 20:47:21 2024 +

Further improvements to asynchronous error handling.

Ensure that application threads cannot access the AsyncContext once the
call to AsyncListener.onError() has returned to the container. This
protects against various race conditions.
---
 java/org/apache/catalina/core/AsyncContextImpl.java   | 19 ---
 java/org/apache/catalina/core/LocalStrings.properties |  1 +
 webapps/docs/changelog.xml|  7 +++
 3 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/java/org/apache/catalina/core/AsyncContextImpl.java 
b/java/org/apache/catalina/core/AsyncContextImpl.java
index 0f1b3694de..aea694a57d 100644
--- a/java/org/apache/catalina/core/AsyncContextImpl.java
+++ b/java/org/apache/catalina/core/AsyncContextImpl.java
@@ -73,7 +73,8 @@ public class AsyncContextImpl implements AsyncContext, 
AsyncContextCallback {
 private long timeout = -1;
 private AsyncEvent event = null;
 private volatile Request request;
-private final AtomicBoolean hasProcessedError = new AtomicBoolean(false);
+private final AtomicBoolean hasErrorProcessingStarted = new 
AtomicBoolean(false);
+private final AtomicBoolean hasOnErrorReturned = new AtomicBoolean(false);
 
 public AsyncContextImpl(Request request) {
 if (log.isDebugEnabled()) {
@@ -280,7 +281,8 @@ public class AsyncContextImpl implements AsyncContext, 
AsyncContextCallback {
 request = null;
 clearServletRequestResponse();
 timeout = -1;
-hasProcessedError.set(false);
+hasErrorProcessingStarted.set(false);
+hasOnErrorReturned.set(false);
 }
 
 private void clearServletRequestResponse() {
@@ -379,7 +381,7 @@ public class AsyncContextImpl implements AsyncContext, 
AsyncContextCallback {
 
 
 public void setErrorState(Throwable t, boolean fireOnError) {
-if (!hasProcessedError.compareAndSet(false, true)) {
+if (!hasErrorProcessingStarted.compareAndSet(false, true)) {
 // Skip duplicate error processing
 return;
 }
@@ -401,6 +403,8 @@ public class AsyncContextImpl implements AsyncContext, 
AsyncContextCallback {
 } catch (Throwable t2) {
 ExceptionUtils.handleThrowable(t2);
 log.warn(sm.getString("asyncContextImpl.onErrorError", 
listener.getClass().getName()), t2);
+} finally {
+hasOnErrorReturned.set(true);
 }
 }
 }
@@ -500,10 +504,19 @@ public class AsyncContextImpl implements AsyncContext, 
AsyncContextCallback {
 }
 
 private void check() {
+Request request = this.request;
 if (request == null) {
 // AsyncContext has been recycled and should not be being used
 throw new 
IllegalStateException(sm.getString("asyncContextImpl.requestEnded"));
 }
+if (hasOnErrorReturned.get() && 
!request.getCoyoteRequest().isRequestThread()) {
+/*
+ * Non-container thread is trying to use the AsyncContext after an 
error has occurred and the call to
+ * AsyncListener.onError() has returned. At this point, the 
non-container thread should not be trying to use
+ * the AsyncContext due to possible race conditions.
+ */
+throw new 
IllegalStateException(sm.getString("asyncContextImpl.afterOnError"));
+}
 }
 
 private static class DebugException extends Exception {
diff --git a/java/org/apache/catalina/core/LocalStrings.properties 
b/java/org/apache/catalina/core/LocalStrings.properties
index af25085a27..9448e44378 100644
--- a/java/org/apache/catalina/core/LocalStrings.properties
+++ b/java/org/apache/catalina/core/LocalStrings.properties
@@ -96,6 +96,7 @@ aprListener.tooLateForSSLRandomSeed=Cannot setSSLRandomSeed: 
SSL has already bee
 aprListener.usingFIPSProvider=Using OpenSSL with the FIPS provider as the 
default provider
 aprListener.wrongFIPSMode=Unexpected value of FIPSMode option of 
AprLifecycleListener: [{0}]
 
+asyncContextImpl.afterOnError=A non-container (application) thread attempted 
to use the AsyncContext after an error had occurred and the call to 
AsyncListener.onError() had returned. This is not allowed to avoid race 
conditions.
 asyncContextImpl.asyncDispatchError=Error during asynchronous dispatch
 asyncContextImpl.asyncRunnableError=Error during processing of asynchronous 
Runnable via AsyncContext.start()
 asyncContextImpl.dispatchingStarte