This is an automated email from the ASF dual-hosted git repository.
markt-asf 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 519e35f909 Improve AsyncContext.dispatch() when dispatchersUseEncodedPaths=false
519e35f909 is described below
commit 519e35f9093fe2eecc3e7c64c88242ca8dbb2eff
Author: Mark Thomas <[email protected]>
AuthorDate: Thu Aug 13 10:37:18 2026 +0100
Improve AsyncContext.dispatch() when dispatchersUseEncodedPaths=false
---
.../apache/catalina/core/ApplicationContext.java | 7 +++++--
java/org/apache/catalina/core/AsyncContextImpl.java | 21 +++++++++++++++++----
webapps/docs/changelog.xml | 12 ++++++++++++
3 files changed, 34 insertions(+), 6 deletions(-)
diff --git a/java/org/apache/catalina/core/ApplicationContext.java b/java/org/apache/catalina/core/ApplicationContext.java
index 046a77757e..0dc4abb49f 100644
--- a/java/org/apache/catalina/core/ApplicationContext.java
+++ b/java/org/apache/catalina/core/ApplicationContext.java
@@ -400,8 +400,11 @@ public class ApplicationContext implements ServletContext {
// Remove path parameters
String uriToMap = org.apache.catalina.util.RequestUtil.stripPathParams(uri, null);
+ boolean pathIsEncoded =
+ getContext().getDispatchersUseEncodedPaths() || AsyncContextImpl.uriEncoded.get().booleanValue();
+
// Decode only if the uri derived from the provided path is expected to be encoded
- if (getContext().getDispatchersUseEncodedPaths()) {
+ if (pathIsEncoded) {
uriToMap = UDecoder.URLDecode(uriToMap, StandardCharsets.UTF_8, context.getEncodedSolidusHandlingEnum(),
context.getEncodedReverseSolidusHandlingEnum());
}
@@ -419,7 +422,7 @@ public class ApplicationContext implements ServletContext {
* getRequestURI() which returns encoded values. getContextPath() returns a decoded value. uri may be encoded or
* not. Need to prepend the context path to uri and ensure the result is correctly encoded.
*/
- if (getContext().getDispatchersUseEncodedPaths()) {
+ if (pathIsEncoded) {
uri = URLEncoder.DEFAULT.encode(getContextPath(), StandardCharsets.UTF_8) + uri;
} else {
uri = URLEncoder.DEFAULT.encode(getContextPath() + uri, StandardCharsets.UTF_8);
diff --git a/java/org/apache/catalina/core/AsyncContextImpl.java b/java/org/apache/catalina/core/AsyncContextImpl.java
index ce392c5bae..93da1ca0c7 100644
--- a/java/org/apache/catalina/core/AsyncContextImpl.java
+++ b/java/org/apache/catalina/core/AsyncContextImpl.java
@@ -127,6 +127,10 @@ public class AsyncContextImpl implements AsyncContext, AsyncContextCallback {
private final AtomicBoolean hasErrorProcessingStarted = new AtomicBoolean(false);
private final AtomicBoolean hasOnErrorReturned = new AtomicBoolean(false);
+ /*
+ * ThreadLocal for passing over-ridden URL encoding state when dispatching.
+ */
+ static ThreadLocal<Boolean> uriEncoded = ThreadLocal.withInitial(() -> Boolean.FALSE);
/**
* Constructs an AsyncContextImpl for the given request.
@@ -218,7 +222,6 @@ public class AsyncContextImpl implements AsyncContext, AsyncContextCallback {
String path;
String cpath;
Request request = this.request;
- Context context = this.context;
// Calls check() so local copies are validated
ServletRequest servletRequest = getRequest();
if (servletRequest instanceof HttpServletRequest) {
@@ -232,10 +235,20 @@ public class AsyncContextImpl implements AsyncContext, AsyncContextCallback {
if (cpath.length() > 1) {
path = path.substring(cpath.length());
}
- if (!context.getDispatchersUseEncodedPaths()) {
- path = UDecoder.URLDecode(path, StandardCharsets.UTF_8);
+ /*
+ * This is a dispatch of the original request path. That path will always be URI-decoded. That will cause
+ * problems in ServletContext.getRequestDispatcher() if the decoded URI contains a literal '?' as it will be
+ * treated as a query delimiter. Therefore, ignore context.getDispatchersUseEncodedPaths() here and always
+ * encode. Also need to mark this request as ignoring context.getDispatchersUseEncodedPaths() so it is handled
+ * correctly in ServletContext.getRequestDispatcher().
+ */
+ path = UDecoder.URLDecode(path, StandardCharsets.UTF_8);
+ try {
+ uriEncoded.set(Boolean.TRUE);
+ dispatch(path);
+ } finally {
+ uriEncoded.set(Boolean.FALSE);
}
- dispatch(path);
}
@Override
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index f83534d888..0b173c1737 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -108,6 +108,18 @@
issues do not "pop up" wrt. others).
-->
<section name="Tomcat 9.0.122 (remm)" rtext="in development">
+ <subsection name="Catalina">
+ <changelog>
+ <fix>
+ Improve the handling of <code>AsyncContext.dispatch()</code> when the
+ <code>Context</code> attribute <code>dispatchersUseEncodedPaths</code>
+ is set to <code>false</code> since the application has no control over
+ the path used for the <code>AsyncContext.dispatch()</code>. Prior to
+ this fix, paths containing literal <code>'?'</code> characters were
+ truncated. (markt)
+ </fix>
+ </changelog>
+ </subsection>
<subsection name="Coyote">
<changelog>
<fix>
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.