⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 modrewriteconfloader.java

📁 UrlRewriteFilter 是一个不错的URL转换工具
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
package org.tuckey.web.filters.urlrewrite.utils;

import org.tuckey.web.filters.urlrewrite.Condition;
import org.tuckey.web.filters.urlrewrite.Conf;
import org.tuckey.web.filters.urlrewrite.NormalRule;
import org.tuckey.web.filters.urlrewrite.SetAttribute;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Loader to enable loading of mod_rewrite style configuration for UrlRewriteFilter.
 */
public class ModRewriteConfLoader {

    private static Log log = Log.getLog(ModRewriteConfLoader.class);

    private final Pattern LOG_LEVEL_PATTERN = Pattern.compile("RewriteLogLevel\\s+([0-9]+)\\s*$");
    private final Pattern LOG_TYPE_PATTERN = Pattern.compile("RewriteLog\\s+(.*)$");
    private final Pattern ENGINE_PATTERN = Pattern.compile("RewriteEngine\\s+([a-zA-Z0-9]+)\\s*$");
    private final Pattern CONDITION_PATTERN = Pattern.compile("RewriteCond\\s+(.*)$");
    private final Pattern RULE_PATTERN = Pattern.compile("RewriteRule\\s+(.*)$");

    public void process(InputStream is, Conf conf) throws IOException {
        String line;
        BufferedReader in = new BufferedReader(new InputStreamReader(is));
        StringBuffer buffer = new StringBuffer();
        while ((line = in.readLine()) != null) {
            buffer.append(line);
            buffer.append("\n");
        }
        process(buffer.toString(), conf);
    }

    public void process(String modRewriteStyleConf, Conf conf) {
        String[] lines = modRewriteStyleConf.split("\n");
        List conditionsBuffer = new ArrayList();
        StringBuffer notesBuffer = new StringBuffer();
        String logLevelStr = null;
        String logTypeStr = null;

        for (int i = 0; i < lines.length; i++) {
            String line = StringUtils.trimToNull(lines[i]);
            if (line == null) continue;
            log.debug("processing line: " + line);

            if (line.startsWith("#")) {
                log.debug("adding note line (line starting with #)");
                if (notesBuffer.length() > 0) notesBuffer.append("\n");
                String noteLine = StringUtils.trim(line.substring(1));
                notesBuffer.append(noteLine);

            } else if (line.startsWith("RewriteBase")) {
                log.info("RewriteBase not supported, ignored");

            } else if (line.startsWith("RewriteCond")) {
                Condition condition = processRewriteCond(line);
                if (condition != null) conditionsBuffer.add(condition);

            } else if (line.startsWith("RewriteEngine")) {
                processRewriteEngine(conf, line);

            } else if (line.startsWith("RewriteLock")) {
                log.error("RewriteLock not supported, ignored");

            } else if (line.startsWith("RewriteLogLevel")) {
                logLevelStr = parseLogLevel(logLevelStr, line);

            } else if (line.startsWith("RewriteLog")) {
                logTypeStr = parseLogType(logTypeStr, line);

            } else if (line.startsWith("RewriteMap")) {
                log.error("RewriteMap not supported, ignored");

            } else if (line.startsWith("RewriteOptions")) {
                log.error("RewriteOptions not supported, ignored");

            } else if (line.startsWith("RewriteRule")) {
                parseRule(conf, conditionsBuffer, notesBuffer, line);
                notesBuffer = new StringBuffer();
                conditionsBuffer = new ArrayList();
            }
        }
        if (logTypeStr != null || logLevelStr != null) {
            String logStr = (logTypeStr == null ? "" : logTypeStr) + (logLevelStr == null ? "" : ":" + logLevelStr);
            log.debug("setting log to: " + logStr);
            Log.setLevel(logStr);
        }
        if (conditionsBuffer.size() > 0) {
            log.error("conditions left over without a rule");
        }
    }

    private void parseRule(Conf conf, List conditionsBuffer, StringBuffer notesBuffer, String line) {
        NormalRule rule = processRule(line);
        for (int j = 0; j < conditionsBuffer.size(); j++) {
            Condition condition = (Condition) conditionsBuffer.get(j);
            rule.addCondition(condition);
        }
        if (notesBuffer.length() > 0) rule.setNote(notesBuffer.toString());
        conf.addRule(rule);
    }

    private String parseLogType(String logTypeStr, String line) {
        Matcher logTypeMatcher = LOG_TYPE_PATTERN.matcher(line);
        if (logTypeMatcher.matches()) {
            logTypeStr = StringUtils.trimToNull(logTypeMatcher.group(1));
            if (logTypeStr != null) {
                logTypeStr = logTypeStr.replaceAll("\"", "");
                log.debug("RewriteLog parsed as " + logTypeStr);
            }
        }
        return logTypeStr;
    }

    private String parseLogLevel(String logLevelStr, String line) {
        log.debug("found a RewriteLogLevel");
        Matcher logLevelMatcher = LOG_LEVEL_PATTERN.matcher(line);
        if (logLevelMatcher.matches()) {
            int logLevel = NumberUtils.stringToInt(logLevelMatcher.group(1));
            if (logLevel <= 1) logLevelStr = "FATAL";
            else if (logLevel == 2) logLevelStr = "ERROR";
            else if (logLevel == 3) logLevelStr = "INFO";
            else if (logLevel == 4) logLevelStr = "WARN";
            else if (logLevel >= 5) logLevelStr = "DEBUG";
            log.debug("RewriteLogLevel parsed as " + logLevel);

        } else {
            log.error("cannot parse " + line);
        }
        return logLevelStr;
    }

    private NormalRule processRule(String line) {
        NormalRule rule = new NormalRule();
        Matcher ruleMatcher = RULE_PATTERN.matcher(line);
        if (ruleMatcher.matches()) {
            String rulePartStr = StringUtils.trimToNull(ruleMatcher.group(1));
            if (rulePartStr != null) {
                log.debug("got rule " + rulePartStr);
                String[] ruleParts = rulePartStr.split(" ");
                int partCounter = 0;
                for (int j = 0; j < ruleParts.length; j++) {
                    String part = StringUtils.trimToNull(ruleParts[j]);
                    if (part == null) continue;
                    partCounter++;
                    log.debug("parsed rule part " + part);
                    if (partCounter == 1) {
                        rule.setFrom(part);
                    }
                    if (partCounter == 2) {
                        if (!"-".equals(part)) {
                            rule.setTo(part);
                        }
                    }
                    if (part.startsWith("[") && part.endsWith("]")) {
                        processRuleFlags(rule, part);
                    }
                }
            } else {
                log.error("could not parse rule from " + line);
            }
        } else {
            log.error("cannot parse " + line);
        }
        return rule;
    }

    private void processRewriteEngine(Conf conf, String line) {
        boolean enabled = true;
        Matcher engineMatcher = ENGINE_PATTERN.matcher(line);
        if (engineMatcher.matches()) {
            String enabledStr = StringUtils.trim(engineMatcher.group(1));
            log.debug("RewriteEngine value parsed as '" + enabledStr + "'");
            if ("0".equalsIgnoreCase(enabledStr) ||
                    "false".equalsIgnoreCase(enabledStr) ||
                    "no".equalsIgnoreCase(enabledStr) ||
                    "off".equalsIgnoreCase(enabledStr)) enabled = false;
            log.debug("RewriteEngine as boolean '" + enabled + "'");
        } else {
            log.error("cannot parse " + line);
        }
        conf.setEngineEnabled(enabled);
    }

    private void processRuleFlags(NormalRule rule, String part) {
        String rawFlags = StringUtils.trimToNull(part.substring(1, part.length() - 1));
        if (rawFlags != null) {
            String[] flags = rawFlags.split(",");
            for (int k = 0; k < flags.length; k++) {
                String flag = flags[k];
                String flagValue = null;
                if (flag.indexOf("=") != -1) {
                    flagValue = flag.substring(flag.indexOf("=") + 1);
                    flag = flag.substring(0, flag.indexOf("="));
                }
                flag = flag.toLowerCase();
                /*
                # 'chain|C' (chained with next rule)
                This flag chains the current rule with the next rule (which itself can be chained with the following rule, and so on). This has the following effect: if a rule matches, then processing continues as usual - the flag has no effect. If the rule does not match, then all following chained rules are skipped. For instance, it can be used to remove the ``.www'' part, inside a per-directory rule set, when you let an external redirect happen (where the ``.www'' part should not occur!).
                 */
                if ("chain".equalsIgnoreCase(flag) || "C".equalsIgnoreCase(flag)) {
                    log.info("chain flag [C] not supported");
                }
                /*
                # 'cookie|CO=NAME:VAL:domain[:lifetime[:path]]' (set cookie)
                This sets a cookie in 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
                 */
                if ("cookie".equalsIgnoreCase(flag) || "CO".equalsIgnoreCase(flag)) {
                    SetAttribute set = new SetAttribute();
                    set.setType("cookie");
                    String cookieName = flagValue;
                    String cookieValue = null;
                    if (flagValue != null) {
                        int colon = flagValue.indexOf(":");
                        if (colon != -1) {
                            cookieValue = flagValue.substring(colon + 1);
                            cookieName = flagValue.substring(0, colon);
                        }
                    }
                    set.setName(cookieName);
                    // NOTE: The colon separated domain, lifetime, path are
                    // handled by SetAttribute.setValue()
                    set.setValue(cookieValue);
                    rule.addSetAttribute(set);
                }
                /*
                # 'env|E=VAR:VAL' (set environment variable)
                This forces an environment variable named VAR to be set to the value VAL, where VAL can contain regexp backreferences ($N and %N) which will be expanded. You can use this flag more than once, to set more than one variable. The variables can later be dereferenced in many situations, most commonly from within XSSI (via <!--#echo var="VAR"-->) or CGI ($ENV{'VAR'}). You can also dereference the variable in a later RewriteCond pattern, using %{ENV:VAR}. Use this to strip information from URLs, while maintaining a record of that information.
                */
                if ("env".equalsIgnoreCase(flag) || "E".equalsIgnoreCase(flag)) {
                    log.info("env flag [E] not supported");
                }
                /*
                # 'forbidden|F' (force URL to be forbidden)
                This forces the current URL to be forbidden - it immediately sends back a HTTP response of 403 (FORBIDDEN). Use this flag in conjunction with appropriate RewriteConds to conditionally block some URLs.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -