This is an automated email from the ASF dual-hosted git repository. remm pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/master by this push: new 0446c5c Add the default internal rewrite maps 0446c5c is described below commit 0446c5c97741344556c519a566db926d660e4b8a Author: remm <r...@apache.org> AuthorDate: Wed May 20 13:22:40 2020 +0200 Add the default internal rewrite maps After looking at the httpd docs, integrate more parts of PR #221 with some additions. --- .../valves/rewrite/InternalRewriteMap.java | 122 +++++++++++++++++++++ .../catalina/valves/rewrite/RewriteValve.java | 18 ++- .../catalina/valves/rewrite/TestRewriteValve.java | 6 + webapps/docs/changelog.xml | 4 + webapps/docs/rewrite.xml | 9 ++ 5 files changed, 154 insertions(+), 5 deletions(-) diff --git a/java/org/apache/catalina/valves/rewrite/InternalRewriteMap.java b/java/org/apache/catalina/valves/rewrite/InternalRewriteMap.java new file mode 100644 index 0000000..b556e4c --- /dev/null +++ b/java/org/apache/catalina/valves/rewrite/InternalRewriteMap.java @@ -0,0 +1,122 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.catalina.valves.rewrite; + +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.Locale; + +import org.apache.catalina.util.URLEncoder; +import org.apache.tomcat.util.buf.UDecoder; + +public class InternalRewriteMap { + + public static RewriteMap toMap(String name) { + if ("toupper".equals(name)) { + return new UpperCase(); + } else if ("tolower".equals(name)) { + return new LowerCase(); + } else if ("escape".equals(name)) { + return new Escape(); + } else if ("unescape".equals(name)) { + return new Unescape(); + } else { + return null; + } + } + + public static class LowerCase implements RewriteMap { + + private Locale locale = Locale.getDefault(); + + @Override + public String setParameters(String params) { + this.locale = Locale.forLanguageTag(params); + return null; + } + + @Override + public String lookup(String key) { + if (key != null) { + return key.toLowerCase(locale); + } + return null; + } + + } + + public static class UpperCase implements RewriteMap { + + private Locale locale = Locale.getDefault(); + + @Override + public String setParameters(String params) { + this.locale = Locale.forLanguageTag(params); + return null; + } + + @Override + public String lookup(String key) { + if (key != null) { + return key.toUpperCase(locale); + } + return null; + } + + } + + public static class Escape implements RewriteMap { + + private Charset charset = StandardCharsets.UTF_8; + + @Override + public String setParameters(String params) { + this.charset = Charset.forName(params); + return null; + } + + @Override + public String lookup(String key) { + if (key != null) { + return URLEncoder.DEFAULT.encode(key, charset); + } + return null; + } + + } + + public static class Unescape implements RewriteMap { + + private Charset charset = StandardCharsets.UTF_8; + + @Override + public String setParameters(String params) { + this.charset = Charset.forName(params); + return null; + } + + @Override + public String lookup(String key) { + if (key != null) { + return UDecoder.URLDecode(key, charset); + } + return null; + } + + } + +} diff --git a/java/org/apache/catalina/valves/rewrite/RewriteValve.java b/java/org/apache/catalina/valves/rewrite/RewriteValve.java index d2c40a6..98ba57a 100644 --- a/java/org/apache/catalina/valves/rewrite/RewriteValve.java +++ b/java/org/apache/catalina/valves/rewrite/RewriteValve.java @@ -617,17 +617,25 @@ public class RewriteValve extends ValveBase { return rule; } else if (token.equals("RewriteMap")) { // RewriteMap name rewriteMapClassName whateverOptionalParameterInWhateverFormat + // FIXME: Possibly implement more special maps from https://httpd.apache.org/docs/2.4/rewrite/rewritemap.html if (tokenizer.countTokens() < 2) { throw new IllegalArgumentException(sm.getString("rewriteValve.invalidLine", line)); } String name = tokenizer.nextToken(); String rewriteMapClassName = tokenizer.nextToken(); RewriteMap map = null; - try { - map = (RewriteMap) (Class.forName( - rewriteMapClassName).getConstructor().newInstance()); - } catch (Exception e) { - throw new IllegalArgumentException(sm.getString("rewriteValve.invalidMapClassName", line)); + if (rewriteMapClassName.startsWith("int:")) { + map = InternalRewriteMap.toMap(rewriteMapClassName.substring("int:".length())); + } else if (rewriteMapClassName.startsWith("prg:")) { + rewriteMapClassName = rewriteMapClassName.substring("prg:".length()); + } + if (map == null) { + try { + map = (RewriteMap) (Class.forName( + rewriteMapClassName).getConstructor().newInstance()); + } catch (Exception e) { + throw new IllegalArgumentException(sm.getString("rewriteValve.invalidMapClassName", line)); + } } if (tokenizer.hasMoreTokens()) { if (tokenizer.countTokens() == 1) { diff --git a/test/org/apache/catalina/valves/rewrite/TestRewriteValve.java b/test/org/apache/catalina/valves/rewrite/TestRewriteValve.java index 4c9a97c..c6e8c26 100644 --- a/test/org/apache/catalina/valves/rewrite/TestRewriteValve.java +++ b/test/org/apache/catalina/valves/rewrite/TestRewriteValve.java @@ -113,6 +113,12 @@ public class TestRewriteValve extends TomcatBaseTest { } @Test + public void testRewriteMap08() throws Exception { + doTestRewrite("RewriteMap lc int:tolower\n" + + "RewriteRule ^(.*) ${lc:$1}", "/C/AaA", "/c/aaa"); + } + + @Test public void testRewriteServerVar() throws Exception { doTestRewrite("RewriteRule /b/(.*).html$ /c%{SERVLET_PATH}", "/b/x.html", "/c/b/x.html"); } diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index bf30ab6..57c981c 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -56,6 +56,10 @@ Fix use of multiple parameters when defining RewriteMaps. (remm/fschumacher) </fix> + <update> + Add the special internal rewrite maps for case modification and + escaping. (remm/fschumacher) + </update> </changelog> </subsection> <subsection name="Coyote"> diff --git a/webapps/docs/rewrite.xml b/webapps/docs/rewrite.xml index 4869b92..c40eb35 100644 --- a/webapps/docs/rewrite.xml +++ b/webapps/docs/rewrite.xml @@ -395,6 +395,15 @@ RewriteRule ^/$ /homepage.std.html [L]</source> <p>Syntax: <code>RewriteMap name rewriteMapClassName optionalParameters</code></p> + <p>The <code>rewriteMapClassName</code> value also allows special values: + <ul> + <li><code>int:toupper</code>: Special map converting passed values to upper case</li> + <li><code>int:tolower</code>: Special map converting passed values to lower case</li> + <li><code>int:escape</code>: URL escape the passed value</li> + <li><code>int:unescape</code>: URL unescape the passed value</li> + </ul> + </p> + <p>The maps are implemented using an interface that users must implement. Its class name is <code>org.apache.catalina.valves.rewrite.RewriteMap</code>, and its code is:</p> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org