Beispiel #1
0
        /// <summary>
        /// Runs the rules.
        /// </summary>
        /// <param name="httpContext">The HTTP context.</param>
        /// <param name="url">The URL.</param>
        /// <returns>
        /// Returns a rewritten <see cref="System.Uri"/>, or a value of <see langword="null"/> if no rewriting was done to <paramref name="url"/>.
        /// </returns>
        public Uri RunRules(HttpContextBase httpContext, Uri url)
        {
            var context    = new RuleSetContext(this, url, httpContext);
            var currentUrl = url;

            if (!EngineEnabled)
            {
                Manager.LogIf(!EngineEnabled && LogLevel >= 9, "Rewrite Engine Is DISABLED", "Rewrite");
            }

            if (_rules.Count > 0 && EngineEnabled)
            {
                Manager.LogIf(LogLevel >= 1, "**********************************************************************************");
                Manager.LogIf(LogLevel >= 1, "Input: " + currentUrl, "Rewrite");

                // check if max number of internal transfers have been exceeded
                if (InternalTransferCount(httpContext) > MaxInternalTransfers)
                {
                    string message = "Exceeded the max number of internal transfers.";
                    Manager.LogIf(LogLevel >= 1, message, "Error");
                    throw new HttpException(500, message);
                }

                var temporyFlags  = (IRuleFlagProcessor)null;
                var skipNextChain = false;
                var initialUrl    = currentUrl;

                if (!String.IsNullOrEmpty(VirtualBase) && VirtualBase != "/")
                {
                    currentUrl = RemoveBase(VirtualBase, currentUrl);
                }

                // process rules according to their settings
                for (int i = 0; i < _rules.Count; i++)
                {
                    var ruleContext = new RuleContext(i, context, currentUrl, _rules[i]);
                    temporyFlags = _rules[i].Flags;

                    // continue if this rule shouldn't be processed because it doesn't allow internal transfer requests
                    if (RuleFlagsProcessor.HasNotForInternalSubRequests(temporyFlags) && IsInternalTransfer(httpContext))
                    {
                        continue;
                    }

                    bool containsChain         = RuleFlagsProcessor.HasChain(_rules[i].Flags);
                    bool previousContainsChain = RuleFlagsProcessor.HasChain(_rules[Math.Max(0, i - 1)].Flags);

                    // if the previous rule doesn't contain a chain flag then set the initial URL
                    // this will be used to reset a chain if one of the chain rules fail
                    if (!previousContainsChain)
                    {
                        initialUrl = currentUrl;
                    }

                    // skip if the current rule or the last rule has a chain flag
                    // and if the skip next chain is set
                    if (skipNextChain && (previousContainsChain || containsChain))
                    {
                        continue;
                    }
                    else
                    {
                        skipNextChain = false;
                    }

                    if (_rules[i].TryExecute(ruleContext))
                    {
                        var flagResponse = temporyFlags.Apply(ruleContext);
                        currentUrl = ruleContext.SubstitutedUrl;
                        i          = ruleContext.RuleIndex ?? -1;
                        bool breakLoop = false;

                        // apply the flags to the rules, and only do special processing
                        // for the flag responses listed in the switch statement below
                        switch (flagResponse)
                        {
                        case RuleFlagProcessorResponse.ExitRuleSet:
                            return(null);

                        case RuleFlagProcessorResponse.LastRule:
                            breakLoop = true;
                            break;
                        }

                        // break the loop because we have reached the last rule as indicated by a flag
                        if (breakLoop)
                        {
                            break;
                        }
                    }
                    else if (containsChain)
                    {
                        skipNextChain = true;

                        // reset the current URL back to the initial URL from the start of the chain
                        currentUrl = initialUrl;
                    }
                    else if (previousContainsChain)
                    {
                        // reset the current URL back to the initial URL from the start of the chain
                        currentUrl = initialUrl;
                    }
                }

                // if the scheme, host, and ports do not match on the request vs the rewrite a redirect needs to be performed instead of a rewrite
                if (Uri.Compare(currentUrl, context.RequestedUrl, UriComponents.SchemeAndServer, UriFormat.SafeUnescaped, StringComparison.OrdinalIgnoreCase) != 0)
                {
                    Manager.LogIf(LogLevel >= 1, "Output: 302 Redirect to " + currentUrl, "Rewrite");
                    Manager.Redirect(httpContext, "found", currentUrl);
                }

                if (!String.IsNullOrEmpty(VirtualBase) && VirtualBase != "/")
                {
                    currentUrl = AddBase(VirtualBase, currentUrl);
                }

                Manager.LogIf(LogLevel >= 1, "Output: " + currentUrl, "Rewrite");
                Manager.LogIf(LogLevel >= 1, "**********************************************************************************");

                Manager.TryToAddXRewriteUrlHeader(httpContext);
                Manager.TryToAddVanityHeader(httpContext);
            }

            // if the http request url matches for both the request and the rewrite no work was done so the url should be null
            if (Uri.Compare(currentUrl, url, UriComponents.HttpRequestUrl, UriFormat.SafeUnescaped, StringComparison.OrdinalIgnoreCase) == 0)
            {
                currentUrl = null;
            }

            return(currentUrl);
        }
