private static void AddConditionsToRule(List <ConditionEntry> conditions, RuleEntry rule) { string text = null; int num = 0; foreach (ConditionEntry conditionEntry in conditions) { if (conditionEntry.ErrorInfo != null) { text = conditionEntry.ErrorInfo.Message; } if (conditionEntry.IsOr) { num++; } } if (num > 0) { if (num == conditions.Count || (num == conditions.Count - 1 && !conditions[conditions.Count - 1].IsOr)) { rule.ConditionsLogicalGrouping = LogicalGrouping.MatchAny; } else { rule.ErrorInfo = new ErrorInfo("This rule was not converted because only some of the conditions are using the OR flag."); } } if (text != null) { rule.HasErrorInConditions = true; } if (conditions != null) { foreach (ConditionEntry item in conditions) { rule.Conditions.Add(item); } } }
public static RewriteEntry Translate(string input, bool isServerLevel, int baseNumber) { Parser parser = new Parser(input); IList <Parser.RawEntry> list = parser.Parse(); RewriteEntry rewriteEntry = new RewriteEntry(null, isServerLevel); List <CommentEntry> list2 = null; bool flag = false; List <ConditionEntry> list3 = null; for (int i = 0; i < list.Count; i++) { Parser.RawEntry rawEntry = list[i]; if (rawEntry is Parser.RawCondition) { if (list3 == null) { list3 = new List <ConditionEntry>(); } ConditionEntry conditionEntry = ConditionLogic.Create((Parser.RawCondition)rawEntry); if (list2 != null) { conditionEntry.Comments.AddRange(list2); list2 = null; } list3.Add(conditionEntry); } else if (rawEntry is Parser.RawRule) { RuleEntry ruleEntry = RuleLogic.Create(rewriteEntry, (Parser.RawRule)rawEntry, isServerLevel); ruleEntry.Name = string.Format(CultureInfo.InvariantCulture, "Imported Rule {0}", rewriteEntry.Rules.Count + baseNumber + 1); if (list3 != null) { AddConditionsToRule(list3, ruleEntry); } list3 = null; if (flag || ruleEntry.IsChained) { ruleEntry.ErrorInfo = new ErrorInfo("This rule was not converted because it is chained to other rules."); flag = ruleEntry.IsChained; } if (list2 != null) { ruleEntry.Comments.AddRange(list2); list2 = null; } rewriteEntry.Rules.Add(ruleEntry); } else if (rawEntry is Parser.RawComment) { if (list2 == null) { list2 = new List <CommentEntry>(); } list2.Add(new CommentEntry((Parser.RawComment)rawEntry)); } else if (rawEntry is Parser.RawRuleEngine) { TranslateRuleEngine(rewriteEntry, rawEntry); } else if (rawEntry is Parser.UnsupportedDirective) { rewriteEntry.UnsupportedDirectives.Add(new UnsupportedDirectiveEntry((Parser.UnsupportedDirective)rawEntry)); } } return(rewriteEntry); }
internal static RuleEntry Create(RewriteEntry rewrite, Parser.RawRule rawRule, bool isServerLevel) { RuleEntry ruleEntry = new RuleEntry(rawRule); if (rewrite.EnabledSet && !rewrite.Enabled) { ruleEntry.Enabled = false; } ErrorInfo errorInfo = null; if (!string.IsNullOrEmpty(rawRule.Pattern)) { ruleEntry.MatchNegate = rawRule.Pattern.StartsWith("!", StringComparison.Ordinal); if (!ruleEntry.MatchNegate) { ruleEntry.MatchUrl = RuleLogic.SanitizePattern(rawRule.Pattern, isServerLevel, ref errorInfo); } else { ruleEntry.MatchUrl = RuleLogic.SanitizePattern(rawRule.Pattern.Substring(1), isServerLevel, ref errorInfo); } } ruleEntry.ActionType = ActionType.Rewrite; ruleEntry.ActionUrl = RuleLogic.SanitizeActionUrl(rawRule.Substitution, ref errorInfo); bool flag = false; if (!string.IsNullOrEmpty(rawRule.Flags)) { string text = rawRule.Flags.Substring(1, rawRule.Flags.Length - 2); string[] array = text.Split(new char[] { ',' }); for (int i = 0; i < array.Length; i++) { string text2 = array[i]; int num = text2.IndexOf('='); if (num != -1) { text2 = text2.Substring(0, num).Trim(); } if (RuleLogic.Is(text2, "F") || RuleLogic.Is(text2, "forbidden")) { ruleEntry.ActionType = ActionType.CustomResponse; ruleEntry.StatusCode = 403L; ruleEntry.SubStatusCode = 0L; ruleEntry.StatusReason = "Forbidden"; ruleEntry.StatusDescription = "Forbidden"; } else if (RuleLogic.Is(text2, "Gone") || RuleLogic.Is(text2, "G")) { ruleEntry.ActionType = ActionType.CustomResponse; ruleEntry.StatusCode = 410L; ruleEntry.SubStatusCode = 0L; ruleEntry.StatusReason = "Gone"; ruleEntry.StatusDescription = "The URL is gone"; } else if (RuleLogic.Is(text2, "L") || RuleLogic.Is(text2, "last")) { ruleEntry.StopProcessing = true; } else if (RuleLogic.Is(text2, "nocase") || RuleLogic.Is(text2, "nc") || RuleLogic.Is(text2, "I")) { ruleEntry.MatchIgnoreCase = true; } else if (RuleLogic.Is(text2, "Proxy") || RuleLogic.Is(text2, "P")) { flag = true; ruleEntry.ActionType = ActionType.Rewrite; ruleEntry.StopProcessing = true; if (string.IsNullOrEmpty(ruleEntry.ActionUrl)) { ruleEntry.ActionUrl = "{R:0}"; } } else if (RuleLogic.Is(text2, "QSA") || RuleLogic.Is(text2, "qsappend")) { ruleEntry.ActionAppendQueryString = true; } else if (RuleLogic.Is(text2, "redirect") || RuleLogic.Is(text2, "r") || RuleLogic.Is(text2, "RP")) { flag = true; ruleEntry.ActionType = ActionType.Redirect; if (num != -1) { string value = array[i].Substring(num + 1).Trim(); if (RuleLogic.Is(value, "permanent") || RuleLogic.Is(value, "301")) { ruleEntry.ActionRedirectType = RedirectType.Permanent; } else if (RuleLogic.Is(value, "302") || RuleLogic.Is(value, "Found")) { ruleEntry.ActionRedirectType = RedirectType.Found; } else if (RuleLogic.Is(value, "303") || RuleLogic.Is(value, "seeother")) { ruleEntry.ActionRedirectType = RedirectType.SeeOther; } else { ruleEntry.ActionRedirectType = RedirectType.Temporary; } } if (string.IsNullOrEmpty(ruleEntry.ActionUrl)) { ruleEntry.ActionUrl = "{R:0}"; } } else if (RuleLogic.Is(text2, "cookie") || RuleLogic.Is(text2, "co") || RuleLogic.Is(text2, "env") || RuleLogic.Is(text2, "e") || RuleLogic.Is(text2, "noescape") || RuleLogic.Is(text2, "ne") || RuleLogic.Is(text2, "nosubreq") || RuleLogic.Is(text2, "ns") || RuleLogic.Is(text2, "type") || RuleLogic.Is(text2, "t")) { errorInfo = new ErrorInfo(string.Format(CultureInfo.InvariantCulture, "The rule cannot be converted into an equivalent IIS format because of unsupported flags: {0}", text2)); } else if (RuleLogic.Is(text2, "chain") || RuleLogic.Is(text2, "c")) { ruleEntry.IsChained = true; } else { if (RuleLogic.Is(text2, "skip") || RuleLogic.Is(text2, "s") || RuleLogic.Is(text2, "next") || RuleLogic.Is(text2, "n")) { throw new NotSupportedException("The rule set cannot be converted into an equivalent IIS format because control flow flags (C, S, N) are not supported."); } if (!RuleLogic.Is(text2, "passthrough") && !RuleLogic.Is(text2, "PT")) { errorInfo = new ErrorInfo(string.Format(CultureInfo.InvariantCulture, "The rule contains a control flag that is not recognized: {0}.", text2), true); } } } } if (string.IsNullOrEmpty(ruleEntry.ActionUrl) && ruleEntry.ActionType == ActionType.Rewrite) { ruleEntry.ActionType = ActionType.None; } if (!ruleEntry.ActionAppendQueryString && ruleEntry.ActionUrl != null && ruleEntry.ActionUrl.IndexOf('?') != -1) { ruleEntry.ActionAppendQueryString = false; } if (!flag && !string.IsNullOrEmpty(ruleEntry.ActionUrl) && (ruleEntry.ActionUrl.StartsWith("http://", StringComparison.OrdinalIgnoreCase) || ruleEntry.ActionUrl.StartsWith("https://", StringComparison.OrdinalIgnoreCase))) { ruleEntry.ActionType = ActionType.Redirect; ruleEntry.ActionRedirectType = RedirectType.Found; } if (errorInfo != null) { ruleEntry.ErrorInfo = errorInfo; } return(ruleEntry); }