//TODO would want this for unit tests to be easily loaded from a collection...
        public virtual string GetSampleValue(string variable, RedirectData data)
        {
            if (LookupDictionary != null && LookupDictionary.ContainsKey(variable))
            {
                return LookupDictionary[variable](data);
            }

            switch (variable)
            {
                case "HTTP_TRUE_CLIENT_IP":
                    return GetRandom(IpExamples);
                case "HTTP_HOST":
                case "HTTP:Host":
                    return data.OriginalUrl.Host;
                case "HTTP:User-Agent":
                    return GetRandom(UserAgentExamples);
                case "REQUEST_METHOD":
                    return "GET";
                case "HTTPS":
                    return data.OriginalUrl.OriginalString.StartsWith("https") ? "ON" : "OFF";
                case "SERVER_PORT":
                    return data.OriginalUrl.Port.ToString();
                case "QUERY_STRING":
                    return data.OriginalUrl.Query;
                case "HTTP:Referer":
                    return GetRandom(ReferrerExamples);
                case "REQUEST_URI":
                    return data.OriginalUrl.OriginalString;
            }
            throw new Exception("Unknown variable: " + variable);
        }
示例#2
0
        public bool ProcessConditions(ref RedirectData data)
        {
            //Default to true
            if (Conditions == null)
            {
                return(true);
            }

            foreach (var c in Conditions)
            {
                try
                {
                    if (!c.MatchesCondition(ref data))
                    {
                        return(false);
                    }
                }
                catch (Exception ex)
                {
                    throw new Exception("Failed processing condition from line: " + c.LineNumber, ex);
                }
            }
            //data.RuleSetMatched = this;
            return(true);
        }
示例#3
0
        public RedirectData ProcessRules(RedirectData data)
        {
            foreach (var rule in Rules)
            {
                try
                {
                    data = rule.ProcessRule(data);
                    switch (data.Status)
                    {
                    case RedirectStatus.NotProcessed:
                        //case RedirectStatus.Continue:
                        continue;

                    case RedirectStatus.Modified:
                        data.RuleSetMatched = this;
                        continue;

                    case RedirectStatus.Redirected:
                        data.RuleSetMatched = this;
                        break;

                    default:
                        throw new Exception("Unknown RedirectStatus... code needs to be updated: " + data.Status.ToString());
                    }
                }
                catch (Exception ex)
                {
                    throw new Exception("Failed processing rule from line: " + rule.LineNumber, ex);
                }
            }
            return(data);
        }
        public string BuildOutputUrl(RedirectData data)
        {
            var ruleMatches = data.RuleMatchGroups ?? new List<string>();
            var conditionMatches = data.ConditionMatchGroups ?? new List<string>();

            var processedUrl = Regex.Replace(ReplacePattern, @"(\$\d|%\d|\$\$\d\d|%%\d\d)", match => Evaluator(match, ruleMatches, conditionMatches));
            return Options_PostProcessing(processedUrl);
        }
        public string BuildOutputUrl(RedirectData data)
        {
            var ruleMatches      = data.RuleMatchGroups ?? new List <string>();
            var conditionMatches = data.ConditionMatchGroups ?? new List <string>();

            var processedUrl = Regex.Replace(ReplacePattern, @"(\$\d|%\d|\$\$\d\d|%%\d\d)", match => Evaluator(match, ruleMatches, conditionMatches));

            return(Options_PostProcessing(processedUrl));
        }
        //TODO all these tests could be moved into this...
        public static void BuildAndTestConditions(IEnumerable<string> lines, string originalUrl, bool matchesCond, bool matchesRule, string expectedUrl, int? expectedRuleCount = null)
        {
            var samples = new RandomSampleValues();
            var factory = new RewriteFactory(samples);
            var lineNum = 1;
            var redirects = lines.Select(l => factory.Build(lineNum++, l));
            var ruleSet = RewriteRuleSet.BuildRuleSets(redirects);
            var redirectData = new RedirectData(originalUrl);

            TestConditions(matchesCond, matchesRule, null, expectedUrl, ruleSet, redirectData);
        }
        public bool MatchesCondition(ref RedirectData data)
        {
            string testString = data.OriginalUrl.PathAndQuery;
            if (Variable != null) testString = _values.GetSampleValue(Variable, data);

            var m = Regex.Match(testString, MatchPattern);
            if (m.Success)
            {
                data.ConditionMatchGroups = m.Groups.Cast<Group>()
                                             .Select(a => a.Value).ToList();
            }
            return m.Success;
        }
        public RedirectData TestUrl(string url)
        {
            if (RulesSets == null) throw new Exception("Did you forget to call LoadConfig?");

            var data = new RedirectData(url);
            var matchesRuleSets = RulesSets.Where(r => r.ProcessConditions(ref data));

            foreach (var rule in matchesRuleSets)
            {
                data = rule.ProcessRules(data);
                if (data.Status == RedirectStatus.Redirected)
                    break;
            }
            return data;
        }