Beispiel #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="httpContext"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        public byte[] RunOutputRules(HttpContextBase httpContext, byte[] content)
        {
            var context = new RuleSetContext(this, content, httpContext);

            byte[] currentContent = content;

            if (!EngineEnabled)
            {
                Manager.LogIf(!EngineEnabled && LogLevel >= 9, "Rewrite Engine Is DISABLED", "OutRewrite");
            }

            if (_outputRules.Count > 0 && EngineEnabled)
            {
                Manager.LogIf(LogLevel >= 1, "**********************************************************************************");
                //Manager.LogIf(LogLevel >= 9, "Input: " + currentContent, "OutRewrite");

                var    temporyFlags   = (IRuleFlagProcessor)null;
                bool   skipNextChain  = false;
                byte[] initialContent = currentContent;

                // process rules according to their settings
                for (int i = 0; i < _outputRules.Count; i++)
                {
                    var ruleContext = new RuleContext(i, context, currentContent, _outputRules[i]);
                    temporyFlags = _outputRules[i].Flags;

                    bool containsChain         = RuleFlagsProcessor.HasChain(_outputRules[i].Flags);
                    bool previousContainsChain = RuleFlagsProcessor.HasChain(_outputRules[Math.Max(0, i - 1)].Flags);

                    // if the previous rule doesn't contain a chain flag then set the initial URL
                    // this will be used to reset a chain if one of the chain rules fail
                    if (!previousContainsChain)
                    {
                        initialContent = currentContent;
                    }

                    // skip if the current rule or the last rule has a chain flag
                    // and if the skip next chain is set
                    if (skipNextChain && (previousContainsChain || containsChain))
                    {
                        continue;
                    }
                    else
                    {
                        skipNextChain = false;
                    }

                    if (_outputRules[i].TryExecute(ruleContext))
                    {
                        var flagResponse = temporyFlags.Apply(ruleContext);
                        currentContent = ruleContext.SubstitutedContent;
                        i = ruleContext.RuleIndex ?? -1;
                        bool breakLoop = false;

                        // apply the flags to the rules, and only do special processing
                        // for the flag responses listed in the switch statement below
                        switch (flagResponse)
                        {
                        case RuleFlagProcessorResponse.ExitRuleSet:
                            return(null);

                        case RuleFlagProcessorResponse.LastRule:
                            breakLoop = true;
                            break;
                        }

                        // break the loop because we have reached the last rule as indicated by a flag
                        if (breakLoop)
                        {
                            break;
                        }
                    }
                    else if (containsChain)
                    {
                        skipNextChain = true;

                        // reset the current URL back to the initial URL from the start of the chain
                        currentContent = initialContent;
                    }
                    else if (previousContainsChain)
                    {
                        // reset the current URL back to the initial URL from the start of the chain
                        currentContent = initialContent;
                    }
                }

                //Manager.LogIf(LogLevel >= 9, "Output: " + currentContent, "OutRewrite");
                Manager.LogIf(LogLevel >= 1, "**********************************************************************************");
            }

            return(currentContent);
        }
        /// <summary>
        /// Refreshes the rules.
        /// </summary>
        /// <param name="reader">The reader.</param>
        public void RefreshRules(TextReader reader)
        {
            // put a lock on the refresh process so that only one refresh can happen at a time
            lock (_refreshLock)
            {
                Manager.LogEnabled = false;
                Manager.LogPath    = null;

                string tempBase                 = PhysicalBase;
                string tempLogPath              = null;
                int    tempLogLevel             = 0;
                int    tempMaxInternalTransfers = 10;
                bool   tempEngineEnabled        = false;

                string             line;
                IList <ICondition> conditions   = new List <ICondition>(0);
                IList <IRule>      rules        = new List <IRule>();
                IList <IRule>      outputRules  = new List <IRule>();
                IList <string>     unknownLines = new List <string>();
                ModuleFactory      modules      = new ModuleFactory();

                while (reader.Peek() >= 0)
                {
                    line = reader.ReadLine().Trim();

                    if (String.IsNullOrEmpty(line))
                    {
                        // just plain old ignore empty lines no logging or anything
                        continue;
                    }
                    else if (line[0] == '#')
                    {
                        Manager.LogIf(tempLogLevel >= 4, "Comment: " + line, "Rule Processing");
                    }
                    else if (RewriteEngineLine.IsMatch(line))
                    {
                        #region RewriteEngine

                        Match  match       = RewriteEngineLine.Match(line);
                        string engineState = match.Groups["state"].Value;

                        // by default the engine is turned off
                        if (String.IsNullOrEmpty(engineState) || String.Equals(engineState, "off", StringComparison.OrdinalIgnoreCase))
                        {
                            rules.Clear();
                            tempEngineEnabled = false;

                            // don't bother processing any other rules if the engine is disabled
                            break;
                        }
                        else
                        {
                            tempEngineEnabled = true;
                        }

                        Manager.LogIf(tempLogLevel >= 3, "RewriteEngine: " + (tempEngineEnabled ? "Enabled" : "Disabled"), "Rule Processing");

                        #endregion
                    }
                    else if (RewriteOptionsLine.IsMatch(line))
                    {
                        #region RewriteOptions

                        Match match     = RewriteOptionsLine.Match(line);
                        Group variables = match.Groups["var"];

                        if (variables.Success)
                        {
                            foreach (Capture var in variables.Captures)
                            {
                                string[] parts = var.Value.Split(new[] { '=' }, 2);
                                bool     variableUnderstood = false;

                                if (parts.Length == 2)
                                {
                                    switch (parts[0])
                                    {
                                    case "inherit":
                                        break;

                                    // obsolete in 2.1 mod_rewrite
                                    case "MaxRedirects":
                                        Manager.LogIf(tempLogLevel >= 1, "MaxRedirects is obsolete", "Obsolete");

                                        int maxInternalTransfers;
                                        if (Int32.TryParse(parts[1], out maxInternalTransfers))
                                        {
                                            tempMaxInternalTransfers = maxInternalTransfers;
                                            variableUnderstood       = true;
                                        }
                                        break;
                                    }
                                }

                                if (!variableUnderstood)
                                {
                                    Manager.LogIf(tempLogLevel >= 4, "Not Understood: " + var.Value, "Unknown");
                                }
                            }
                        }

                        #endregion
                    }
                    else if (RewriteBaseLine.IsMatch(line))
                    {
                        #region RewriteBase

                        Match match = RewriteBaseLine.Match(line);
                        tempBase = match.Groups["base"].Value;

                        Manager.LogIf(tempLogLevel >= 3, "RewriteBase: " + VirtualBase, "Rule Processing");

                        #endregion
                    }
                    else if (RewriteModuleLine.IsMatch(line))
                    {
                        #region RewriteModule

                        Match  match      = RewriteModuleLine.Match(line);
                        string moduleName = match.Groups["name"].Value;
                        string moduleType = match.Groups["type"].Value;
                        Type   module     = Type.GetType(moduleType, false, true);

                        if (module == null)
                        {
                            module = BuildManager.GetType(moduleType, false, true);
                        }

                        if (module == null)
                        {
                            Manager.LogIf(tempLogLevel >= 3, "RewriteModule: Error finding " + moduleType, "Rule Processing");
                        }
                        else
                        {
                            // add the module to the list
                            modules.AddModule(moduleName, module);

                            Manager.LogIf(tempLogLevel >= 3, "RewriteModule: " + moduleType, "Rule Processing");
                        }

                        #endregion
                    }
                    else if (RewriteLogLine.IsMatch(line))
                    {
                        #region RewriteLog

                        Match match = RewriteLogLine.Match(line);
                        tempLogPath = match.Groups["location"].Value;
                        tempLogPath = NormalizeLogLocation(tempLogPath);

                        Manager.LogIf(tempLogLevel >= 3, "RewriteLog: " + tempLogPath, "Rule Processing");

                        #endregion
                    }
                    else if (RewriteLogLevelLine.IsMatch(line))
                    {
                        #region RewriteLogLevel

                        Match match    = RewriteLogLevelLine.Match(line);
                        int   logLevel = 1;

                        if (!Int32.TryParse(match.Groups["level"].Value, out logLevel))
                        {
                            tempLogLevel = 0;
                            Manager.LogIf(tempLogLevel >= 3, "RewriteLogLevel: " + match.Groups["level"].Value + " not understood.", "Rule Processing");
                        }
                        else
                        {
                            tempLogLevel = logLevel;
                        }

                        Manager.LogIf(tempLogLevel >= 3, "RewriteLogLevel: " + logLevel, "Rule Processing");

                        #endregion
                    }
                    else if (RewriteCondLine.IsMatch(line))
                    {
                        #region RewriteCond

                        Match match = RewriteCondLine.Match(line);

                        string module1 = match.Groups["module1"].Value;
                        string module2 = match.Groups["module2"].Value;

                        Type moduleType1 = null;
                        Type moduleType2 = null;

                        // set the types of the first module
                        if (modules.ContainsName(module1))
                        {
                            moduleType1 = modules.GetModule(module1);
                        }

                        // make sure the module is of the right type
                        if (moduleType1 != null && moduleType1.GetInterface("ICondition", false) == null)
                        {
                            moduleType1 = null;
                        }

                        // set the types of the second module
                        if (modules.ContainsName(module2))
                        {
                            moduleType2 = modules.GetModule(module2);
                        }

                        // make sure the module is of the right type
                        if (moduleType2 != null && moduleType2.GetInterface("IConditionTestValue", false) == null)
                        {
                            moduleType2 = null;
                        }

                        try
                        {
                            RegexOptions            patternOptions = Manager.RuleOptions;
                            IConditionFlagProcessor flags;

                            if (match.Groups["flags"] != null)
                            {
                                flags = SplitConditionFlags(match.Groups["flags"].Value);
                            }
                            else
                            {
                                flags = new ConditionFlagProcessor();
                            }

                            // check to see if the pattern should ignore the case when testing
                            if (ConditionFlagsProcessor.HasNoCase(flags))
                            {
                                patternOptions |= RegexOptions.IgnoreCase;
                            }

                            string test    = match.Groups["test"].Value;
                            string pattern = match.Groups["pattern"].Value;
                            IConditionTestValue testValue;
                            ICondition          condition;

                            // create the second module
                            if (moduleType2 == null)
                            {
                                testValue = GetConditionTestValue(ref test);
                            }
                            else
                            {
                                testValue = Activator.CreateInstance(moduleType2) as IConditionTestValue;
                            }

                            // create the first module
                            if (moduleType1 == null)
                            {
                                condition = GetCondition(pattern);
                            }
                            else
                            {
                                condition = Activator.CreateInstance(moduleType1) as ICondition;
                            }

                            // initialize the modules
                            testValue.Init(test);
                            condition.Init(new Pattern(pattern, patternOptions), testValue, flags);

                            // add condition to next rule that shows up
                            conditions.Add(condition);
                        }
                        catch (Exception exc)
                        {
                            if (tempLogLevel >= 3)
                            {
                                Manager.Log("RewriteCond: " + exc.Message, "Error");
                            }
                            else
                            {
                                Manager.Log("RewriteCond: " + exc, "Error");
                            }
                        }
                        finally
                        {
                            Manager.LogIf(tempLogLevel >= 3, "RewriteCond: " + match.Groups["test"].Value + " " + match.Groups["pattern"].Value + " [" + match.Groups["flags"].Value + "]", "Rule Processing");
                        }

                        #endregion
                    }
                    else if (RewriteRuleLine.IsMatch(line))
                    {
                        #region RewriteRule

                        Match match = RewriteRuleLine.Match(line);

                        string module1 = match.Groups["module1"].Value;
                        string module2 = match.Groups["module2"].Value;

                        Type moduleType1 = null;
                        Type moduleType2 = null;

                        // set the types of the first module
                        if (modules.ContainsName(module1))
                        {
                            moduleType1 = modules.GetModule(module1);
                        }

                        // make sure the module is of the right type
                        if (moduleType1 != null && moduleType1.GetInterface("IRule", false) == null)
                        {
                            moduleType1 = null;
                        }

                        // set the types of the second module
                        if (modules.ContainsName(module2))
                        {
                            moduleType2 = modules.GetModule(module2);
                        }

                        // make sure the module is of the right type
                        if (moduleType2 != null && moduleType2.GetInterface("IRuleAction", false) == null)
                        {
                            moduleType2 = null;
                        }

                        try
                        {
                            RegexOptions       patternOptions = Manager.RuleOptions;
                            IRuleFlagProcessor flags;

                            if (match.Groups["flags"] != null)
                            {
                                flags = SplitRuleFlags(match.Groups["flags"].Value);
                            }
                            else
                            {
                                flags = new RuleFlagProcessor();
                            }

                            // check to see if the pattern should ignore the case when testing
                            if (RuleFlagsProcessor.HasNoCase(flags))
                            {
                                patternOptions |= RegexOptions.IgnoreCase;
                            }

                            IRule       rule         = null;
                            IRuleAction substitution = null;
                            Pattern     pattern      = new Pattern(match.Groups["pattern"].Value, patternOptions);

                            // create the first module
                            if (moduleType1 == null)
                            {
                                rule = new DefaultRule();
                            }
                            else
                            {
                                rule = Activator.CreateInstance(moduleType1) as IRule;
                            }

                            // create the second module
                            if (moduleType2 == null)
                            {
                                substitution = new DefaultRuleAction();
                            }
                            else
                            {
                                substitution = Activator.CreateInstance(moduleType2) as IRuleAction;
                            }

                            // initialize the modules
                            substitution.Init(pattern, match.Groups["substitution"].Value);
                            rule.Init(conditions, substitution, flags);

                            // add condition to next rule that shows up
                            rules.Add(rule);

                            // clear conditions for next rule
                            conditions.Clear();
                        }
                        catch (Exception exc)
                        {
                            if (tempLogLevel >= 3)
                            {
                                Manager.Log("RewriteRule: " + exc.Message, "Error");
                            }
                            else
                            {
                                Manager.Log("RewriteRule: " + exc, "Error");
                            }
                        }
                        finally
                        {
                            Manager.LogIf(tempLogLevel >= 3, "RewriteRule: " + match.Groups["pattern"].Value + " " + match.Groups["substitution"].Value + " [" + match.Groups["flags"].Value + "]", "Rule Processing");
                        }

                        #endregion
                    }
                    else if (OutRewriteCondLine.IsMatch(line))
                    {
                        #region OutRewriteCond

                        Match match = OutRewriteCondLine.Match(line);

                        string module1 = match.Groups["module1"].Value;
                        string module2 = match.Groups["module2"].Value;

                        Type moduleType1 = null;
                        Type moduleType2 = null;

                        // set the types of the first module
                        if (modules.ContainsName(module1))
                        {
                            moduleType1 = modules.GetModule(module1);
                        }

                        // make sure the module is of the right type
                        if (moduleType1 != null && moduleType1.GetInterface("ICondition", false) == null)
                        {
                            moduleType1 = null;
                        }

                        // set the types of the second module
                        if (modules.ContainsName(module2))
                        {
                            moduleType2 = modules.GetModule(module2);
                        }

                        // make sure the module is of the right type
                        if (moduleType2 != null && moduleType2.GetInterface("IConditionTestValue", false) == null)
                        {
                            moduleType2 = null;
                        }

                        try
                        {
                            RegexOptions            patternOptions = Manager.RuleOptions;
                            IConditionFlagProcessor flags;

                            if (match.Groups["flags"] != null)
                            {
                                flags = SplitConditionFlags(match.Groups["flags"].Value);
                            }
                            else
                            {
                                flags = new ConditionFlagProcessor();
                            }

                            // check to see if the pattern should ignore the case when testing
                            if (ConditionFlagsProcessor.HasNoCase(flags))
                            {
                                patternOptions |= RegexOptions.IgnoreCase;
                            }

                            string test    = match.Groups["test"].Value;
                            string pattern = match.Groups["pattern"].Value;
                            IConditionTestValue testValue;
                            ICondition          condition;

                            // create the second module
                            if (moduleType2 == null)
                            {
                                testValue = GetConditionTestValue(ref test);
                            }
                            else
                            {
                                testValue = Activator.CreateInstance(moduleType2) as IConditionTestValue;
                            }

                            // create the first module
                            if (moduleType1 == null)
                            {
                                condition = GetCondition(pattern);
                            }
                            else
                            {
                                condition = Activator.CreateInstance(moduleType1) as ICondition;
                            }

                            // initialize the modules
                            testValue.Init(test);
                            condition.Init(new Pattern(pattern, patternOptions), testValue, flags);

                            // add condition to next rule that shows up
                            conditions.Add(condition);
                        }
                        catch (Exception exc)
                        {
                            if (tempLogLevel >= 3)
                            {
                                Manager.Log("OutRewriteCond: " + exc.Message, "Error");
                            }
                            else
                            {
                                Manager.Log("OutRewriteCond: " + exc, "Error");
                            }
                        }
                        finally
                        {
                            Manager.LogIf(tempLogLevel >= 3, "OutRewriteCond: " + match.Groups["test"].Value + " " + match.Groups["pattern"].Value + " [" + match.Groups["flags"].Value + "]", "Rule Processing");
                        }

                        #endregion
                    }
                    else if (OutRewriteRuleLine.IsMatch(line))
                    {
                        #region OutRewriteRule

                        Match match = OutRewriteRuleLine.Match(line);

                        string module1 = match.Groups["module1"].Value;
                        string module2 = match.Groups["module2"].Value;

                        Type moduleType1 = null;
                        Type moduleType2 = null;

                        // set the types of the first module
                        if (modules.ContainsName(module1))
                        {
                            moduleType1 = modules.GetModule(module1);
                        }

                        // make sure the module is of the right type
                        if (moduleType1 != null && moduleType1.GetInterface("IRule", false) == null)
                        {
                            moduleType1 = null;
                        }

                        // set the types of the second module
                        if (modules.ContainsName(module2))
                        {
                            moduleType2 = modules.GetModule(module2);
                        }

                        // make sure the module is of the right type
                        if (moduleType2 != null && moduleType2.GetInterface("IRuleAction", false) == null)
                        {
                            moduleType2 = null;
                        }

                        try
                        {
                            RegexOptions       patternOptions = Manager.RuleOptions;
                            IRuleFlagProcessor flags;

                            if (match.Groups["flags"] != null)
                            {
                                flags = SplitRuleFlags(match.Groups["flags"].Value);
                            }
                            else
                            {
                                flags = new RuleFlagProcessor();
                            }

                            // check to see if the pattern should ignore the case when testing
                            if (RuleFlagsProcessor.HasNoCase(flags))
                            {
                                patternOptions |= RegexOptions.IgnoreCase;
                            }

                            IRule       rule         = null;
                            IRuleAction substitution = null;
                            Pattern     pattern      = new Pattern(match.Groups["pattern"].Value, patternOptions);

                            // create the first module
                            if (moduleType1 == null)
                            {
                                rule = new DefaultRule();
                            }
                            else
                            {
                                rule = Activator.CreateInstance(moduleType1) as IRule;
                            }

                            // create the second module
                            if (moduleType2 == null)
                            {
                                substitution = new DefaultOutputRuleAction();
                            }
                            else
                            {
                                substitution = Activator.CreateInstance(moduleType2) as IRuleAction;
                            }

                            // initialize the modules
                            substitution.Init(pattern, match.Groups["substitution"].Value);
                            rule.Init(conditions, substitution, flags);

                            // add condition to next rule that shows up
                            outputRules.Add(rule);

                            // clear conditions for next rule
                            conditions.Clear();
                        }
                        catch (Exception exc)
                        {
                            if (tempLogLevel >= 3)
                            {
                                Manager.Log("OutRewriteRule: " + exc.Message, "Error");
                            }
                            else
                            {
                                Manager.Log("OutRewriteRule: " + exc, "Error");
                            }
                        }
                        finally
                        {
                            Manager.LogIf(tempLogLevel >= 3, "OutRewriteRule: " + match.Groups["pattern"].Value + " " + match.Groups["substitution"].Value + " [" + match.Groups["flags"].Value + "]", "Rule Processing");
                        }

                        #endregion
                    }
                    else
                    {
                        unknownLines.Add(line);
                    }
                }

                Manager.LogIf(tempLogLevel > 0, "Managed Fusion Rewriter Version: " + Manager.RewriterVersion, "Rule Processing");

                // clear and add new rules
                ClearRules();
                AddRules(rules);
                AddOutputRules(outputRules);

                // try to process any unknown lines
                if (unknownLines.Count > 0)
                {
                    RefreshUnknownLines(ref unknownLines);

                    foreach (var unknownLine in unknownLines)
                    {
                        Manager.LogIf(tempLogLevel >= 4, "Not Understood: " + unknownLine, "Unknown");
                    }
                }


                // set the ruleset defining properties
                VirtualBase        = tempBase;
                LogLocation        = tempLogPath;
                LogLevel           = tempLogLevel;
                EngineEnabled      = tempEngineEnabled;
                Manager.LogPath    = tempLogPath;
                Manager.LogEnabled = tempLogLevel > 0;
            }
        }