Parsers are now non-static (when appropriate)

This commit is contained in:
Justin Kotalik 2016-08-18 10:18:15 -07:00
parent 7a56073835
commit d1ab35db87
26 changed files with 149 additions and 138 deletions

View File

@ -44,7 +44,7 @@ namespace Microsoft.AspNetCore.Rewrite
public static RewriteOptions RewriteRule(this RewriteOptions options, string regex, string onMatch, bool stopProcessing) public static RewriteOptions RewriteRule(this RewriteOptions options, string regex, string onMatch, bool stopProcessing)
{ {
var builder = new UrlRewriteRuleBuilder(); var builder = new UrlRewriteRuleBuilder();
var pattern = InputParser.ParseInputString(onMatch); var pattern = new InputParser().ParseInputString(onMatch);
builder.AddUrlMatch(regex); builder.AddUrlMatch(regex);
builder.AddUrlAction(pattern, actionType: ActionType.Rewrite, stopProcessing: stopProcessing); builder.AddUrlAction(pattern, actionType: ActionType.Rewrite, stopProcessing: stopProcessing);
@ -60,7 +60,7 @@ namespace Microsoft.AspNetCore.Rewrite
public static RewriteOptions RedirectRule(this RewriteOptions options, string regex, string onMatch, int statusCode, bool stopProcessing) public static RewriteOptions RedirectRule(this RewriteOptions options, string regex, string onMatch, int statusCode, bool stopProcessing)
{ {
var builder = new UrlRewriteRuleBuilder(); var builder = new UrlRewriteRuleBuilder();
var pattern = InputParser.ParseInputString(onMatch); var pattern = new InputParser().ParseInputString(onMatch);
builder.AddUrlMatch(regex); builder.AddUrlMatch(regex);
builder.AddUrlAction(pattern, actionType: ActionType.Redirect, stopProcessing: stopProcessing); builder.AddUrlAction(pattern, actionType: ActionType.Redirect, stopProcessing: stopProcessing);

View File

@ -10,6 +10,7 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.CodeRules
{ {
public int? SSLPort { get; set; } public int? SSLPort { get; set; }
public int StatusCode { get; set; } public int StatusCode { get; set; }
public override RuleResult ApplyRule(RewriteContext context) public override RuleResult ApplyRule(RewriteContext context)
{ {
if (!context.HttpContext.Request.IsHttps) if (!context.HttpContext.Request.IsHttps)

View File

@ -10,6 +10,7 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.CodeRules
public bool stopProcessing { get; set; } public bool stopProcessing { get; set; }
public int? SSLPort { get; set; } public int? SSLPort { get; set; }
public override RuleResult ApplyRule(RewriteContext context) public override RuleResult ApplyRule(RewriteContext context)
{ {
if (!context.HttpContext.Request.IsHttps) if (!context.HttpContext.Request.IsHttps)

View File

@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using Microsoft.AspNetCore.Rewrite.Internal;
namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
{ {
@ -10,7 +9,7 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
/// Parses the "CondPattern" portion of the RewriteCond. /// Parses the "CondPattern" portion of the RewriteCond.
/// RewriteCond TestString CondPattern /// RewriteCond TestString CondPattern
/// </summary> /// </summary>
public static class ConditionPatternParser public class ConditionPatternParser
{ {
private const char Not = '!'; private const char Not = '!';
private const char Dash = '-'; private const char Dash = '-';
@ -26,7 +25,7 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
/// </summary> /// </summary>
/// <param name="condition">The CondPattern portion of a mod_rewrite RewriteCond.</param> /// <param name="condition">The CondPattern portion of a mod_rewrite RewriteCond.</param>
/// <returns>A new parsed condition.</returns> /// <returns>A new parsed condition.</returns>
public static ParsedModRewriteInput ParseActionCondition(string condition) public ParsedModRewriteInput ParseActionCondition(string condition)
{ {
if (condition == null) if (condition == null)
{ {
@ -39,7 +38,7 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
throw new FormatException(Resources.FormatError_InputParserUnrecognizedParameter(condition, context.Index)); throw new FormatException(Resources.FormatError_InputParserUnrecognizedParameter(condition, context.Index));
} }
// If we hit a !, make sure the condition is inverted when resolving the string // If we hit a !, invert the condition
if (context.Current == Not) if (context.Current == Not)
{ {
results.Invert = true; results.Invert = true;
@ -139,7 +138,7 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
/// <param name="context"></param> /// <param name="context"></param>
/// <param name="invert"></param> /// <param name="invert"></param>
/// <returns></returns> /// <returns></returns>
public static ParsedModRewriteInput ParseProperty(ParserContext context, bool invert) private static ParsedModRewriteInput ParseProperty(ParserContext context, bool invert)
{ {
if (!context.Next()) if (!context.Next())
{ {

View File

@ -15,6 +15,14 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
var rules = new List<Rule>(); var rules = new List<Rule>();
var builder = new RuleBuilder(); var builder = new RuleBuilder();
var lineNum = 0; var lineNum = 0;
// parsers
var testStringParser = new TestStringParser();
var conditionParser = new ConditionPatternParser();
var regexParser = new RuleRegexParser();
var flagsParser = new FlagParser();
var tokenizer = new Tokenizer();
while ((line = input.ReadLine()) != null) while ((line = input.ReadLine()) != null)
{ {
lineNum++; lineNum++;
@ -26,7 +34,7 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
{ {
continue; continue;
} }
var tokens = Tokenizer.Tokenize(line); var tokens = tokenizer.Tokenize(line);
if (tokens.Count > 4) if (tokens.Count > 4)
{ {
// This means the line didn't have an appropriate format, throw format exception // This means the line didn't have an appropriate format, throw format exception
@ -40,13 +48,13 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
case "RewriteCond": case "RewriteCond":
try try
{ {
var pattern = TestStringParser.Parse(tokens[1]); var pattern = testStringParser.Parse(tokens[1]);
var condActionParsed = ConditionPatternParser.ParseActionCondition(tokens[2]); var condActionParsed = conditionParser.ParseActionCondition(tokens[2]);
var flags = new Flags(); var flags = new Flags();
if (tokens.Count == 4) if (tokens.Count == 4)
{ {
flags = FlagParser.Parse(tokens[3]); flags = flagsParser.Parse(tokens[3]);
} }
builder.AddConditionFromParts(pattern, condActionParsed, flags); builder.AddConditionFromParts(pattern, condActionParsed, flags);
@ -59,14 +67,17 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
case "RewriteRule": case "RewriteRule":
try try
{ {
var regex = RuleRegexParser.ParseRuleRegex(tokens[1]); var regex = regexParser.ParseRuleRegex(tokens[1]);
var pattern = TestStringParser.Parse(tokens[2]); var pattern = testStringParser.Parse(tokens[2]);
// TODO see if we can have flags be null. Flags flags;
var flags = new Flags();
if (tokens.Count == 4) if (tokens.Count == 4)
{ {
flags = FlagParser.Parse(tokens[3]); flags = flagsParser.Parse(tokens[3]);
}
else
{
flags = new Flags();
} }
builder.AddMatch(regex, flags); builder.AddMatch(regex, flags);

View File

@ -2,22 +2,68 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using System.Collections.Generic;
namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
{ {
public class FlagParser public class FlagParser
{ {
public static Flags Parse(string flagString) private readonly IDictionary<string, FlagType> _ruleFlagLookup = new Dictionary<string, FlagType>(StringComparer.OrdinalIgnoreCase) {
{ "b", FlagType.EscapeBackreference},
{ "c", FlagType.Chain },
{ "chain", FlagType.Chain},
{ "co", FlagType.Cookie },
{ "cookie", FlagType.Cookie },
{ "dpi", FlagType.DiscardPath },
{ "discardpath", FlagType.DiscardPath },
{ "e", FlagType.Env},
{ "env", FlagType.Env},
{ "end", FlagType.End },
{ "f", FlagType.Forbidden },
{ "forbidden", FlagType.Forbidden },
{ "g", FlagType.Gone },
{ "gone", FlagType.Gone },
{ "h", FlagType.Handler },
{ "handler", FlagType.Handler },
{ "l", FlagType.Last },
{ "last", FlagType.Last },
{ "n", FlagType.Next },
{ "next", FlagType.Next },
{ "nc", FlagType.NoCase },
{ "nocase", FlagType.NoCase },
{ "ne", FlagType.NoEscape },
{ "noescape", FlagType.NoEscape },
{ "ns", FlagType.NoSubReq },
{ "nosubreq", FlagType.NoSubReq },
{ "p", FlagType.Proxy },
{ "proxy", FlagType.Proxy },
{ "pt", FlagType.PassThrough },
{ "passthrough", FlagType.PassThrough },
{ "qsa", FlagType.QSAppend },
{ "qsappend", FlagType.QSAppend },
{ "qsd", FlagType.QSDiscard },
{ "qsdiscard", FlagType.QSDiscard },
{ "qsl", FlagType.QSLast },
{ "qslast", FlagType.QSLast },
{ "r", FlagType.Redirect },
{ "redirect", FlagType.Redirect },
{ "s", FlagType.Skip },
{ "skip", FlagType.Skip },
{ "t", FlagType.Type },
{ "type", FlagType.Type },
};
public Flags Parse(string flagString)
{ {
if (string.IsNullOrEmpty(flagString)) if (string.IsNullOrEmpty(flagString))
{ {
return null; throw new ArgumentNullException(nameof(flagString));
} }
// Check that flags are contained within [] // Check that flags are contained within []
if (!flagString.StartsWith("[") || !flagString.EndsWith("]")) if (!(flagString.StartsWith("[") && flagString.EndsWith("]")))
{ {
throw new FormatException(); throw new FormatException("Flags should start and end with square brackets: [flags]");
} }
// Lexing esque step to split all flags. // Lexing esque step to split all flags.
@ -27,13 +73,20 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
foreach (string token in tokens) foreach (string token in tokens)
{ {
var hasPayload = token.Split('='); var hasPayload = token.Split('=');
FlagType flag;
if (!_ruleFlagLookup.TryGetValue(hasPayload[0], out flag))
{
throw new FormatException($"Unrecognized flag: {hasPayload[0]}");
}
if (hasPayload.Length == 2) if (hasPayload.Length == 2)
{ {
flags.SetFlag(hasPayload[0], hasPayload[1]); flags.SetFlag(flag, hasPayload[1]);
} }
else else
{ {
flags.SetFlag(hasPayload[0], string.Empty); flags.SetFlag(flag, string.Empty);
} }
} }
return flags; return flags;

View File

@ -1,7 +1,6 @@
// Copyright (c) .NET Foundation. All rights reserved. // Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
@ -11,51 +10,6 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
// http://httpd.apache.org/docs/current/expr.html#vars // http://httpd.apache.org/docs/current/expr.html#vars
public class Flags public class Flags
{ {
private static IDictionary<string, FlagType> _ruleFlagLookup = new Dictionary<string, FlagType>(StringComparer.OrdinalIgnoreCase) {
{ "b", FlagType.EscapeBackreference},
{ "c", FlagType.Chain },
{ "chain", FlagType.Chain},
{ "co", FlagType.Cookie },
{ "cookie", FlagType.Cookie },
{ "dpi", FlagType.DiscardPath },
{ "discardpath", FlagType.DiscardPath },
{ "e", FlagType.Env},
{ "env", FlagType.Env},
{ "end", FlagType.End },
{ "f", FlagType.Forbidden },
{ "forbidden", FlagType.Forbidden },
{ "g", FlagType.Gone },
{ "gone", FlagType.Gone },
{ "h", FlagType.Handler },
{ "handler", FlagType.Handler },
{ "l", FlagType.Last },
{ "last", FlagType.Last },
{ "n", FlagType.Next },
{ "next", FlagType.Next },
{ "nc", FlagType.NoCase },
{ "nocase", FlagType.NoCase },
{ "ne", FlagType.NoEscape },
{ "noescape", FlagType.NoEscape },
{ "ns", FlagType.NoSubReq },
{ "nosubreq", FlagType.NoSubReq },
{ "p", FlagType.Proxy },
{ "proxy", FlagType.Proxy },
{ "pt", FlagType.PassThrough },
{ "passthrough", FlagType.PassThrough },
{ "qsa", FlagType.QSAppend },
{ "qsappend", FlagType.QSAppend },
{ "qsd", FlagType.QSDiscard },
{ "qsdiscard", FlagType.QSDiscard },
{ "qsl", FlagType.QSLast },
{ "qslast", FlagType.QSLast },
{ "r", FlagType.Redirect },
{ "redirect", FlagType.Redirect },
{ "s", FlagType.Skip },
{ "skip", FlagType.Skip },
{ "t", FlagType.Type },
{ "type", FlagType.Type },
};
public IDictionary<FlagType, string> FlagDictionary { get; } public IDictionary<FlagType, string> FlagDictionary { get; }
public Flags(IDictionary<FlagType, string> flags) public Flags(IDictionary<FlagType, string> flags)
@ -68,16 +22,6 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
FlagDictionary = new Dictionary<FlagType, string>(); FlagDictionary = new Dictionary<FlagType, string>();
} }
public void SetFlag(string flag, string value)
{
FlagType res;
if (!_ruleFlagLookup.TryGetValue(flag, out res))
{
throw new FormatException("Unrecognized flag");
}
SetFlag(res, value);
}
public void SetFlag(FlagType flag, string value) public void SetFlag(FlagType flag, string value)
{ {
if (value == null) if (value == null)

View File

@ -3,7 +3,6 @@
using System; using System;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Rewrite.Internal;
using Microsoft.Net.Http.Headers; using Microsoft.Net.Http.Headers;
namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite

View File

@ -3,7 +3,6 @@
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions; using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Rewrite.Internal;
namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
{ {

View File

@ -4,7 +4,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Microsoft.AspNetCore.Rewrite.Internal;
using Microsoft.AspNetCore.Rewrite.Internal.PreActions; using Microsoft.AspNetCore.Rewrite.Internal.PreActions;
using Microsoft.AspNetCore.Rewrite.Internal.UrlActions; using Microsoft.AspNetCore.Rewrite.Internal.UrlActions;
using Microsoft.AspNetCore.Rewrite.Internal.UrlMatches; using Microsoft.AspNetCore.Rewrite.Internal.UrlMatches;
@ -32,13 +31,18 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
public void AddRule(string rule) public void AddRule(string rule)
{ {
// TODO // TODO
var tokens = Tokenizer.Tokenize(rule); var tokens = new Tokenizer().Tokenize(rule);
var regex = RuleRegexParser.ParseRuleRegex(tokens[1]); var regex = new RuleRegexParser().ParseRuleRegex(tokens[1]);
var pattern = TestStringParser.Parse(tokens[2]); var pattern = new TestStringParser().Parse(tokens[2]);
var flags = new Flags();
Flags flags;
if (tokens.Count == 4) if (tokens.Count == 4)
{ {
flags = FlagParser.Parse(tokens[3]); flags = new FlagParser().Parse(tokens[3]);
}
else
{
flags = new Flags();
} }
AddMatch(regex, flags); AddMatch(regex, flags);
AddAction(pattern, flags); AddAction(pattern, flags);

View File

@ -5,9 +5,9 @@ using System;
namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
{ {
public static class RuleRegexParser public class RuleRegexParser
{ {
public static ParsedModRewriteInput ParseRuleRegex(string regex) public ParsedModRewriteInput ParseRuleRegex(string regex)
{ {
if (regex == null || regex == string.Empty) if (regex == null || regex == string.Empty)
{ {

View File

@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using Microsoft.AspNetCore.Rewrite.Internal;
using Microsoft.AspNetCore.Rewrite.Internal.PatternSegments; using Microsoft.AspNetCore.Rewrite.Internal.PatternSegments;
using Microsoft.Net.Http.Headers; using Microsoft.Net.Http.Headers;

View File

@ -3,7 +3,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.AspNetCore.Rewrite.Internal;
using Microsoft.AspNetCore.Rewrite.Internal.PatternSegments; using Microsoft.AspNetCore.Rewrite.Internal.PatternSegments;
namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
@ -32,7 +31,7 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
/// $1</param> /// $1</param>
/// <returns>A new <see cref="Pattern"/>, containing a list of <see cref="PatternSegment"/></returns> /// <returns>A new <see cref="Pattern"/>, containing a list of <see cref="PatternSegment"/></returns>
/// http://httpd.apache.org/docs/current/mod/mod_rewrite.html /// http://httpd.apache.org/docs/current/mod/mod_rewrite.html
public static Pattern Parse(string testString) public Pattern Parse(string testString)
{ {
if (testString == null) if (testString == null)
{ {

View File

@ -9,7 +9,7 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
/// <summary> /// <summary>
/// Tokenizes a mod_rewrite rule, delimited by spaces. /// Tokenizes a mod_rewrite rule, delimited by spaces.
/// </summary> /// </summary>
public static class Tokenizer public class Tokenizer
{ {
private const char Space = ' '; private const char Space = ' ';
private const char Escape = '\\'; private const char Escape = '\\';
@ -20,7 +20,7 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
/// </summary> /// </summary>
/// <param name="rule">The rule to tokenize.</param> /// <param name="rule">The rule to tokenize.</param>
/// <returns>A list of tokens.</returns> /// <returns>A list of tokens.</returns>
public static List<string> Tokenize(string rule) public List<string> Tokenize(string rule)
{ {
// TODO make list of strings a reference to the original rule? (run into problems with escaped spaces). // TODO make list of strings a reference to the original rule? (run into problems with escaped spaces).
// TODO handle "s and probably replace \ character with no slash. // TODO handle "s and probably replace \ character with no slash.

View File

@ -15,7 +15,6 @@ namespace Microsoft.AspNetCore.Rewrite.Internal
public string Evaluate(RewriteContext context, MatchResults ruleMatch, MatchResults condMatch) public string Evaluate(RewriteContext context, MatchResults ruleMatch, MatchResults condMatch)
{ {
// TODO consider thread static for string builder - DAVID PERF
foreach (var pattern in PatternSegments) foreach (var pattern in PatternSegments)
{ {
context.Builder.Append(pattern.Evaluate(context, ruleMatch, condMatch)); context.Builder.Append(pattern.Evaluate(context, ruleMatch, condMatch));

View File

@ -7,15 +7,16 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Xml; using System.Xml;
using System.Xml.Linq; using System.Xml.Linq;
using Microsoft.AspNetCore.Rewrite.Internal;
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite
{ {
public static class UrlRewriteFileParser public class FileParser
{ {
private static readonly TimeSpan RegexTimeout = TimeSpan.FromMilliseconds(1); private static readonly TimeSpan RegexTimeout = TimeSpan.FromMilliseconds(1);
public static List<UrlRewriteRule> Parse(TextReader reader) private InputParser _inputParser = new InputParser();
public List<UrlRewriteRule> Parse(TextReader reader)
{ {
var xmlDoc = XDocument.Load(reader, LoadOptions.SetLineInfo); var xmlDoc = XDocument.Load(reader, LoadOptions.SetLineInfo);
var xmlRoot = xmlDoc.Descendants(RewriteTags.Rewrite).FirstOrDefault(); var xmlRoot = xmlDoc.Descendants(RewriteTags.Rewrite).FirstOrDefault();
@ -32,7 +33,7 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite
return null; return null;
} }
private static void ParseRules(XElement rules, List<UrlRewriteRule> result) private void ParseRules(XElement rules, List<UrlRewriteRule> result)
{ {
if (rules == null) if (rules == null)
{ {
@ -51,7 +52,7 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite
} }
} }
private static void ParseRuleAttributes(XElement rule, UrlRewriteRuleBuilder builder) private void ParseRuleAttributes(XElement rule, UrlRewriteRuleBuilder builder)
{ {
builder.Name = rule.Attribute(RewriteTags.Name)?.Value; builder.Name = rule.Attribute(RewriteTags.Name)?.Value;
@ -90,7 +91,7 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite
ParseUrlAction(action, builder, stopProcessing); ParseUrlAction(action, builder, stopProcessing);
} }
private static void ParseMatch(XElement match, UrlRewriteRuleBuilder builder, PatternSyntax patternSyntax) private void ParseMatch(XElement match, UrlRewriteRuleBuilder builder, PatternSyntax patternSyntax)
{ {
var parsedInputString = match.Attribute(RewriteTags.Url)?.Value; var parsedInputString = match.Attribute(RewriteTags.Url)?.Value;
if (parsedInputString == null) if (parsedInputString == null)
@ -112,7 +113,7 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite
builder.AddUrlMatch(parsedInputString, ignoreCase, negate, patternSyntax); builder.AddUrlMatch(parsedInputString, ignoreCase, negate, patternSyntax);
} }
private static void ParseConditions(XElement conditions, UrlRewriteRuleBuilder builder, PatternSyntax patternSyntax) private void ParseConditions(XElement conditions, UrlRewriteRuleBuilder builder, PatternSyntax patternSyntax)
{ {
if (conditions == null) if (conditions == null)
{ {
@ -139,7 +140,7 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite
} }
} }
private static void ParseCondition(XElement condition, UrlRewriteRuleBuilder builder, PatternSyntax patternSyntax) private void ParseCondition(XElement condition, UrlRewriteRuleBuilder builder, PatternSyntax patternSyntax)
{ {
bool ignoreCase; bool ignoreCase;
if (!bool.TryParse(condition.Attribute(RewriteTags.IgnoreCase)?.Value, out ignoreCase)) if (!bool.TryParse(condition.Attribute(RewriteTags.IgnoreCase)?.Value, out ignoreCase))
@ -170,7 +171,7 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite
Pattern input = null; Pattern input = null;
try try
{ {
input = InputParser.ParseInputString(parsedInputString); input = _inputParser.ParseInputString(parsedInputString);
builder.AddUrlCondition(input, parsedPatternString, patternSyntax, matchType, ignoreCase, negate); builder.AddUrlCondition(input, parsedPatternString, patternSyntax, matchType, ignoreCase, negate);
} }
@ -180,7 +181,7 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite
} }
} }
private static void ParseUrlAction(XElement urlAction, UrlRewriteRuleBuilder builder, bool stopProcessing) private void ParseUrlAction(XElement urlAction, UrlRewriteRuleBuilder builder, bool stopProcessing)
{ {
ActionType actionType; ActionType actionType;
if (!Enum.TryParse(urlAction.Attribute(RewriteTags.Type)?.Value, out actionType)) if (!Enum.TryParse(urlAction.Attribute(RewriteTags.Type)?.Value, out actionType))
@ -202,7 +203,7 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite
try try
{ {
var input = InputParser.ParseInputString(urlAction.Attribute(RewriteTags.Url)?.Value); var input = _inputParser.ParseInputString(urlAction.Attribute(RewriteTags.Url)?.Value);
builder.AddUrlAction(input, actionType, appendQuery, stopProcessing, (int)redirectType); builder.AddUrlAction(input, actionType, appendQuery, stopProcessing, (int)redirectType);
} }
catch (FormatException formatException) catch (FormatException formatException)
@ -211,14 +212,14 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite
} }
} }
private static void ThrowUrlFormatException(XElement element, string message) private void ThrowUrlFormatException(XElement element, string message)
{ {
var line = ((IXmlLineInfo)element).LineNumber; var line = ((IXmlLineInfo)element).LineNumber;
var col = ((IXmlLineInfo)element).LinePosition; var col = ((IXmlLineInfo)element).LinePosition;
throw new FormatException(Resources.FormatError_UrlRewriteParseError(message, line, col)); throw new FormatException(Resources.FormatError_UrlRewriteParseError(message, line, col));
} }
private static void ThrowUrlFormatException(XElement element, string message, Exception ex) private void ThrowUrlFormatException(XElement element, string message, Exception ex)
{ {
var line = ((IXmlLineInfo)element).LineNumber; var line = ((IXmlLineInfo)element).LineNumber;
var col = ((IXmlLineInfo)element).LinePosition; var col = ((IXmlLineInfo)element).LinePosition;

View File

@ -20,7 +20,7 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite
/// </summary> /// </summary>
/// <param name="testString"></param> /// <param name="testString"></param>
/// <returns>A new <see cref="Pattern"/>, containing a list of <see cref="PatternSegment"/></returns> /// <returns>A new <see cref="Pattern"/>, containing a list of <see cref="PatternSegment"/></returns>
public static Pattern ParseInputString(string testString) public Pattern ParseInputString(string testString)
{ {
if (testString == null) if (testString == null)
{ {

View File

@ -5,7 +5,6 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Rewrite.Internal;
using Microsoft.AspNetCore.Rewrite.Internal.UrlActions; using Microsoft.AspNetCore.Rewrite.Internal.UrlActions;
using Microsoft.AspNetCore.Rewrite.Internal.UrlMatches; using Microsoft.AspNetCore.Rewrite.Internal.UrlMatches;

View File

@ -36,7 +36,7 @@ namespace Microsoft.AspNetCore.Rewrite
var path = Path.Combine(hostingEnv.ContentRootPath, filePath); var path = Path.Combine(hostingEnv.ContentRootPath, filePath);
using (var stream = File.OpenRead(path)) using (var stream = File.OpenRead(path))
{ {
options.Rules.AddRange(UrlRewriteFileParser.Parse(new StreamReader(stream))); options.Rules.AddRange(new FileParser().Parse(new StreamReader(stream)));
}; };
return options; return options;
} }
@ -60,7 +60,7 @@ namespace Microsoft.AspNetCore.Rewrite
using (stream) using (stream)
{ {
options.Rules.AddRange(UrlRewriteFileParser.Parse(stream)); options.Rules.AddRange(new FileParser().Parse(stream));
}; };
return options; return options;
} }

View File

@ -16,7 +16,7 @@ namespace Microsoft.AspNetCore.Rewrite.Tests.ModRewrite
[InlineData("=hey", OperationType.Equal, "hey", ConditionType.StringComp)] [InlineData("=hey", OperationType.Equal, "hey", ConditionType.StringComp)]
public void ConditionParser_CheckStringComp(string condition, OperationType operation, string variable, ConditionType conditionType) public void ConditionParser_CheckStringComp(string condition, OperationType operation, string variable, ConditionType conditionType)
{ {
var results = ConditionPatternParser.ParseActionCondition(condition); var results = new ConditionPatternParser().ParseActionCondition(condition);
var expected = new ParsedModRewriteInput { OperationType = operation, ConditionType = conditionType, Operand = variable, Invert = false }; var expected = new ParsedModRewriteInput { OperationType = operation, ConditionType = conditionType, Operand = variable, Invert = false };
Assert.True(CompareConditions(results, expected)); Assert.True(CompareConditions(results, expected));
@ -26,7 +26,7 @@ namespace Microsoft.AspNetCore.Rewrite.Tests.ModRewrite
public void ConditionParser_CheckRegexEqual() public void ConditionParser_CheckRegexEqual()
{ {
var condition = @"(.*)"; var condition = @"(.*)";
var results = ConditionPatternParser.ParseActionCondition(condition); var results = new ConditionPatternParser().ParseActionCondition(condition);
var expected = new ParsedModRewriteInput { ConditionType = ConditionType.Regex, Operand = "(.*)", Invert = false }; var expected = new ParsedModRewriteInput { ConditionType = ConditionType.Regex, Operand = "(.*)", Invert = false };
Assert.True(CompareConditions(results, expected)); Assert.True(CompareConditions(results, expected));
@ -44,7 +44,7 @@ namespace Microsoft.AspNetCore.Rewrite.Tests.ModRewrite
[InlineData("-x", OperationType.Executable, ConditionType.PropertyTest)] [InlineData("-x", OperationType.Executable, ConditionType.PropertyTest)]
public void ConditionParser_CheckFileOperations(string condition, OperationType operation, ConditionType cond) public void ConditionParser_CheckFileOperations(string condition, OperationType operation, ConditionType cond)
{ {
var results = ConditionPatternParser.ParseActionCondition(condition); var results = new ConditionPatternParser().ParseActionCondition(condition);
var expected = new ParsedModRewriteInput { ConditionType = cond, OperationType = operation , Invert = false }; var expected = new ParsedModRewriteInput { ConditionType = cond, OperationType = operation , Invert = false };
Assert.True(CompareConditions(results, expected)); Assert.True(CompareConditions(results, expected));
@ -62,7 +62,7 @@ namespace Microsoft.AspNetCore.Rewrite.Tests.ModRewrite
[InlineData("!-x", OperationType.Executable, ConditionType.PropertyTest)] [InlineData("!-x", OperationType.Executable, ConditionType.PropertyTest)]
public void ConditionParser_CheckFileOperationsInverted(string condition, OperationType operation, ConditionType cond) public void ConditionParser_CheckFileOperationsInverted(string condition, OperationType operation, ConditionType cond)
{ {
var results = ConditionPatternParser.ParseActionCondition(condition); var results = new ConditionPatternParser().ParseActionCondition(condition);
var expected = new ParsedModRewriteInput { ConditionType = cond, OperationType = operation, Invert = true }; var expected = new ParsedModRewriteInput { ConditionType = cond, OperationType = operation, Invert = true };
Assert.True(CompareConditions(results, expected)); Assert.True(CompareConditions(results, expected));
@ -77,7 +77,7 @@ namespace Microsoft.AspNetCore.Rewrite.Tests.ModRewrite
[InlineData("-ne1", OperationType.NotEqual, "1", ConditionType.IntComp)] [InlineData("-ne1", OperationType.NotEqual, "1", ConditionType.IntComp)]
public void ConditionParser_CheckIntComp(string condition, OperationType operation, string variable, ConditionType cond) public void ConditionParser_CheckIntComp(string condition, OperationType operation, string variable, ConditionType cond)
{ {
var results = ConditionPatternParser.ParseActionCondition(condition); var results = new ConditionPatternParser().ParseActionCondition(condition);
var expected = new ParsedModRewriteInput { ConditionType = cond, OperationType = operation, Invert = false, Operand = variable }; var expected = new ParsedModRewriteInput { ConditionType = cond, OperationType = operation, Invert = false, Operand = variable };
Assert.True(CompareConditions(results, expected)); Assert.True(CompareConditions(results, expected));

View File

@ -13,7 +13,7 @@ namespace Microsoft.AspNetCore.Rewrite.Tests.ModRewrite
[Fact] [Fact]
public void FlagParser_CheckSingleTerm() public void FlagParser_CheckSingleTerm()
{ {
var results = FlagParser.Parse("[NC]"); var results = new FlagParser().Parse("[NC]");
var dict = new Dictionary<FlagType, string>(); var dict = new Dictionary<FlagType, string>();
dict.Add(FlagType.NoCase, string.Empty); dict.Add(FlagType.NoCase, string.Empty);
var expected = new Flags(dict); var expected = new Flags(dict);
@ -24,7 +24,7 @@ namespace Microsoft.AspNetCore.Rewrite.Tests.ModRewrite
[Fact] [Fact]
public void FlagParser_CheckManyTerms() public void FlagParser_CheckManyTerms()
{ {
var results = FlagParser.Parse("[NC,F,L]"); var results = new FlagParser().Parse("[NC,F,L]");
var dict = new Dictionary<FlagType, string>(); var dict = new Dictionary<FlagType, string>();
dict.Add(FlagType.NoCase, string.Empty); dict.Add(FlagType.NoCase, string.Empty);
dict.Add(FlagType.Forbidden, string.Empty); dict.Add(FlagType.Forbidden, string.Empty);
@ -37,7 +37,7 @@ namespace Microsoft.AspNetCore.Rewrite.Tests.ModRewrite
[Fact] [Fact]
public void FlagParser_CheckManyTermsWithEquals() public void FlagParser_CheckManyTermsWithEquals()
{ {
var results = FlagParser.Parse("[NC,F,R=301]"); var results = new FlagParser().Parse("[NC,F,R=301]");
var dict = new Dictionary<FlagType, string>(); var dict = new Dictionary<FlagType, string>();
dict.Add(FlagType.NoCase, string.Empty); dict.Add(FlagType.NoCase, string.Empty);
dict.Add(FlagType.Forbidden, string.Empty); dict.Add(FlagType.Forbidden, string.Empty);

View File

@ -13,7 +13,7 @@ namespace Microsoft.AspNetCore.Rewrite.Tests.ModRewrite
public void Tokenize_RewriteCondtion() public void Tokenize_RewriteCondtion()
{ {
var testString = "RewriteCond %{HTTPS} !-f"; var testString = "RewriteCond %{HTTPS} !-f";
var tokens = Tokenizer.Tokenize(testString); var tokens = new Tokenizer().Tokenize(testString);
var expected = new List<string>(); var expected = new List<string>();
expected.Add("RewriteCond"); expected.Add("RewriteCond");
@ -27,7 +27,7 @@ namespace Microsoft.AspNetCore.Rewrite.Tests.ModRewrite
{ {
// TODO need consultation on escape characters. // TODO need consultation on escape characters.
var testString = @"RewriteCond %{HTTPS}\ what !-f"; var testString = @"RewriteCond %{HTTPS}\ what !-f";
var tokens = Tokenizer.Tokenize(testString); var tokens = new Tokenizer().Tokenize(testString);
var expected = new List<string>(); var expected = new List<string>();
expected.Add("RewriteCond"); expected.Add("RewriteCond");

View File

@ -12,19 +12,19 @@ namespace Microsoft.AspNetCore.Rewrite.Tests.ModRewrite
[Fact] [Fact]
public void RuleRegexParser_ShouldThrowOnNull() public void RuleRegexParser_ShouldThrowOnNull()
{ {
Assert.Throws<FormatException>(() => RuleRegexParser.ParseRuleRegex(null)); Assert.Throws<FormatException>(() => new RuleRegexParser().ParseRuleRegex(null));
} }
[Fact] [Fact]
public void RuleRegexParser_ShouldThrowOnEmpty() public void RuleRegexParser_ShouldThrowOnEmpty()
{ {
Assert.Throws<FormatException>(() => RuleRegexParser.ParseRuleRegex(string.Empty)); Assert.Throws<FormatException>(() => new RuleRegexParser().ParseRuleRegex(string.Empty));
} }
[Fact] [Fact]
public void RuleRegexParser_RegularRegexExpression() public void RuleRegexParser_RegularRegexExpression()
{ {
var results = RuleRegexParser.ParseRuleRegex("(.*)"); var results = new RuleRegexParser().ParseRuleRegex("(.*)");
Assert.False(results.Invert); Assert.False(results.Invert);
Assert.Equal(results.Operand, "(.*)"); Assert.Equal(results.Operand, "(.*)");
} }

View File

@ -35,7 +35,7 @@ namespace Microsoft.AspNetCore.Rewrite.Tests.UrlRewrite
pattern: "article.aspx?id={R:1}&amp;title={R:2}")); pattern: "article.aspx?id={R:1}&amp;title={R:2}"));
// act // act
var res = UrlRewriteFileParser.Parse(new StringReader(xml)); var res = new FileParser().Parse(new StringReader(xml));
// assert // assert
AssertUrlRewriteRuleEquality(res, expected); AssertUrlRewriteRuleEquality(res, expected);
@ -60,7 +60,7 @@ namespace Microsoft.AspNetCore.Rewrite.Tests.UrlRewrite
var condList = new List<Condition>(); var condList = new List<Condition>();
condList.Add(new Condition condList.Add(new Condition
{ {
Input = InputParser.ParseInputString("{HTTPS}"), Input = new InputParser().ParseInputString("{HTTPS}"),
Match = new RegexMatch(new Regex("^OFF$"), false) Match = new RegexMatch(new Regex("^OFF$"), false)
}); });
@ -72,7 +72,7 @@ namespace Microsoft.AspNetCore.Rewrite.Tests.UrlRewrite
pattern: "article.aspx?id={R:1}&amp;title={R:2}")); pattern: "article.aspx?id={R:1}&amp;title={R:2}"));
// act // act
var res = UrlRewriteFileParser.Parse(new StringReader(xml)); var res = new FileParser().Parse(new StringReader(xml));
// assert // assert
AssertUrlRewriteRuleEquality(res, expected); AssertUrlRewriteRuleEquality(res, expected);
@ -104,7 +104,7 @@ namespace Microsoft.AspNetCore.Rewrite.Tests.UrlRewrite
var condList = new List<Condition>(); var condList = new List<Condition>();
condList.Add(new Condition condList.Add(new Condition
{ {
Input = InputParser.ParseInputString("{HTTPS}"), Input = new InputParser().ParseInputString("{HTTPS}"),
Match = new RegexMatch(new Regex("^OFF$"), false) Match = new RegexMatch(new Regex("^OFF$"), false)
}); });
@ -121,7 +121,7 @@ namespace Microsoft.AspNetCore.Rewrite.Tests.UrlRewrite
pattern: "article.aspx?id={R:1}&amp;title={R:2}")); pattern: "article.aspx?id={R:1}&amp;title={R:2}"));
// act // act
var res = UrlRewriteFileParser.Parse(new StringReader(xml)); var res = new FileParser().Parse(new StringReader(xml));
// assert // assert
AssertUrlRewriteRuleEquality(res, expected); AssertUrlRewriteRuleEquality(res, expected);
@ -147,7 +147,7 @@ namespace Microsoft.AspNetCore.Rewrite.Tests.UrlRewrite
{ {
return new UrlRewriteRule return new UrlRewriteRule
{ {
Action = new RewriteAction(RuleTerminiation.Continue, InputParser.ParseInputString(Url), clearQuery: false), Action = new RewriteAction(RuleTerminiation.Continue, new InputParser().ParseInputString(Url), clearQuery: false),
Name = name, Name = name,
Enabled = enabled, Enabled = enabled,
InitialMatch = new RegexMatch(new Regex("^OFF$"), false) InitialMatch = new RegexMatch(new Regex("^OFF$"), false)
@ -190,6 +190,9 @@ namespace Microsoft.AspNetCore.Rewrite.Tests.UrlRewrite
Assert.Equal(c1.Input.PatternSegments.Count, c2.Input.PatternSegments.Count); Assert.Equal(c1.Input.PatternSegments.Count, c2.Input.PatternSegments.Count);
} }
} }
Assert.Equal(r1.Action.GetType(), r2.Action.GetType());
Assert.Equal(r1.InitialMatch.GetType(), r2.InitialMatch.GetType());
} }
} }
} }

View File

@ -114,7 +114,7 @@ namespace Microsoft.AspNetCore.Rewrite.Tests.UrlRewrite
public void ThrowFormatExceptionWithCorrectMessage(string input, string expected) public void ThrowFormatExceptionWithCorrectMessage(string input, string expected)
{ {
// Arrange, Act, Assert // Arrange, Act, Assert
var ex = Assert.Throws<FormatException>(() => UrlRewriteFileParser.Parse(new StringReader(input))); var ex = Assert.Throws<FormatException>(() => new FileParser().Parse(new StringReader(input)));
Assert.Equal(ex.Message, expected); Assert.Equal(ex.Message, expected);
} }
} }

View File

@ -16,7 +16,7 @@ namespace Microsoft.AspNetCore.Rewrite.Tests.UrlRewrite
public void InputParser_ParseLiteralString() public void InputParser_ParseLiteralString()
{ {
var testString = "hello/hey/what"; var testString = "hello/hey/what";
var result = InputParser.ParseInputString(testString); var result = new InputParser().ParseInputString(testString);
Assert.Equal(result.PatternSegments.Count, 1); Assert.Equal(result.PatternSegments.Count, 1);
} }
@ -29,7 +29,7 @@ namespace Microsoft.AspNetCore.Rewrite.Tests.UrlRewrite
[InlineData("foo/", 1)] [InlineData("foo/", 1)]
public void InputParser_ParseStringWithBackReference(string testString, int expected) public void InputParser_ParseStringWithBackReference(string testString, int expected)
{ {
var result = InputParser.ParseInputString(testString); var result = new InputParser().ParseInputString(testString);
Assert.Equal(result.PatternSegments.Count, expected); Assert.Equal(result.PatternSegments.Count, expected);
} }
@ -45,7 +45,7 @@ namespace Microsoft.AspNetCore.Rewrite.Tests.UrlRewrite
[InlineData("hey/{R:1}/{C:1}", "hey/foo/foo")] [InlineData("hey/{R:1}/{C:1}", "hey/foo/foo")]
public void EvaluateBackReferenceRule(string testString, string expected) public void EvaluateBackReferenceRule(string testString, string expected)
{ {
var middle = InputParser.ParseInputString(testString); var middle = new InputParser().ParseInputString(testString);
var result = middle.Evaluate(CreateTestRewriteContext(), CreateTestRuleMatch(), CreateTestCondMatch()); var result = middle.Evaluate(CreateTestRewriteContext(), CreateTestRuleMatch(), CreateTestCondMatch());
Assert.Equal(result, expected); Assert.Equal(result, expected);
} }
@ -58,7 +58,7 @@ namespace Microsoft.AspNetCore.Rewrite.Tests.UrlRewrite
[InlineData("hey/ToLower:/what", "hey/ToLower:/what")] [InlineData("hey/ToLower:/what", "hey/ToLower:/what")]
public void EvaluatToLowerRule(string testString, string expected) public void EvaluatToLowerRule(string testString, string expected)
{ {
var middle = InputParser.ParseInputString(testString); var middle = new InputParser().ParseInputString(testString);
var result = middle.Evaluate(CreateTestRewriteContext(), CreateTestRuleMatch(), CreateTestCondMatch()); var result = middle.Evaluate(CreateTestRewriteContext(), CreateTestRuleMatch(), CreateTestCondMatch());
Assert.Equal(result, expected); Assert.Equal(result, expected);
} }
@ -67,7 +67,7 @@ namespace Microsoft.AspNetCore.Rewrite.Tests.UrlRewrite
[InlineData("hey/{UrlEncode:<hey>}", "hey/%3Chey%3E")] [InlineData("hey/{UrlEncode:<hey>}", "hey/%3Chey%3E")]
public void EvaluatUriEncodeRule(string testString, string expected) public void EvaluatUriEncodeRule(string testString, string expected)
{ {
var middle = InputParser.ParseInputString(testString); var middle = new InputParser().ParseInputString(testString);
var result = middle.Evaluate(CreateTestRewriteContext(), CreateTestRuleMatch(), CreateTestCondMatch()); var result = middle.Evaluate(CreateTestRewriteContext(), CreateTestRuleMatch(), CreateTestCondMatch());
Assert.Equal(result, expected); Assert.Equal(result, expected);
} }
@ -86,7 +86,7 @@ namespace Microsoft.AspNetCore.Rewrite.Tests.UrlRewrite
[InlineData("{HTTPS")] [InlineData("{HTTPS")]
public void FormatExceptionsOnBadSyntax(string testString) public void FormatExceptionsOnBadSyntax(string testString)
{ {
Assert.Throws<FormatException>(() => InputParser.ParseInputString(testString)); Assert.Throws<FormatException>(() => new InputParser().ParseInputString(testString));
} }
private RewriteContext CreateTestRewriteContext() private RewriteContext CreateTestRewriteContext()