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 f4374b3be3 Process path parameters rewrite production
f4374b3be3 is described below
commit f4374b3be3f986870286160e2bcfd16cc2e69b65
Author: remm <[email protected]>
AuthorDate: Thu Apr 3 21:27:35 2025 +0200
Process path parameters rewrite production
---
java/org/apache/catalina/connector/Request.java | 4 +-
.../apache/catalina/core/ApplicationContext.java | 30 +-------------
java/org/apache/catalina/util/RequestUtil.java | 46 ++++++++++++++++++++++
.../catalina/valves/rewrite/RewriteValve.java | 4 ++
.../TestApplicationContextStripPathParams.java | 44 ++++++++++++++-------
webapps/docs/changelog.xml | 4 ++
6 files changed, 86 insertions(+), 46 deletions(-)
diff --git a/java/org/apache/catalina/connector/Request.java
b/java/org/apache/catalina/connector/Request.java
index a2c1808466..ef9345ba4f 100644
--- a/java/org/apache/catalina/connector/Request.java
+++ b/java/org/apache/catalina/connector/Request.java
@@ -422,11 +422,11 @@ public class Request implements HttpServletRequest {
// --------------------------------------------------------- Public Methods
- protected void addPathParameter(String name, String value) {
+ public void addPathParameter(String name, String value) {
coyoteRequest.addPathParameter(name, value);
}
- protected String getPathParameter(String name) {
+ public String getPathParameter(String name) {
return coyoteRequest.getPathParameter(name);
}
diff --git a/java/org/apache/catalina/core/ApplicationContext.java
b/java/org/apache/catalina/core/ApplicationContext.java
index 612dd3092c..a3375588a7 100644
--- a/java/org/apache/catalina/core/ApplicationContext.java
+++ b/java/org/apache/catalina/core/ApplicationContext.java
@@ -374,7 +374,7 @@ public class ApplicationContext implements ServletContext {
// From this point, the removal of path parameters, decoding and
normalization is only for mapping purposes.
// Remove path parameters
- String uriToMap = stripPathParams(uri);
+ String uriToMap =
org.apache.catalina.util.RequestUtil.stripPathParams(uri, null);
// Decode only if the uri derived from the provided path is expected
to be encoded
if (getContext().getDispatchersUseEncodedPaths()) {
@@ -449,34 +449,6 @@ public class ApplicationContext implements ServletContext {
}
- // Package private to facilitate testing
- static String stripPathParams(String input) {
- // Shortcut
- if (input.indexOf(';') < 0) {
- return input;
- }
-
- StringBuilder sb = new StringBuilder(input.length());
- int pos = 0;
- int limit = input.length();
- while (pos < limit) {
- int nextSemiColon = input.indexOf(';', pos);
- if (nextSemiColon < 0) {
- nextSemiColon = limit;
- }
- sb.append(input, pos, nextSemiColon);
- int followingSlash = input.indexOf('/', nextSemiColon);
- if (followingSlash < 0) {
- pos = limit;
- } else {
- pos = followingSlash;
- }
- }
-
- return sb.toString();
- }
-
-
@Override
public URL getResource(String path) throws MalformedURLException {
diff --git a/java/org/apache/catalina/util/RequestUtil.java
b/java/org/apache/catalina/util/RequestUtil.java
index 85448b7ad1..36f5f072a6 100644
--- a/java/org/apache/catalina/util/RequestUtil.java
+++ b/java/org/apache/catalina/util/RequestUtil.java
@@ -18,6 +18,8 @@ package org.apache.catalina.util;
import jakarta.servlet.http.HttpServletRequest;
+import org.apache.catalina.connector.Request;
+
/**
* General purpose request parsing and encoding utility methods.
*
@@ -54,4 +56,48 @@ public final class RequestUtil {
return url;
}
+
+
+ /**
+ * Strip parameters for given path.
+ * @param input the input path
+ * @param request the request to add the parameters to
+ * @return the cleaned path
+ */
+ public static String stripPathParams(String input, Request request) {
+ // Shortcut
+ if (input.indexOf(';') < 0) {
+ return input;
+ }
+
+ StringBuilder sb = new StringBuilder(input.length());
+ int pos = 0;
+ int limit = input.length();
+ while (pos < limit) {
+ int nextSemiColon = input.indexOf(';', pos);
+ if (nextSemiColon < 0) {
+ nextSemiColon = limit;
+ }
+ sb.append(input, pos, nextSemiColon);
+ int followingSlash = input.indexOf('/', nextSemiColon);
+ if (followingSlash < 0) {
+ pos = limit;
+ } else {
+ pos = followingSlash;
+ }
+ if (request != null && nextSemiColon + 1 <pos) {
+ String pathVariable = input.substring(nextSemiColon + 1, pos);
+ int equals = pathVariable.indexOf('=');
+ if (equals > -1 && equals + 1 < pathVariable.length()) {
+ String name = pathVariable.substring(0, equals);
+ String value = pathVariable.substring(equals + 1);
+ request.addPathParameter(name, value);
+ }
+ }
+ }
+
+ return sb.toString();
+ }
+
+
}
diff --git a/java/org/apache/catalina/valves/rewrite/RewriteValve.java
b/java/org/apache/catalina/valves/rewrite/RewriteValve.java
index 60294fc19a..0b538d3820 100644
--- a/java/org/apache/catalina/valves/rewrite/RewriteValve.java
+++ b/java/org/apache/catalina/valves/rewrite/RewriteValve.java
@@ -527,6 +527,8 @@ public class RewriteValve extends ValveBase {
queryStringRewriteEncoded =
urlStringRewriteEncoded.substring(queryIndex + 1);
urlStringRewriteEncoded =
urlStringRewriteEncoded.substring(0, queryIndex);
}
+ // Parse path parameters from rewrite production and
populate request path parameters
+ urlStringRewriteEncoded =
org.apache.catalina.util.RequestUtil.stripPathParams(urlStringRewriteEncoded,
request);
// Save the current context path before re-writing starts
String contextPath = null;
if (context) {
@@ -870,4 +872,6 @@ public class RewriteValve extends ValveBase {
return input;
}
}
+
+
}
diff --git
a/test/org/apache/catalina/core/TestApplicationContextStripPathParams.java
b/test/org/apache/catalina/core/TestApplicationContextStripPathParams.java
index 2faea49a60..a1a083c660 100644
--- a/test/org/apache/catalina/core/TestApplicationContextStripPathParams.java
+++ b/test/org/apache/catalina/core/TestApplicationContextStripPathParams.java
@@ -25,42 +25,56 @@ import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
+import org.apache.catalina.connector.Request;
import org.apache.catalina.startup.TomcatBaseTest;
+import org.apache.catalina.util.RequestUtil;
@RunWith(value = Parameterized.class)
public class TestApplicationContextStripPathParams extends TomcatBaseTest {
private final String input;
private final String expectedOutput;
+ private final Boolean hasParameter;
- public TestApplicationContextStripPathParams(String input, String
expectedOutput) {
+ public TestApplicationContextStripPathParams(String input, String
expectedOutput, Boolean hasParameter) {
this.input = input;
this.expectedOutput = expectedOutput;
+ this.hasParameter = hasParameter;
}
@Parameters(name = "{index}: input[{0}]")
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][]{
- { "/foo", "/foo"},
- { "/foo/", "/foo/"},
- { "/foo/bar", "/foo/bar"},
- { "/foo;", "/foo"},
- { "/foo;/", "/foo/"},
- { "/foo;/bar", "/foo/bar"},
- { "/foo;a=1", "/foo"},
- { "/foo;a=1/", "/foo/"},
- { "/foo;a=1/bar", "/foo/bar"},
+ { "/foo", "/foo", Boolean.FALSE },
+ { "/foo/", "/foo/", Boolean.FALSE },
+ { "/foo/bar", "/foo/bar", Boolean.FALSE },
+ { "/foo;", "/foo", Boolean.FALSE },
+ { "/foo;/", "/foo/", Boolean.FALSE },
+ { "/foo;/bar", "/foo/bar", Boolean.FALSE },
+ { "/foo;a=1", "/foo", Boolean.TRUE },
+ { "/foo;a=1/", "/foo/", Boolean.TRUE },
+ { "/foo;a=1/bar", "/foo/bar", Boolean.TRUE },
// Arguably not valid but does the right thing anyway
- { ";/foo", "/foo"},
- { ";a=1/foo", "/foo"},
- { ";/foo/bar", "/foo/bar"},
- { ";/foo;a=1/bar", "/foo/bar"},
+ { ";/foo", "/foo", Boolean.FALSE },
+ { ";a=1/foo", "/foo", Boolean.TRUE },
+ { ";/foo/bar", "/foo/bar", Boolean.FALSE },
+ { ";/foo;a=1/bar", "/foo/bar", Boolean.TRUE },
+ { ";/foo;=/bar", "/foo/bar", Boolean.FALSE },
+ { ";/foo;a=/bar", "/foo/bar", Boolean.FALSE },
+ { ";/foo;=1/bar", "/foo/bar", Boolean.FALSE },
});
}
@Test
public void testStringPathParams() {
- String output = ApplicationContext.stripPathParams(input);
+ Request request = new Request(null, new org.apache.coyote.Request());
+ String output = RequestUtil.stripPathParams(input, request);
Assert.assertEquals(expectedOutput, output);
+ String parameter = request.getPathParameter("a");
+ if (hasParameter.booleanValue()) {
+ Assert.assertEquals("1", parameter);
+ } else {
+ Assert.assertNull(parameter);
+ }
}
}
\ No newline at end of file
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index d799ab793d..a046154488 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -157,6 +157,10 @@
rejected by default. (markt)
</update>
<!-- Entries for backport and removal before 12.0.0-M1 below this line
-->
+ <fix>
+ Process possible path parameters rewrite production in the rewrite
+ valve. (remm)
+ </fix>
</changelog>
</subsection>
<subsection name="Coyote">
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]