📄 rulebase.java
字号:
/**
* Copyright (c) 2005-2007, Paul Tuckey
* All rights reserved.
* ====================================================================
* Licensed under the BSD License. Text as follows.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* - Neither the name tuckey.org nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*/
package org.tuckey.web.filters.urlrewrite;
import org.tuckey.web.filters.urlrewrite.extend.RewriteMatch;
import org.tuckey.web.filters.urlrewrite.utils.Log;
import org.tuckey.web.filters.urlrewrite.utils.RegexPattern;
import org.tuckey.web.filters.urlrewrite.utils.StringMatchingMatcher;
import org.tuckey.web.filters.urlrewrite.utils.StringMatchingPattern;
import org.tuckey.web.filters.urlrewrite.utils.StringMatchingPatternSyntaxException;
import org.tuckey.web.filters.urlrewrite.utils.StringUtils;
import org.tuckey.web.filters.urlrewrite.utils.WildcardPattern;
import org.tuckey.web.filters.urlrewrite.utils.FunctionReplacer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
/**
* Defines a rule that can be run against an incoming request.
*
* @author Paul Tuckey
* @version $Revision: 36 $ $Date: 2006-09-19 18:32:39 +1200 (Tue, 19 Sep 2006) $
*/
public class RuleBase implements Runnable {
private static Log log = Log.getLog(RuleBase.class);
private static String DEFAULT_RULE_FROM = "^(.*)$";
protected int id;
private boolean enabled = true;
private boolean fromCaseSensitive;
protected boolean initialised;
protected boolean valid;
protected String name;
private String note;
protected String from;
protected String to;
private boolean toEmpty;
private String matchType;
private boolean last = false;
private int conditionIdCounter;
private int runIdCounter;
private StringMatchingPattern pattern;
protected final List errors = new ArrayList(5);
private final List conditions = new ArrayList(5);
private final List runs = new ArrayList(2);
protected final List setAttributes = new ArrayList(2);
private boolean stopFilterChainOnMatch = false;
private boolean noSubstitution = false;
private boolean toContainsVariable = false;
private boolean toContainsBackReference = false;
private boolean toContainsFunction = false;
public static final String MATCH_TYPE_WILDCARD = "wildcard";
public static final String DEFAULT_MATCH_TYPE = "regex";
private boolean filter = false;
/**
* Constructor.
*/
public RuleBase() {
super();
// empty
}
/**
* Will run the rule against the uri and perform action required will return false is not matched
* otherwise true.
*
* @param url
* @param hsRequest
* @return String of the rewritten url or the same as the url passed in if no match was made
*/
protected RuleExecutionOutput matchesBase(String url, final HttpServletRequest hsRequest,
final HttpServletResponse hsResponse, RuleChain chain)
throws IOException, ServletException, InvocationTargetException {
// make sure all the conditions match
if (log.isDebugEnabled()) {
String displayName = getDisplayName();
log.debug(displayName + " run called with " + url);
}
if (!initialised) {
log.debug("not initialised, skipping");
return null;
}
if (!valid) {
log.debug("not valid, skipping");
return null;
}
if (!enabled) {
log.debug("not enabled, skipping");
return null;
}
if (url == null) {
log.debug("url is null (maybe because of a previous match), skipping");
return null;
}
StringMatchingMatcher matcher = pattern.matcher(url);
boolean performToReplacement = false;
if (toEmpty || stopFilterChainOnMatch) {
// to is empty this must be an attempt to "set" and/or "run"
if (!matcher.find()) {
if (log.isTraceEnabled()) {
log.trace("no match on \"from\" (to is empty)");
}
return null;
}
} else {
if (!matcher.find()) {
if (log.isTraceEnabled()) {
log.trace("no match on \"from\" for " + from + " and " + url);
}
return null;
}
if (!toEmpty && !noSubstitution) {
performToReplacement = true;
}
}
if (log.isDebugEnabled()) {
log.debug("matched \"from\"");
}
int conditionsSize = conditions.size();
ConditionMatch lastConditionMatch = null;
if (conditionsSize > 0) {
boolean processNextOr = false;
boolean currentResult = true;
for (int i = 0; i < conditionsSize; i++) {
final Condition condition = (Condition) conditions.get(i);
ConditionMatch conditionMatch = condition.getConditionMatch(hsRequest);
if (conditionMatch != null) {
lastConditionMatch = conditionMatch;
}
boolean conditionMatches = conditionMatch != null;
if (processNextOr) {
currentResult |= conditionMatches;
} else {
// must be and
currentResult &= conditionMatches;
}
processNextOr = condition.isProcessNextOr();
}
if (!currentResult) {
log.debug("conditions do not match");
return null;
} else {
log.debug("conditions match");
}
}
// set a req attrib in case people want to use it
hsRequest.setAttribute("org.tuckey.web.filters.urlrewrite.RuleMatched", Boolean.TRUE);
// make sure the setAttributes are handled
int setAttributesSize = setAttributes.size();
if (setAttributesSize > 0) {
log.trace("setting sttributes");
for (int i = 0; i < setAttributesSize; i++) {
SetAttribute setAttribute = (SetAttribute) setAttributes.get(i);
setAttribute.execute(lastConditionMatch, matcher, hsRequest, hsResponse);
}
}
// make sure the runs are handled
int runsSize = runs.size();
RewriteMatch lastRunMatch = null;
if (runsSize > 0) {
log.trace("performing runs");
for (int i = 0; i < runsSize; i++) {
Run run = (Run) runs.get(i);
lastRunMatch = run.execute(hsRequest, hsResponse, matcher, lastConditionMatch, chain);
}
}
String replacedTo = null;
if (performToReplacement) {
// replace back ref eg, %3 items
// replace vars eg, %{txt}
replacedTo = to;
if (replacedTo != null) {
// do variable replacement
if (toContainsVariable) {
replacedTo = VariableReplacer.replace(replacedTo, hsRequest);
}
// perform backref replacement
if (toContainsBackReference) {
replacedTo = BackReferenceReplacer.replace(lastConditionMatch, replacedTo);
}
}
if ( replacedTo != null && toContainsFunction ) {
// escape the function start sequence so it doesn't cause problems with $x item replacement
replacedTo = replacedTo.replaceAll("\\$\\{", "\\\\\\$\\{");
}
// get existing eg, $1 items
replacedTo = matcher.replaceAll(replacedTo);
if ( replacedTo != null && toContainsFunction ) {
// do variable replacement
replacedTo = FunctionReplacer.replace(replacedTo);
}
}
RuleExecutionOutput ruleExecutionOutput = new RuleExecutionOutput(replacedTo, true, lastRunMatch);
// check for empty to element (valid when only set's)
if (toEmpty) {
log.debug("'to' is empty, no rewrite, only 'set' and or 'run'");
return null;
}
// Check for "no substitution" (-)
if (noSubstitution) {
log.debug("'to' is '-', no substitution, passing through URL");
ruleExecutionOutput.setNoSubstitution(true);
ruleExecutionOutput.setReplacedUrl(url);
}
// when match found but need to stop filter chain
if (stopFilterChainOnMatch) {
ruleExecutionOutput.setStopFilterMatch(true);
ruleExecutionOutput.setReplacedUrl(null);
}
// note, the rewritten URL is unchanged if there was no <to> element.
return ruleExecutionOutput;
}
public String getDisplayName() {
return null;
}
/**
* Will initialise the rule.
*
* @return true on success
*/
public boolean initialise(ServletContext context) {
// check all the conditions
initialised = true;
boolean ok = true;
for (int i = 0; i < conditions.size(); i++) {
final Condition condition = (Condition) conditions.get(i);
condition.setRule(this);
if (!condition.initialise()) {
ok = false;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -