ttomcat-1778514358873.zip-extract/apache-tomcat-11.0.18-src/java/org/apache/catalina/valves/rewrite/RewriteRule.java

Path
ttomcat-1778514358873.zip-extract/apache-tomcat-11.0.18-src/java/org/apache/catalina/valves/rewrite/RewriteRule.java
Status
scanned
Type
file
Name
RewriteRule.java
Extension
.java
Programming language
Java
Mime type
text/plain
File type
ASCII text, with CRLF line terminators
Tag

      
    
Rootfs path

      
    
Size
19890 (19.4 KB)
MD5
2b86eb7177624d2815d2456906a680e7
SHA1
4f3980ffae5ee2c130959a5fe5dabea7adba9a18
SHA256
77d7c2dbc33c2aa77c8c4a7f5f990e4e3eee9aa870b8b714addf00e47e628d5e
SHA512

      
    
SHA1_git
80939129bd46a3e458ab6325ca9c36c72c60d04e
Is binary

      
    
Is text
True
Is archive

      
    
Is media

      
    
Is legal

      
    
Is manifest

      
    
Is readme

      
    
Is top level

      
    
Is key file

      
    
RewriteRule.java | 19.4 KB |

/* * 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.util.ArrayList; import java.util.Arrays; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; public class RewriteRule { protected RewriteCond[] conditions = new RewriteCond[0]; protected ThreadLocal<Pattern> pattern = new ThreadLocal<>(); protected Substitution substitution = null; protected String patternString = null; protected String substitutionString = null; protected String flagsString = null; protected boolean positive = true; public void parse(Map<String,RewriteMap> maps) { // Parse the substitution if (!"-".equals(substitutionString)) { substitution = new Substitution(); substitution.setSub(substitutionString); substitution.parse(maps); substitution.setEscapeBackReferences(isEscapeBackReferences()); } // Parse the pattern if (patternString.startsWith("!")) { positive = false; patternString = patternString.substring(1); } int flags = Pattern.DOTALL; if (isNocase()) { flags |= Pattern.CASE_INSENSITIVE; } Pattern.compile(patternString, flags); // Parse conditions for (RewriteCond condition : conditions) { condition.parse(maps); } // Parse flag which have substitution values if (isEnv()) { for (String s : envValue) { Substitution newEnvSubstitution = new Substitution(); newEnvSubstitution.setSub(s); newEnvSubstitution.parse(maps); envSubstitution.add(newEnvSubstitution); envResult.add(new ThreadLocal<>()); } } if (isCookie()) { cookieSubstitution = new Substitution(); cookieSubstitution.setSub(cookieValue); cookieSubstitution.parse(maps); } } public void addCondition(RewriteCond condition) { RewriteCond[] conditions = Arrays.copyOf(this.conditions, this.conditions.length + 1); conditions[this.conditions.length] = condition; this.conditions = conditions; } /** * Evaluate the rule based on the context * * @param url The char sequence * @param resolver Property resolver * * @return <code>null</code> if no rewrite took place */ public CharSequence evaluate(CharSequence url, Resolver resolver) { Pattern pattern = this.pattern.get(); if (pattern == null) { // Parse the pattern int flags = Pattern.DOTALL; if (isNocase()) { flags |= Pattern.CASE_INSENSITIVE; } pattern = Pattern.compile(patternString, flags); this.pattern.set(pattern); } Matcher matcher = pattern.matcher(url); // Use XOR if (positive ^ matcher.matches()) { // Evaluation done return null; } // Evaluate conditions boolean done = false; boolean rewrite = true; Matcher lastMatcher = null; int pos = 0; while (!done) { if (pos < conditions.length) { rewrite = conditions[pos].evaluate(matcher, lastMatcher, resolver); if (rewrite) { Matcher lastMatcher2 = conditions[pos].getMatcher(); if (lastMatcher2 != null) { lastMatcher = lastMatcher2; } while (pos < conditions.length && conditions[pos].isOrnext()) { pos++; } } else if (!conditions[pos].isOrnext()) { done = true; } pos++; } else { done = true; } } // Use the substitution to rewrite the url if (rewrite) { if (isEnv()) { for (int i = 0; i < envSubstitution.size(); i++) { envResult.get(i).set(envSubstitution.get(i).evaluate(matcher, lastMatcher, resolver)); } } if (isCookie()) { cookieResult.set(cookieSubstitution.evaluate(matcher, lastMatcher, resolver)); } if (substitution != null) { return substitution.evaluate(matcher, lastMatcher, resolver); } else { return url; } } else { return null; } } /** * String representation. */ @Override public String toString() { return "RewriteRule " + patternString + " " + substitutionString + ((flagsString != null) ? (" " + flagsString) : ""); } private boolean escapeBackReferences = false; /** * This flag chains the current rule with the next rule (which itself can be chained with the following rule, etc.). * This has the following effect: if a rule matches, then processing continues as usual, i.e., the flag has no * effect. If the rule does not match, then all following chained rules are skipped. For instance, use it to remove * the ".www" part inside a per-directory rule set when you let an external redirect happen (where the ".www" part * should not to occur!). */ protected boolean chain = false; /** * This sets a cookie on the client's browser. The cookie's name is specified by NAME and the value is VAL. The * domain field is the domain of the cookie, such as '.apache.org',the optional lifetime is the lifetime of the * cookie in minutes, and the optional path is the path of the cookie */ protected boolean cookie = false; protected String cookieName = null; protected String cookieValue = null; protected String cookieDomain = null; protected int cookieLifetime = -1; protected String cookiePath = null; protected boolean cookieSecure = false; protected boolean cookieHttpOnly = false; protected Substitution cookieSubstitution = null; protected ThreadLocal<String> cookieResult = new ThreadLocal<>(); /** * This forces a request attribute named VAR to be set to the value VAL, where VAL can contain regexp back * references $N and %N which will be expanded. Multiple env flags are allowed. */ protected boolean env = false; protected ArrayList<String> envName = new ArrayList<>(); protected ArrayList<String> envValue = new ArrayList<>(); protected ArrayList<Substitution> envSubstitution = new ArrayList<>(); protected ArrayList<ThreadLocal<String>> envResult = new ArrayList<>(); /** * This forces the current URL to be forbidden, i.e., it immediately sends back an HTTP response of 403 (FORBIDDEN). * Use this flag in conjunction with appropriate RewriteConds to conditionally block some URLs. */ protected boolean forbidden = false; /** * This forces the current URL to be gone, i.e., it immediately sends back an HTTP response of 410 (GONE). Use this * flag to mark pages which no longer exist as gone. */ protected boolean gone = false; /** * Host. This means this rule and its associated conditions will apply to host, allowing host rewriting (ex: * redirecting internally *.foo.com to bar.foo.com). */ protected boolean host = false; /** * Stop the rewriting process here and don't apply any additional rewriting rules. This corresponds to the Perl last * command or the break command from the C language. Use this flag to prevent the currently rewritten URL from being * rewritten further by following rules. For example, use it to rewrite the root-path URL ('/') to a real one, e.g., * '/e/www/'. */ protected boolean last = false; /** * Re-run the rewriting process (starting again with the first rewriting rule). Here the URL to match is again not * the original URL but the URL from the last rewriting rule. This corresponds to the Perl next command or the * continue command from the C language. Use this flag to restart the rewriting process, i.e., to immediately go to * the top of the loop. But be careful not to create an infinite loop! */ protected boolean next = false; /** * This makes the Pattern case-insensitive, i.e., there is no difference between 'A-Z' and 'a-z' when Pattern is * matched against the current URL. */ protected boolean nocase = false; /** * This flag keeps mod_rewrite from applying the usual URI escaping rules to the result of a rewrite. Ordinarily, * special characters (such as '%', '$', ';', and so on) will be escaped into their hexcode equivalents ('%25', * '%24', and '%3B', respectively); this flag prevents this from being done. This allows percent symbols to appear * in the output, as in {@code RewriteRule /foo/(.*) /bar?arg=P1\%3d$1 [R,NE]} which would turn '/foo/zed' into a * safe request for '/bar?arg=P1=zed'. */ protected boolean noescape = false; /** * This flag forces the rewriting engine to skip a rewriting rule if the current request is an internal sub-request. * For instance, sub-requests occur internally in Apache when mod_include tries to find out information about * possible directory default files (index.xxx). On sub-requests it is not always useful and even sometimes causes a * failure to if the complete set of rules are applied. Use this flag to exclude some rules. Use the following rule * for your decision: whenever you prefix some URLs with CGI-scripts to force them to be processed by the * CGI-script, the chance is high that you will run into problems (or even overhead) on sub-requests. In these * cases, use this flag. */ protected boolean nosubreq = false; /* * Note: No proxy */ /* * Note: No passthrough */ /** * This flag forces the rewriting engine to append a query string part in the substitution string to the existing * one instead of replacing it. Use this when you want to add more data to the query string via a rewrite rule. */ protected boolean qsappend = false; /** * When the requested URI contains a query string, and the target URI does not, the default behavior of RewriteRule * is to copy that query string to the target URI. Using the [QSD] flag causes the query string to be discarded. * Using [QSD] and [QSA] together will result in [QSD] taking precedence. */ protected boolean qsdiscard = false; /** * Prefix Substitution with http://thishost[:thisport]/ (which makes the new URL a URI) to force an external * redirection. If no code is given an HTTP response of 302 (FOUND, previously MOVED TEMPORARILY) is used. If you * want to use other response codes in the range 300-399 just specify them as a number or use one of the following * symbolic names: temp (default), permanent, seeother. Use it for rules which should canonicalize the URL and give * it back to the client, e.g., translate "/~" into "/u/" or always append a slash to /u/user, etc. Note: When you * use this flag, make sure that the substitution field is a valid URL! If not, you are redirecting to an invalid * location! And remember that this flag itself only prefixes the URL with http://thishost[:thisport]/, rewriting * continues. Usually you also want to stop and do the redirection immediately. To stop the rewriting you also have * to provide the 'L' flag. */ protected boolean redirect = false; protected int redirectCode = 0; /** * This flag forces the rewriting engine to skip the next num rules in sequence when the current rule matches. Use * this to make pseudo if-then-else constructs: The last rule of the then-clause becomes skip=N where N is the * number of rules in the else-clause. (This is not the same as the 'chain|C' flag!) */ protected int skip = 0; /** * Force the MIME-type of the target file to be MIME-type. For instance, this can be used to set up the content-type * based on some conditions. For example, the following snippet allows .php files to be displayed by mod_php if they * are called with the .phps extension: RewriteRule ^(.+\.php)s$ $1 [T=application/x-httpd-php-source] */ protected boolean type = false; protected String typeValue = null; /** * Allows skipping the next valve in the Catalina pipeline. */ protected boolean valveSkip = false; public boolean isEscapeBackReferences() { return escapeBackReferences; } public void setEscapeBackReferences(boolean escapeBackReferences) { this.escapeBackReferences = escapeBackReferences; } public boolean isChain() { return chain; } public void setChain(boolean chain) { this.chain = chain; } public RewriteCond[] getConditions() { return conditions; } public void setConditions(RewriteCond[] conditions) { this.conditions = conditions; } public boolean isCookie() { return cookie; } public void setCookie(boolean cookie) { this.cookie = cookie; } public String getCookieName() { return cookieName; } public void setCookieName(String cookieName) { this.cookieName = cookieName; } public String getCookieValue() { return cookieValue; } public void setCookieValue(String cookieValue) { this.cookieValue = cookieValue; } public String getCookieResult() { return cookieResult.get(); } public boolean isEnv() { return env; } public int getEnvSize() { return envName.size(); } public void setEnv(boolean env) { this.env = env; } public String getEnvName(int i) { return envName.get(i); } public void addEnvName(String envName) { this.envName.add(envName); } public String getEnvValue(int i) { return envValue.get(i); } public void addEnvValue(String envValue) { this.envValue.add(envValue); } public String getEnvResult(int i) { return envResult.get(i).get(); } public boolean isForbidden() { return forbidden; } public void setForbidden(boolean forbidden) { this.forbidden = forbidden; } public boolean isGone() { return gone; } public void setGone(boolean gone) { this.gone = gone; } public boolean isLast() { return last; } public void setLast(boolean last) { this.last = last; } public boolean isNext() { return next; } public void setNext(boolean next) { this.next = next; } public boolean isNocase() { return nocase; } public void setNocase(boolean nocase) { this.nocase = nocase; } public boolean isNoescape() { return noescape; } public void setNoescape(boolean noescape) { this.noescape = noescape; } public boolean isNosubreq() { return nosubreq; } public void setNosubreq(boolean nosubreq) { this.nosubreq = nosubreq; } public boolean isQsappend() { return qsappend; } public void setQsappend(boolean qsappend) { this.qsappend = qsappend; } public final boolean isQsdiscard() { return qsdiscard; } public final void setQsdiscard(boolean qsdiscard) { this.qsdiscard = qsdiscard; } public boolean isRedirect() { return redirect; } public void setRedirect(boolean redirect) { this.redirect = redirect; } public int getRedirectCode() { return redirectCode; } public void setRedirectCode(int redirectCode) { this.redirectCode = redirectCode; } public int getSkip() { return skip; } public void setSkip(int skip) { this.skip = skip; } public Substitution getSubstitution() { return substitution; } public void setSubstitution(Substitution substitution) { this.substitution = substitution; } public boolean isType() { return type; } public void setType(boolean type) { this.type = type; } public String getTypeValue() { return typeValue; } public void setTypeValue(String typeValue) { this.typeValue = typeValue; } public String getPatternString() { return patternString; } public void setPatternString(String patternString) { this.patternString = patternString; } public String getSubstitutionString() { return substitutionString; } public void setSubstitutionString(String substitutionString) { this.substitutionString = substitutionString; } public final String getFlagsString() { return flagsString; } public final void setFlagsString(String flagsString) { this.flagsString = flagsString; } public boolean isHost() { return host; } public void setHost(boolean host) { this.host = host; } public String getCookieDomain() { return cookieDomain; } public void setCookieDomain(String cookieDomain) { this.cookieDomain = cookieDomain; } public int getCookieLifetime() { return cookieLifetime; } public void setCookieLifetime(int cookieLifetime) { this.cookieLifetime = cookieLifetime; } public String getCookiePath() { return cookiePath; } public void setCookiePath(String cookiePath) { this.cookiePath = cookiePath; } public boolean isCookieSecure() { return cookieSecure; } public void setCookieSecure(boolean cookieSecure) { this.cookieSecure = cookieSecure; } public boolean isCookieHttpOnly() { return cookieHttpOnly; } public void setCookieHttpOnly(boolean cookieHttpOnly) { this.cookieHttpOnly = cookieHttpOnly; } public boolean isValveSkip() { return this.valveSkip; } public void setValveSkip(boolean valveSkip) { this.valveSkip = valveSkip; } }
Detected license expression
apache-2.0
Detected license expression (SPDX)
Apache-2.0
Percentage of license text
5.62
Copyrights

      
    
Holders

      
    
Authors

      
    
License detections License expression License expression SPDX
apache_2_0-4bde3f57-78aa-4201-96bf-531cba09e7de apache-2.0 Apache-2.0
URL Start line End line
http://www.apache.org/licenses/LICENSE-2.0 9 9