Example #1
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);
        }
Example #2
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);
        }