This is an automated email from the ASF dual-hosted git repository.
markt-asf pushed a commit to branch 11.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/11.0.x by this push:
new d57aaacb4a Improve AsyncContext.dispatch() when dispatchersUseEncodedPaths=false
d57aaacb4a is described below
commit d57aaacb4a80f94ac10af457176c6a8958a370db
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 28363b2e44..d499bbe0ab 100644
--- a/java/org/apache/catalina/core/ApplicationContext.java
+++ b/java/org/apache/catalina/core/ApplicationContext.java
@@ -372,8 +372,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());
}
@@ -391,7 +394,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 afa148e861..2e8f1ccc6a 100644
--- a/java/org/apache/catalina/core/AsyncContextImpl.java
+++ b/java/org/apache/catalina/core/AsyncContextImpl.java
@@ -128,6 +128,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.
@@ -219,7 +223,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 sr) {
@@ -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 e8720d622d..841c6caf32 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 11.0.26 (markt)" 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.