예제 #1
0
        public void ConditionMatchAllMustMatchButOneDoesNot()
        {
            var rule = new InboundRule
            {
                ConditionLogicalGrouping = LogicalGrouping.MatchAll,
                Conditions = new List<Condition>
                {
                    new Condition()
                    {
                        CheckIfInputString = CheckIfInputString.DoesNotMatchThePattern,
                        InputString = "OFF",
                        Pattern = "OFF"
                    },
                    new Condition()
                    {
                        CheckIfInputString = CheckIfInputString.MatchesThePattern,
                        InputString = "OFF",
                        Pattern = "OFF"
                    },
                }
            };

            Match match = null;
            var conditionMatchResult = RewriteHelper.TestConditionMatches(rule, null, out match);

            Assert.IsFalse(conditionMatchResult.Matched);
        }
예제 #2
0
        public void ProcessRequestUrlWithAbort()
        {
            var rewriter = new InboundRewriter();
            var newInboundRule = new InboundRule()
            {
                Name = "Abort Rule",
                Pattern = "^abort$",
                Using = Using.RegularExpressions,
                Action = new AbortRequest() { Name = "Abort Action" },
                MatchType = MatchType.MatchesThePattern
            };

            InboundRules.Insert(1, newInboundRule);

            var rewriteResult = rewriter.ProcessRequestUrl(new Uri("http://fictitioussite.com/abort"), InboundRules);

            Assert.IsInstanceOfType(rewriteResult.FinalAction, typeof(AbortRequest));
            Assert.IsTrue(rewriteResult.ProcessedResults.Count == 2);
        }
예제 #3
0
        public static InboundRule ToInboundRule(this InboundRuleItem inboundRuleItem, string siteNameRestriction)
        {

            if (inboundRuleItem == null) return null;

            var conditionItems = GetBaseConditionItems(inboundRuleItem);
            //var serverVariableItems = GetServerVariableItems(inboundRuleItem);
            //var requestHeaderItems = GetRequestHeaderItems(inboundRuleItem);
            var responseHeaderItems = GetResponseHeaderItems(inboundRuleItem);

            var inboundRule = new InboundRule
            {
                ItemId = inboundRuleItem.ID.Guid,
                Name = inboundRuleItem.Name
            };

            SetBaseRule(inboundRuleItem.BaseRuleItem, inboundRule);

            if (string.IsNullOrEmpty(inboundRuleItem.BaseRuleItem.BaseMatchItem.MatchPatternItem.Pattern.Value))
            {
                Log.Warn(logObject, inboundRuleItem.Database, "No pattern set on rule with ItemID: {0}", inboundRuleItem.ID);

                return null;
            }

            if (inboundRuleItem.Action == null)
            {
                Log.Warn(logObject, inboundRuleItem.Database, "No action set on rule with ItemID: {0}", inboundRuleItem.ID);

                return null;
            }

            var baseActionItem = inboundRuleItem.Action.TargetItem;
            IBaseAction baseAction = null;
            if (baseActionItem != null)
            {
                var baseActionItemTemplateId = baseActionItem.TemplateID.ToString();

                if (baseActionItemTemplateId.Equals(RedirectItem.TemplateId, StringComparison.InvariantCultureIgnoreCase))
                {
                    baseAction = new RedirectItem(baseActionItem).ToRedirectAction();
                }
                else if (baseActionItemTemplateId.Equals(RewriteItem.TemplateId,
                    StringComparison.InvariantCultureIgnoreCase))
                {
                    baseAction = new RewriteItem(baseActionItem).ToRewriteAction();
                }
                else if (baseActionItemTemplateId.Equals(AbortRequestItem.TemplateId,
                    StringComparison.InvariantCultureIgnoreCase))
                {
                    baseAction = new AbortRequestItem(baseActionItem).ToAbortRequestAction();
                }
                else if (baseActionItemTemplateId.Equals(CustomResponseItem.TemplateId,
                    StringComparison.InvariantCultureIgnoreCase))
                {
                    baseAction = new CustomResponseItem(baseActionItem).ToCustomResponseAction();
                }
                else if (baseActionItemTemplateId.Equals(ItemQueryRedirectItem.TemplateId))
                {
                    baseAction = new ItemQueryRedirectItem(baseActionItem).ToItemQueryRedirectAction();
                }
            }
            inboundRule.Action = baseAction;

            if (conditionItems != null)
            {
                SetConditions(conditionItems, inboundRule);
            }

            //if (serverVariableItems != null)
            //{
            //    SetServerVariables(serverVariableItems, inboundRule);
            //}

            //if (requestHeaderItems != null)
            //{
            //    SetRequestHeaders(requestHeaderItems, inboundRule);
            //}

            if (responseHeaderItems != null)
            {
                SetResponseHeaders(responseHeaderItems, inboundRule);
            }

            inboundRule.SiteNameRestriction = siteNameRestriction;

            return inboundRule;
        }
예제 #4
0
        internal InboundRule CreateInboundRuleFromSimpleRedirectItem(SimpleRedirectItem simpleRedirectItem, RedirectFolderItem redirectFolderItem)
        {
            var inboundRulePattern = string.Format("^{0}/?$", simpleRedirectItem.Path.Value);

            var siteNameRestriction = GetSiteNameRestriction(redirectFolderItem);

            var redirectTo = simpleRedirectItem.Target;
            string actionRewriteUrl;
            Guid? redirectItem;
            string redirectItemAnchor;

            GetRedirectUrlOrItemId(redirectTo, out actionRewriteUrl, out redirectItem, out redirectItemAnchor);

            Log.Debug(this, simpleRedirectItem.Database, "Creating Inbound Rule From Simple Redirect Item - {0} - id: {1} actionRewriteUrl: {2} redirectItem: {3}", simpleRedirectItem.Name, simpleRedirectItem.ID.Guid, actionRewriteUrl, redirectItem);

            var inboundRule = new InboundRule
            {
                Action = new Redirect
                {
                    AppendQueryString = true,
                    Name = "Redirect",
                    StatusCode = RedirectStatusCode.Permanent,
                    RewriteUrl = actionRewriteUrl,
                    RewriteItemId = redirectItem,
                    RewriteItemAnchor = redirectItemAnchor,
                    StopProcessingOfSubsequentRules = false,
                    HttpCacheability = HttpCacheability.NoCache
                },
                SiteNameRestriction = siteNameRestriction,
                Enabled = simpleRedirectItem.BaseEnabledItem.Enabled.Checked,
                IgnoreCase = true,
                ItemId = simpleRedirectItem.ID.Guid,
                ConditionLogicalGrouping = LogicalGrouping.MatchAll,
                Name = simpleRedirectItem.Name,
                Pattern = inboundRulePattern,
                MatchType = MatchType.MatchesThePattern,
                Using = Using.RegularExpressions
            };

            return inboundRule;
        }
예제 #5
0
        private bool TestSiteNameRestriction(InboundRule inboundRule)
        {
            var currentSiteName = Sitecore.Context.Site.Name;
            bool isInboundRuleMatch = false;

            if (currentSiteName != null)
            {
                isInboundRuleMatch = currentSiteName.Equals(inboundRule.SiteNameRestriction,
                    StringComparison.InvariantCultureIgnoreCase);

                if (!isInboundRuleMatch)
                {
                    Log.Debug(this, "Regex - Rule '{0}' failed.  Site '{1}' does not equal rules site condition '{2}'",
                            inboundRule.Name, currentSiteName, inboundRule.SiteNameRestriction);
                }
                else
                {
                    Log.Debug(this, "Regex - Rule '{0}' matched site name restriction.  Site '{1}' equal rules site condition '{2}'",
                            inboundRule.Name, currentSiteName, inboundRule.SiteNameRestriction);
                }
            }
            else
            {
                Log.Warn(this, "Regex - Rule '{0}' matching based on site name will not occur because site name is null.",
                        inboundRule.Name);
            }

            return isInboundRuleMatch;
        }
예제 #6
0
        private bool TestRuleMatches(InboundRule inboundRule, Uri originalUri, out Match inboundRuleMatch)
        {
            var absolutePath = originalUri.AbsolutePath;
            var uriPath = absolutePath.Substring(1); // remove starting "/"

            var escapedAbsolutePath = HttpUtility.UrlDecode(absolutePath);
            var escapedUriPath = (escapedAbsolutePath ?? string.Empty).Substring(1); // remove starting "/"

            // TODO : I have only implemented "MatchesThePattern" - need to implement the other types
            var matchesThePattern = inboundRule.MatchType.HasValue &&
                                    inboundRule.MatchType.Value == MatchType.MatchesThePattern;

            if (!matchesThePattern)
            {
                throw new NotImplementedException(
                    "Have not yet implemented 'Does Not Match the Pattern' because of possible redirect loops");
            }

            var pattern = inboundRule.Pattern;

            if (inboundRule.Using.HasValue && inboundRule.Using.Value == Using.ExactMatch)
            {
                pattern = "^" + pattern + "$";
            }

            var inboundRuleRegex = new Regex(pattern, inboundRule.IgnoreCase ? RegexOptions.IgnoreCase : RegexOptions.None);

            inboundRuleMatch = inboundRuleRegex.Match(uriPath);
            bool isInboundRuleMatch = matchesThePattern ? inboundRuleMatch.Success : !inboundRuleMatch.Success;

            Log.Debug(this, "Regex - Pattern: '{0}' Input: '{1}' Success: {2}", pattern, uriPath,
                    isInboundRuleMatch);

            if (!isInboundRuleMatch && !uriPath.Equals(escapedUriPath, StringComparison.InvariantCultureIgnoreCase))
            {
                inboundRuleMatch = inboundRuleRegex.Match(escapedUriPath);
                isInboundRuleMatch = matchesThePattern ? inboundRuleMatch.Success : !inboundRuleMatch.Success;

                Log.Debug(this, "Regex - Pattern: '{0}' Input: '{1}' Success: {2}", pattern, escapedUriPath,
                        isInboundRuleMatch);
            }
            return isInboundRuleMatch;
        }