示例#9
0
        public bool MatchesCondition(ref RedirectData data)
        {
            string testString = data.OriginalUrl.PathAndQuery;

            if (Variable != null)
            {
                testString = _values.GetSampleValue(Variable, data);
            }

            var m = Regex.Match(testString, MatchPattern);

            if (m.Success)
            {
                data.ConditionMatchGroups = m.Groups.Cast <Group>()
                                            .Select(a => a.Value).ToList();
            }
            return(m.Success);
        }
        public bool ProcessConditions(ref RedirectData data)
        {
            //Default to true
            if (Conditions == null) return true;

            foreach (var c in Conditions)
            {
                try
                {
                    if (!c.MatchesCondition(ref data)) return false;
                }
                catch (Exception ex)
                {
                    throw new Exception("Failed processing condition from line: " + c.LineNumber, ex);
                }
            }
            //data.RuleSetMatched = this;
            return true;
        }
        public void Https_test_cases(string originalUrl, bool matchesCond, bool matchesRule, string expectedUrl)
        {
            //Arrange
            var samples = new RandomSampleValues();
            var factory = new RewriteFactory(samples);
            string[] lines =
            {
                @"# Force SSL for pages that request personally-identifiable information",
                @"RewriteCond %{HTTPS} ^(?!on).*$",
                @"RewriteCond %{SERVER_PORT} ^80$",
                @"RewriteCond %{HTTP:Host} (.*)",
                @"RewriteRule ^(/ltl-freight)(.*)$ https\://%1$1 [NC,R=301]",
            };
            var lineNum = 1;
            var redirects = lines.Select(l => factory.Build(lineNum++, l));
            var ruleSet = RewriteRuleSet.BuildRuleSets(redirects);
            var redirectData = new RedirectData(originalUrl);

            TestConditions(matchesCond, matchesRule, 1, expectedUrl, ruleSet, redirectData);
        }
        public RedirectData ProcessRule(RedirectData data)
        {
            //TODO actually this is the OriginalString when condition checks that... or something
            //WTF am i saying above... i think i want ProcessedUrl since that will default back to Original if not changed (i.e. its "CurrentUrl")
            var m = Regex.Match(data.CurrentPathAndQuery, MatchPattern, Options_Regex());

            if (m.Success)
            {
                data.RuleMatchGroups = m.Groups.Cast <Group>()
                                       .Select(a => a.Value).ToList();

                data.ProcessedUrl = BuildOutputUrl(data);

                if ((Options & RuleOptions.FINISHED) > 0 &&
                    data.OriginalUrl.OriginalString != data.ProcessedUrl)
                {
                    data.Status = RedirectStatus.Redirected;
                    data.SetUrlChanged();
                }
                else if (data.OriginalUrl.OriginalString != data.ProcessedUrl)
                {
                    data.Status = RedirectStatus.Modified;
                    data.SetUrlChanged();
                }
                else
                {
                    //Is this CURRENT status? - yes
                    data.Status = RedirectStatus.NotProcessed;
                }
            }
            else
            {
                //Is this CURRENT status? - yes
                data.Status = RedirectStatus.NotProcessed;
            }
            return(data);
        }
        public RedirectData ProcessRule(RedirectData data)
        {
            //TODO actually this is the OriginalString when condition checks that... or something
            //WTF am i saying above... i think i want ProcessedUrl since that will default back to Original if not changed (i.e. its "CurrentUrl")
            var m = Regex.Match(data.CurrentPathAndQuery, MatchPattern, Options_Regex());
            if (m.Success)
            {
                data.RuleMatchGroups = m.Groups.Cast<Group>()
                                        .Select(a => a.Value).ToList();

                data.ProcessedUrl = BuildOutputUrl(data);

                if ((Options & RuleOptions.FINISHED) > 0
                    && data.OriginalUrl.OriginalString != data.ProcessedUrl)
                {
                    data.Status = RedirectStatus.Redirected;
                    data.SetUrlChanged();
                }
                else if (data.OriginalUrl.OriginalString != data.ProcessedUrl)
                {
                    data.Status = RedirectStatus.Modified;
                    data.SetUrlChanged();
                }
                else
                {
                    //Is this CURRENT status? - yes
                    data.Status = RedirectStatus.NotProcessed;
                }
            }
            else
            {
                //Is this CURRENT status? - yes
                data.Status = RedirectStatus.NotProcessed;
            }
            return data;
        }
        public void Pricing_index_page_urls(string originalUrl, bool matchesCond, bool matchesRule, string expectedUrl)
        {
            //Arrange
            var samples = new RandomSampleValues();
            var factory = new RewriteFactory(samples);
            string[] lines =
                {
                    @"RewriteCond %{HTTP:Host} ^directory[2]?\.uship\.com$",
                    @"RewriteRule ^/tips/showtip.aspx(.*)$ http://www.uship.com/tips/showtip.aspx$1 [NC,R=301]",
                    @"",
                    @"# ...",
                    @"",
                    @"# Listing Index",
                    @"RewriteRule ^/pricing/((?:[a-z]|[-])+)/((?:[a-z]|[-])+)(?:/page/([0-9]+))? /listingindex/PricingCommodity.aspx?c=$1&c2=$2&page=$3 [NC,L]",
                    @"RewriteRule ^/pricing/((?:[a-z]|[-])+)(?:/page/([0-9]+))? /listingindex/PricingCommodity.aspx?c=$1&page=$2 [NC,L]",
                    @"RewriteRule ^/pricing/?$ /listingindex/?c=4&c2=79 [NC,L]"
                };
            var lineNum = 1;
            var redirects = lines.Select(l => factory.Build(lineNum++, l));
            var ruleSet = RewriteRuleSet.BuildRuleSets(redirects);
            var redirectData = new RedirectData(originalUrl);

            TestConditions(matchesCond, matchesRule, 3, expectedUrl, ruleSet, redirectData);
        }
        public void Single_ruleset_should_manually_work_as_expected(string originalUrl, bool matchesCond, bool matchesRule, string expectedUrl)
        {
            //Arrange
            //TODO use structure map for getting the instance???:
            var samples = new RandomSampleValues();
            var factory = new RewriteFactory(samples);
            string[] lines =
                {
                    @"RewriteCond %{HTTP:Host} ^(movers|household-goods|vehicles|boats|motorcycles|special-care|freight|pets-livestock|food-agriculture|junk|craigslist)[2]?\.uship\.com$",
                    @"RewriteRule ^(?!.+\.axd|.+\.ashx|public/images|sticky/images)/([^?]*\u.*)/?(?:[^?]*\u.*)?$ /$1 [CL,R=301]"
                };
            var redirectData = new RedirectData(originalUrl);

            //Act
            var lineNum = 1;
            var redirects = lines.Select(l => factory.Build(lineNum++, l));

            //Assert
            var redirectLines = redirects as IList<IRedirectLine> ?? redirects.ToList();
            redirectLines.Count().Should().Be(2);

            var cond = (RewriteCondition) redirectLines.Single(x => x.LineType == RedirectLineType.Condition);
            cond.Variable.Should().Be("HTTP:Host");
            cond.MatchesCondition(ref redirectData).Should().Be(matchesCond);
            if (matchesCond)
            {
                var rule = (RewriteRule) redirectLines.Single(x => x.LineType == RedirectLineType.Rule);
                redirectData = rule.ProcessRule(redirectData);
                if (matchesRule)
                {
                    redirectData.Status.Should().NotBe(RedirectStatus.NotProcessed);
                    redirectData.ProcessedUrl.Should().Be(expectedUrl);
                }
                else
                {
                    redirectData.Status.Should().Be(RedirectStatus.NotProcessed);
                }
            }
        }
        public void Single_ruleset_should_object_work_as_expected(string originalUrl, bool matchesCond, bool matchesRule, string expectedUrl)
        {
            //Arrange
            var samples = new RandomSampleValues();
            var factory = new RewriteFactory(samples);
            string[] lines =
                {
                    @"RewriteCond %{HTTP:Host} ^(movers|household-goods|vehicles|boats|motorcycles|special-care|freight|pets-livestock|food-agriculture|junk|craigslist)[2]?\.uship\.com$",
                    @"RewriteRule ^(?!.+\.axd|.+\.ashx|public/images|sticky/images)/([^?]*\u.*)/?(?:[^?]*\u.*)?$ /$1 [CL,R=301]"
                };
            var lineNum = 1;
            var redirects = lines.Select(l => factory.Build(lineNum++, l));
            var ruleSet = RewriteRuleSet.BuildRuleSets(redirects);
            var redirectData = new RedirectData(originalUrl);

            TestConditions(matchesCond, matchesRule, 1, expectedUrl, ruleSet, redirectData);
        }
        private static void TestConditions(bool matchesCond, bool matchesRule, int? expectedRuleCount, string expectedUrl, IEnumerable<RewriteRuleSet> ruleSet, RedirectData redirectData)
        {
            //Act
            var matchingSets = ruleSet.Where(r => r.ProcessConditions(ref redirectData));
            var rewriteRuleSets = matchingSets as IList<RewriteRuleSet> ?? matchingSets.ToList();

            //Assert
            if (matchesCond)
            {
                if (expectedRuleCount != null) rewriteRuleSets.Count().Should().Be(expectedRuleCount);
                //TODO this should be a method on RewriteRuleSetCollection...
                foreach (var rs in rewriteRuleSets)
                {
                    redirectData = rs.ProcessRules(redirectData);
                    if (redirectData.Status == RedirectStatus.Redirected)
                        break;
                }

                if (matchesRule)
                {
                    //TODO add an option for LAST RULE too?
                    //redirectData.Status.Should().NotBe(RedirectStatus.NotProcessed);
                    redirectData.WasRedirected.Should().BeTrue("Was NOT processed when it should have been");
                    redirectData.ProcessedUrl.Should().Be(expectedUrl);
                }
                else
                {
                    //redirectData.Status.Should().Be(RedirectStatus.NotProcessed);
                    redirectData.WasRedirected.Should().BeFalse("Was processed when it should NOT have been");
                    if (expectedUrl != null) redirectData.ProcessedUrl.Should().Be(expectedUrl);
                }
            }
            else
            {
                rewriteRuleSets.Count().Should().Be(0);
            }
        }
        public void Vortal_rewrites_alone_should_go_to_correct_domain(string originalUrl, bool matchesCond, bool matchesRule, string expectedUrl)
        {
            //Arrange
            var samples = new RandomSampleValues();
            var factory = new RewriteFactory(samples);
            string[] lines =
                {
                    @"RewriteCond %{HTTP:Host} ^(movers|vehicles|boats|motorcycles|freight)\.uship\.com$",
                    @"RewriteRule ^/(.+)$ http://www.uship.com/%1/$1 [CL,NC,R=301]",
                    @"",
                    @"RewriteCond %{HTTP:Host} ^pets-livestock\.uship\.com$",
                    @"RewriteRule ^/(.+)$ http://www.uship.com/pet-shipping/$1 [CL,NC,R=301]",
                    @"",
                    @"RewriteCond %{HTTP:Host} ^household-goods\.uship\.com$",
                    @"RewriteRule ^/(.+)$ http://www.uship.com/furniture/$1 [CL,NC,R=301]",
                    @"",
                    @"# 301 these lortals to their vortals, these lortals will not exist",
                    @"RewriteCond %{HTTP:Host} ^(craigslist|special-care|junk|food)(?:-agriculture)?\.uship\.com$",
                    @"RewriteRule ^/(.+)$ http://www.uship.com/%1/ [CL,NC,R=301]"
                };
            var lineNum = 1;
            var redirects = lines.Select(l => factory.Build(lineNum++, l));
            var ruleSet = RewriteRuleSet.BuildRuleSets(redirects);
            var redirectData = new RedirectData(originalUrl);

            TestConditions(matchesCond, matchesRule, 1, expectedUrl, ruleSet, redirectData);
        }
 public RedirectData ProcessRules(RedirectData data)
 {
     foreach (var rule in Rules)
     {
         try
         {
             data = rule.ProcessRule(data);
             switch (data.Status)
             {
                 case RedirectStatus.NotProcessed:
                 //case RedirectStatus.Continue:
                     continue;
                 case RedirectStatus.Modified:
                     data.RuleSetMatched = this;
                     continue;
                 case RedirectStatus.Redirected:
                     data.RuleSetMatched = this;
                     break;
                 default:
                     throw new Exception("Unknown RedirectStatus... code needs to be updated: " + data.Status.ToString());
             }
         }
         catch (Exception ex)
         {
             throw new Exception("Failed processing rule from line: " + rule.LineNumber, ex);
         }
     }
     return data;
 }