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 fd755dc2f7 Review "Fix TIME_MON and TIME_WDAY values in the rewrite
valve"
fd755dc2f7 is described below
commit fd755dc2f701ada6b133622715a887354a662354
Author: Mark Thomas <[email protected]>
AuthorDate: Thu Oct 29 17:28:25 2026 +0000
Review "Fix TIME_MON and TIME_WDAY values in the rewrite valve"
Further align behaviour with mod_rewrite
- zero pad time components where required
- user correct time format
---
.../catalina/valves/rewrite/ResolverImpl.java | 25 ++++++++++++++++------
.../catalina/valves/rewrite/TestRewriteValve.java | 20 +++++++++++++++--
webapps/docs/changelog.xml | 8 +++++++
3 files changed, 44 insertions(+), 9 deletions(-)
diff --git a/java/org/apache/catalina/valves/rewrite/ResolverImpl.java
b/java/org/apache/catalina/valves/rewrite/ResolverImpl.java
index f846d25f18..cf4658b6f1 100644
--- a/java/org/apache/catalina/valves/rewrite/ResolverImpl.java
+++ b/java/org/apache/catalina/valves/rewrite/ResolverImpl.java
@@ -22,6 +22,8 @@ import java.nio.charset.Charset;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateParsingException;
import java.security.cert.X509Certificate;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
@@ -35,7 +37,6 @@ import org.apache.catalina.WebResourceRoot;
import org.apache.catalina.connector.Request;
import org.apache.juli.logging.Log;
import org.apache.tomcat.util.compat.JreCompat;
-import org.apache.tomcat.util.http.FastHttpDateFormat;
import org.apache.tomcat.util.http.RequestUtil;
import org.apache.tomcat.util.net.SSLSupport;
import org.apache.tomcat.util.net.jsse.PEMFile;
@@ -51,6 +52,11 @@ public class ResolverImpl extends Resolver {
private static final StringManager sm =
StringManager.getManager(ResolverImpl.class);
+ /**
+ * Format of the TIME variable, as used by mod_rewrite.
+ */
+ private static final DateTimeFormatter TIME_FORMAT =
DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
+
/**
* The request being processed.
*/
@@ -165,19 +171,19 @@ public class ResolverImpl extends Resolver {
} else if (key.equals("TIME_MON")) {
// Like mod_rewrite, TIME_MON is 1-12 and TIME_WDAY is 0-6 with
Sunday first,
// unlike the zero-based Calendar.MONTH and one-based Sunday-first
Calendar.DAY_OF_WEEK
- return String.valueOf(Calendar.getInstance().get(Calendar.MONTH) +
1);
+ return twoDigits(Calendar.getInstance().get(Calendar.MONTH) + 1);
} else if (key.equals("TIME_DAY")) {
- return
String.valueOf(Calendar.getInstance().get(Calendar.DAY_OF_MONTH));
+ return
twoDigits(Calendar.getInstance().get(Calendar.DAY_OF_MONTH));
} else if (key.equals("TIME_HOUR")) {
- return
String.valueOf(Calendar.getInstance().get(Calendar.HOUR_OF_DAY));
+ return twoDigits(Calendar.getInstance().get(Calendar.HOUR_OF_DAY));
} else if (key.equals("TIME_MIN")) {
- return String.valueOf(Calendar.getInstance().get(Calendar.MINUTE));
+ return twoDigits(Calendar.getInstance().get(Calendar.MINUTE));
} else if (key.equals("TIME_SEC")) {
- return String.valueOf(Calendar.getInstance().get(Calendar.SECOND));
+ return twoDigits(Calendar.getInstance().get(Calendar.SECOND));
} else if (key.equals("TIME_WDAY")) {
return
String.valueOf(Calendar.getInstance().get(Calendar.DAY_OF_WEEK) - 1);
} else if (key.equals("TIME")) {
- return FastHttpDateFormat.getCurrentDate();
+ return TIME_FORMAT.format(LocalDateTime.now());
}
return null;
}
@@ -462,6 +468,11 @@ public class ResolverImpl extends Resolver {
}
}
+ private static String twoDigits(int value) {
+ return value < 10 ? "0" + value : String.valueOf(value);
+ }
+
+
private static String emptyStringIfNull(String value) {
if (value == null) {
return "";
diff --git a/test/org/apache/catalina/valves/rewrite/TestRewriteValve.java
b/test/org/apache/catalina/valves/rewrite/TestRewriteValve.java
index 06de70aa02..9d4ba54276 100644
--- a/test/org/apache/catalina/valves/rewrite/TestRewriteValve.java
+++ b/test/org/apache/catalina/valves/rewrite/TestRewriteValve.java
@@ -344,9 +344,9 @@ public class TestRewriteValve extends TomcatBaseTest {
@Test
public void testRewriteTimeMonModRewriteNumbering() throws Exception {
- // mod_rewrite numbering: 1-12; two tokens in one rule also cover
+ // mod_rewrite numbering: 01-12; two tokens in one rule also cover
// concatenation parsing
- String expected = String.valueOf(LocalDate.now().getMonthValue());
+ String expected = String.format("%02d",
Integer.valueOf(LocalDate.now().getMonthValue()));
doTestRewrite("RewriteRule ^/c/x$ -
[E=X-Test:%{TIME_MON}-%{TIME_MON}]",
"/c/x", "/c/x", null, expected + "-" + expected);
}
@@ -360,6 +360,22 @@ public class TestRewriteValve extends TomcatBaseTest {
"/c/x", "/c/x", null, expected + "TUE" + expected);
}
+ @Test
+ public void testRewriteTimeValuesModRewriteFormat() throws Exception {
+ // The time values are zero padded to two digits (the year and the
+ // weekday are not) and TIME is yyyyMMddHHmmss. Matching the format
+ // rather than a value keeps the test independent of the clock.
+ doTestRewrite("RewriteCond %{TIME_YEAR} ^[0-9]{4}$\n" +
+ "RewriteCond %{TIME_MON} ^(0[1-9]|1[0-2])$\n" +
+ "RewriteCond %{TIME_DAY} ^(0[1-9]|[12][0-9]|3[01])$\n" +
+ "RewriteCond %{TIME_HOUR} ^([01][0-9]|2[0-3])$\n" +
+ "RewriteCond %{TIME_MIN} ^[0-5][0-9]$\n" +
+ "RewriteCond %{TIME_SEC} ^[0-5][0-9]$\n" +
+ "RewriteCond %{TIME_WDAY} ^[0-6]$\n" +
+ "RewriteCond %{TIME} ^[0-9]{14}$\n" +
+ "RewriteRule ^/c/x$ /c/ok", "/c/x", "/c/ok");
+ }
+
@Test
public void testRemoteIdentIsNotTheRemoteUser() throws Exception {
// REMOTE_IDENT is the RFC 931 ident protocol user name, which Tomcat
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index b0ba3a249a..4c0a7ff69f 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -285,6 +285,14 @@
Ensure that requests cannot try to start asynchronous processing and
the
HTTP upgrade process on the same request. (markt)
</fix>
+ <fix>
+ Align the format of the <code>TIME_MON</code>, <code>TIME_DAY</code>,
+ <code>TIME_HOUR</code>, <code>TIME_MIN</code>, <code>TIME_SEC</code>
+ and <code>TIME</code> server variables in the rewrite valve with
+ mod_rewrite. The first five are now zero padded to two digits and
+ <code>TIME</code> is now of the form <code>yyyyMMddHHmmss</code>
+ rather than an HTTP date.
+ </fix>
</changelog>
</subsection>
<subsection name="Coyote">
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]