예제 #7
0
        private void ProcessRewriteAction(InboundRule inboundRule, Uri uri, Match inboundRuleMatch, Match lastConditionMatch, InboundRuleResult ruleResult)
        {
            var redirectAction = inboundRule.Action as Rewrite;

            var rewriteUrl = redirectAction.RewriteUrl;
            var rewriteItemId = redirectAction.RewriteItemId;
            var rewriteItemAnchor = redirectAction.RewriteItemAnchor;

            if (string.IsNullOrEmpty(rewriteUrl) && rewriteItemId == null)
            {
                ruleResult.RuleMatched = false;
                return;
            }

            if (rewriteItemId.HasValue)
            {
                rewriteUrl = GetRewriteUrlFromItemId(rewriteItemId.Value, rewriteItemAnchor);
            }

            // process token replacements
            var replacements = new RewriteHelper.Replacements
            {
                RequestHeaders = RequestHeaders,
                RequestServerVariables = RequestServerVariables
            };

            rewriteUrl = RewriteHelper.ReplaceTokens(replacements, rewriteUrl);

            if (redirectAction.AppendQueryString)
            {
                rewriteUrl += uri.Query;
            }

            rewriteUrl = RewriteHelper.ReplaceRuleBackReferences(inboundRuleMatch, rewriteUrl);
            rewriteUrl = RewriteHelper.ReplaceConditionBackReferences(lastConditionMatch, rewriteUrl);

            ruleResult.RewrittenUri = new Uri(rewriteUrl);
            ruleResult.StopProcessing = redirectAction.StopProcessingOfSubsequentRules;
        }
예제 #8
0
        private InboundRuleResult ProcessRegularExpressionInboundRule(Uri originalUri, InboundRule inboundRule)
        {
            var ruleResult = new InboundRuleResult
            {
                OriginalUri = originalUri,
                RewrittenUri = originalUri
            };

            Match inboundRuleMatch,
                lastConditionMatch = null;

            // test rule match
            var isInboundRuleMatch = TestRuleMatches(inboundRule, originalUri, out inboundRuleMatch);
            ConditionMatchResult conditionMatchResult = null;

            // test conditions matches
            if (isInboundRuleMatch && inboundRule.Conditions != null && inboundRule.Conditions.Any())
            {
                var replacements = new RewriteHelper.Replacements
                {
                    RequestHeaders = RequestHeaders,
                    RequestServerVariables = RequestServerVariables
                };

                conditionMatchResult = RewriteHelper.TestConditionMatches(inboundRule, replacements, out lastConditionMatch);
                isInboundRuleMatch = conditionMatchResult.Matched;
            }

            // test site name restrictions
            if (isInboundRuleMatch && !string.IsNullOrEmpty(inboundRule.SiteNameRestriction))
            {
                isInboundRuleMatch = TestSiteNameRestriction(inboundRule);
            }

            if (isInboundRuleMatch && inboundRule.Action != null)
            {
                ruleResult.RuleMatched = true;

                if (inboundRule.ResponseHeaders.Any())
                {
                    ruleResult.ResponseHeaders = inboundRule.ResponseHeaders;
                }

                Log.Debug(this, "INBOUND RULE MATCH - requestUri: {0} inboundRule: {1}", originalUri, inboundRule.Name);

                // TODO: Need to implement Rewrite, None

                if (inboundRule.Action is Redirect)
                {
                    ProcessRedirectAction(inboundRule, originalUri, inboundRuleMatch, lastConditionMatch, ruleResult);
                }
                else if (inboundRule.Action is Rewrite)
                {
                    ProcessRewriteAction(inboundRule, originalUri, inboundRuleMatch, lastConditionMatch, ruleResult);
                }
                else if (inboundRule.Action is ItemQueryRedirect)
                {
                    ProcessItemQueryRedirectAction(inboundRule, originalUri, inboundRuleMatch, lastConditionMatch, ruleResult);
                }
                else if (inboundRule.Action is AbortRequest || inboundRule.Action is CustomResponse)
                {
                    ProcessActionProcessing(ruleResult);
                }
                else
                {
                    throw new NotImplementedException("Redirect Action, Custome Response and Abort Reqeust Action are the only supported type of redirects");
                }

                ruleResult.ResultAction = inboundRule.Action;
                ruleResult.ConditionMatchResult = conditionMatchResult;
            }
            else if (inboundRule.Action == null)
            {
                Log.Warn(this, "Inbound Rule has no Action set - inboundRule: {0} inboundRule ItemId: {1}", inboundRule.Name, inboundRule.ItemId);

                // we are going to skip this because we don't know what to do with it during processing
                ruleResult.RuleMatched = false;
            }

            return ruleResult;
        }
