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>
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]