예제 #9
0
        private void ProcessItemQueryRedirectAction(InboundRule inboundRule, Uri uri, Match inboundRuleMatch, Match lastConditionMatch, InboundRuleResult ruleResult)
        {
            var redirectAction = inboundRule.Action as ItemQueryRedirect;

            var itemQuery = redirectAction.ItemQuery;

            if (string.IsNullOrEmpty(itemQuery))
            {
                ruleResult.RuleMatched = false;
                return;
            }

            // process token replacements in the item query
            itemQuery = RewriteHelper.ReplaceRuleBackReferences(inboundRuleMatch, itemQuery);
            itemQuery = RewriteHelper.ReplaceConditionBackReferences(lastConditionMatch, itemQuery);

            var rewriteItemId = ExecuteItemQuery(itemQuery);

            if (!rewriteItemId.HasValue)
            {
                ruleResult.RuleMatched = false;
                return;
            }

            string rewriteUrl = GetRewriteUrlFromItemId(rewriteItemId.Value, null);

            // process token replacements
            var replacements = new RewriteHelper.Replacements
            {
                RequestHeaders = RequestHeaders,
                RequestServerVariables = RequestServerVariables
            };

            rewriteUrl = RewriteHelper.ReplaceTokens(replacements, rewriteUrl);
            rewriteUrl = RewriteHelper.ReplaceRuleBackReferences(inboundRuleMatch, rewriteUrl);
            rewriteUrl = RewriteHelper.ReplaceConditionBackReferences(lastConditionMatch, rewriteUrl);

            ruleResult.RewrittenUri = new Uri(rewriteUrl);
            ruleResult.StopProcessing = redirectAction.StopProcessingOfSubsequentRules;
        }
예제 #10
0
        private InboundRuleResult ProcessInboundRule(Uri originalUri, InboundRule inboundRule)
        {
            Log.Debug(this, "Processing inbound rule - requestUri: {0} inboundRule: {1}", originalUri, inboundRule.Name);

            var ruleResult = new InboundRuleResult
            {
                OriginalUri = originalUri,
                RewrittenUri = originalUri
            };

            switch (inboundRule.Using)
            {
                case Using.ExactMatch:
                case Using.RegularExpressions:
                case Using.Wildcards:
                    ruleResult = ProcessRegularExpressionInboundRule(ruleResult.OriginalUri, inboundRule);

                    break;
                //case Using.Wildcards:
                //    //TODO: Implement Wildcards
                //    throw new NotImplementedException("Using Wildcards has not been implemented");
                //    break;
            }

            Log.Debug(this, "Processing inbound rule - requestUri: {0} inboundRule: {1} rewrittenUrl: {2}", ruleResult.OriginalUri, inboundRule.Name, ruleResult.RewrittenUri);

            ruleResult.ItemId = inboundRule.ItemId;

            return ruleResult;
        }
예제 #11
0
        public void ProcessRequestUrlWithCustomResponse()
        {
            var rewriter = new InboundRewriter();
            var newInboundRule = new InboundRule()
            {
                Name = "Custom Response Rule",
                Pattern = "customresponse",
                Using = Using.ExactMatch,
                Action = new CustomResponse()
                {
                    Name = "Custom Response Action", 
                    StatusCode = 550, 
                    SubStatusCode = 100, 
                    ErrorDescription = "Custom Response Because I Said So", 
                    Reason = "Custom Response 550"
                },
                MatchType = MatchType.MatchesThePattern
            };

            InboundRules.Insert(0, newInboundRule);

            var rewriteResult = rewriter.ProcessRequestUrl(new Uri("http://fictitioussite.com/customresponse"), InboundRules);
            var customResponse = rewriteResult.FinalAction as CustomResponse;

            Assert.IsNotNull(customResponse);
            Assert.AreEqual(customResponse.StatusCode, 550);
            Assert.AreEqual(customResponse.SubStatusCode, 100);
            Assert.IsTrue(rewriteResult.ProcessedResults.Count == 1);
        }