diff --git a/src/Microsoft.AspNetCore.Rewrite/Internal/IISUrlRewrite/PatternSyntax.cs b/src/Microsoft.AspNetCore.Rewrite/Internal/IISUrlRewrite/PatternSyntax.cs index b068016e72..f27d2c7256 100644 --- a/src/Microsoft.AspNetCore.Rewrite/Internal/IISUrlRewrite/PatternSyntax.cs +++ b/src/Microsoft.AspNetCore.Rewrite/Internal/IISUrlRewrite/PatternSyntax.cs @@ -6,7 +6,7 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.IISUrlRewrite public enum PatternSyntax { ECMAScript, - WildCard, + Wildcard, ExactMatch } } diff --git a/src/Microsoft.AspNetCore.Rewrite/Internal/IISUrlRewrite/RewriteTags.cs b/src/Microsoft.AspNetCore.Rewrite/Internal/IISUrlRewrite/RewriteTags.cs index 420e8e461d..5b60674d41 100644 --- a/src/Microsoft.AspNetCore.Rewrite/Internal/IISUrlRewrite/RewriteTags.cs +++ b/src/Microsoft.AspNetCore.Rewrite/Internal/IISUrlRewrite/RewriteTags.cs @@ -5,29 +5,30 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.IISUrlRewrite { public static class RewriteTags { - public const string Rewrite = "rewrite"; - public const string GlobalRules = "globalRules"; - public const string Rules = "rules"; - public const string Rule = "rule"; public const string Action = "action"; - public const string Name = "name"; - public const string Enabled = "enabled"; - public const string PatternSyntax = "patternSyntax"; - public const string StopProcessing = "stopProcessing"; - public const string Match = "match"; - public const string Conditions = "conditions"; - public const string IgnoreCase = "ignoreCase"; - public const string Negate = "negate"; - public const string Url = "url"; - public const string MatchType = "matchType"; public const string Add = "add"; - public const string TrackingAllCaptures = "trackingAllCaptures"; - public const string MatchPattern = "matchPattern"; - public const string Input = "input"; - public const string Pattern = "pattern"; - public const string Type = "type"; public const string AppendQueryString = "appendQueryString"; + public const string Conditions = "conditions"; + public const string Enabled = "enabled"; + public const string GlobalRules = "globalRules"; + public const string IgnoreCase = "ignoreCase"; + public const string Input = "input"; + public const string LogicalGrouping = "logicalGrouping"; public const string LogRewrittenUrl = "logRewrittenUrl"; + public const string Match = "match"; + public const string MatchPattern = "matchPattern"; + public const string MatchType = "matchType"; + public const string Name = "name"; + public const string Negate = "negate"; + public const string Pattern = "pattern"; + public const string PatternSyntax = "patternSyntax"; + public const string Rewrite = "rewrite"; public const string RedirectType = "redirectType"; + public const string Rule = "rule"; + public const string Rules = "rules"; + public const string StopProcessing = "stopProcessing"; + public const string TrackingAllCaptures = "trackingAllCaptures"; + public const string Type = "type"; + public const string Url = "url"; } } diff --git a/src/Microsoft.AspNetCore.Rewrite/Internal/IISUrlRewrite/UrlRewriteFileParser.cs b/src/Microsoft.AspNetCore.Rewrite/Internal/IISUrlRewrite/UrlRewriteFileParser.cs index e73df77bb4..24b17e78ab 100644 --- a/src/Microsoft.AspNetCore.Rewrite/Internal/IISUrlRewrite/UrlRewriteFileParser.cs +++ b/src/Microsoft.AspNetCore.Rewrite/Internal/IISUrlRewrite/UrlRewriteFileParser.cs @@ -77,10 +77,14 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.IISUrlRewrite } PatternSyntax patternSyntax; - if (!Enum.TryParse(rule.Attribute(RewriteTags.PatternSyntax)?.Value, out patternSyntax)) + if (rule.Attribute(RewriteTags.PatternSyntax) == null) { patternSyntax = PatternSyntax.ECMAScript; } + else if (!Enum.TryParse(rule.Attribute(RewriteTags.PatternSyntax).Value, ignoreCase: true, result: out patternSyntax)) + { + ThrowParameterFormatException(rule, $"The {RewriteTags.PatternSyntax} parameter '{rule.Attribute(RewriteTags.PatternSyntax).Value}' was not recognized"); + } bool stopProcessing; if (!bool.TryParse(rule.Attribute(RewriteTags.StopProcessing)?.Value, out stopProcessing)) @@ -116,7 +120,7 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.IISUrlRewrite bool ignoreCase; if (!bool.TryParse(match.Attribute(RewriteTags.IgnoreCase)?.Value, out ignoreCase)) { - ignoreCase = true; // default + ignoreCase = true; } bool negate; @@ -135,10 +139,14 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.IISUrlRewrite } LogicalGrouping grouping; - if (!Enum.TryParse(conditions.Attribute(RewriteTags.MatchType)?.Value, out grouping)) + if (conditions.Attribute(RewriteTags.LogicalGrouping) == null) { grouping = LogicalGrouping.MatchAll; } + else if (!Enum.TryParse(conditions.Attribute(RewriteTags.LogicalGrouping).Value, ignoreCase: true, result: out grouping)) + { + ThrowParameterFormatException(conditions, $"The {RewriteTags.LogicalGrouping} parameter '{conditions.Attribute(RewriteTags.LogicalGrouping).Value}' was not recognized"); + } bool trackingAllCaptures; if (!bool.TryParse(conditions.Attribute(RewriteTags.TrackingAllCaptures)?.Value, out trackingAllCaptures)) @@ -169,10 +177,14 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.IISUrlRewrite } MatchType matchType; - if (!Enum.TryParse(condition.Attribute(RewriteTags.MatchType)?.Value, out matchType)) + if (condition.Attribute(RewriteTags.MatchType) == null) { matchType = MatchType.Pattern; } + else if (!Enum.TryParse(condition.Attribute(RewriteTags.MatchType).Value, ignoreCase: true, result: out matchType)) + { + ThrowParameterFormatException(condition, $"The {RewriteTags.MatchType} parameter '{condition.Attribute(RewriteTags.MatchType).Value}' was not recognized"); + } var parsedInputString = condition.Attribute(RewriteTags.Input)?.Value; if (parsedInputString == null) @@ -195,10 +207,14 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.IISUrlRewrite private void ParseUrlAction(XElement urlAction, UrlRewriteRuleBuilder builder, bool stopProcessing) { ActionType actionType; - if (!Enum.TryParse(urlAction.Attribute(RewriteTags.Type)?.Value, out actionType)) + if (urlAction.Attribute(RewriteTags.Type) == null) { actionType = ActionType.None; } + else if (!Enum.TryParse(urlAction.Attribute(RewriteTags.Type).Value, ignoreCase: true, result: out actionType)) + { + ThrowParameterFormatException(urlAction, $"The {RewriteTags.Type} parameter '{urlAction.Attribute(RewriteTags.Type).Value}' was not recognized"); + } bool appendQuery; if (!bool.TryParse(urlAction.Attribute(RewriteTags.AppendQueryString)?.Value, out appendQuery)) @@ -207,10 +223,14 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.IISUrlRewrite } RedirectType redirectType; - if (!Enum.TryParse(urlAction.Attribute(RewriteTags.RedirectType)?.Value, out redirectType)) + if (urlAction.Attribute(RewriteTags.RedirectType) == null) { redirectType = RedirectType.Permanent; } + else if (!Enum.TryParse(urlAction.Attribute(RewriteTags.RedirectType).Value, ignoreCase: true, result: out redirectType)) + { + ThrowParameterFormatException(urlAction, $"The {RewriteTags.RedirectType} parameter '{urlAction.Attribute(RewriteTags.RedirectType).Value}' was not recognized"); + } string url = string.Empty; if (urlAction.Attribute(RewriteTags.Url) != null) @@ -235,16 +255,26 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.IISUrlRewrite private static void ThrowUrlFormatException(XElement element, string message) { - var line = ((IXmlLineInfo)element).LineNumber; - var col = ((IXmlLineInfo)element).LinePosition; + var lineInfo = (IXmlLineInfo)element; + var line = lineInfo.LineNumber; + var col = lineInfo.LinePosition; throw new FormatException(Resources.FormatError_UrlRewriteParseError(message, line, col)); } private static void ThrowUrlFormatException(XElement element, string message, Exception ex) { - var line = ((IXmlLineInfo)element).LineNumber; - var col = ((IXmlLineInfo)element).LinePosition; + var lineInfo = (IXmlLineInfo)element; + var line = lineInfo.LineNumber; + var col = lineInfo.LinePosition; throw new FormatException(Resources.FormatError_UrlRewriteParseError(message, line, col), ex); } + + private static void ThrowParameterFormatException(XElement element, string message) + { + var lineInfo = (IXmlLineInfo)element; + var line = lineInfo.LineNumber; + var col = lineInfo.LinePosition; + throw new FormatException(Resources.FormatError_UrlRewriteParseError(message, line, col)); + } } } diff --git a/src/Microsoft.AspNetCore.Rewrite/Internal/IISUrlRewrite/UrlRewriteRuleBuilder.cs b/src/Microsoft.AspNetCore.Rewrite/Internal/IISUrlRewrite/UrlRewriteRuleBuilder.cs index c4edf77cca..172c5ea457 100644 --- a/src/Microsoft.AspNetCore.Rewrite/Internal/IISUrlRewrite/UrlRewriteRuleBuilder.cs +++ b/src/Microsoft.AspNetCore.Rewrite/Internal/IISUrlRewrite/UrlRewriteRuleBuilder.cs @@ -76,7 +76,7 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.IISUrlRewrite } break; } - case PatternSyntax.WildCard: + case PatternSyntax.Wildcard: throw new NotSupportedException("Wildcard syntax is not supported"); case PatternSyntax.ExactMatch: _initialMatch = new ExactMatch(ignoreCase, input, negate); @@ -86,7 +86,7 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.IISUrlRewrite public void AddUrlCondition(Pattern input, string pattern, PatternSyntax patternSyntax, MatchType matchType, bool ignoreCase, bool negate) { - // If there are no conditions specified, + // If there are no conditions specified if (_conditions == null) { AddUrlConditions(LogicalGrouping.MatchAll, trackingAllCaptures: false); @@ -129,7 +129,7 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.IISUrlRewrite } break; } - case PatternSyntax.WildCard: + case PatternSyntax.Wildcard: throw new NotSupportedException("Wildcard syntax is not supported"); case PatternSyntax.ExactMatch: if (pattern == null) diff --git a/test/Microsoft.AspNetCore.Rewrite.Tests/IISUrlRewrite/FormatExceptionHandlingTests.cs b/test/Microsoft.AspNetCore.Rewrite.Tests/IISUrlRewrite/FormatExceptionHandlingTests.cs index 6398da1e95..7aca36e9f1 100644 --- a/test/Microsoft.AspNetCore.Rewrite.Tests/IISUrlRewrite/FormatExceptionHandlingTests.cs +++ b/test/Microsoft.AspNetCore.Rewrite.Tests/IISUrlRewrite/FormatExceptionHandlingTests.cs @@ -101,6 +101,62 @@ namespace Microsoft.AspNetCore.Rewrite.Tests.UrlRewrite ", "Could not parse the UrlRewrite file. Message: 'Url attribute cannot contain an empty string'. Line number '5': '14'.")] + [InlineData( +@" + + + + + + +", + "Could not parse the UrlRewrite file. Message: 'The redirectType parameter 'foo' was not recognized'. Line number '5': '14'.")] + [InlineData( +@" + + + + + + +", + "Could not parse the UrlRewrite file. Message: 'The type parameter 'foo' was not recognized'. Line number '5': '14'.")] + [InlineData( +@" + + + + + + + + + +", + "Could not parse the UrlRewrite file. Message: 'The logicalGrouping parameter 'foo' was not recognized'. Line number '5': '14'.")] + [InlineData( +@" + + + + + + +", + "Could not parse the UrlRewrite file. Message: 'The patternSyntax parameter 'foo' was not recognized'. Line number '3': '10'.")] + [InlineData( +@" + + + + + + + + + +", + "Could not parse the UrlRewrite file. Message: 'The matchType parameter 'foo' was not recognized'. Line number '6': '18'.")] public void ThrowFormatExceptionWithCorrectMessage(string input, string expected) { // Arrange, Act, Assert diff --git a/test/Microsoft.AspNetCore.Rewrite.Tests/IISUrlRewrite/MiddleWareTests.cs b/test/Microsoft.AspNetCore.Rewrite.Tests/IISUrlRewrite/MiddleWareTests.cs index e18f0325c1..2951b9777e 100644 --- a/test/Microsoft.AspNetCore.Rewrite.Tests/IISUrlRewrite/MiddleWareTests.cs +++ b/test/Microsoft.AspNetCore.Rewrite.Tests/IISUrlRewrite/MiddleWareTests.cs @@ -336,5 +336,35 @@ namespace Microsoft.AspNetCore.Rewrite.Tests.UrlRewrite Assert.Equal(response.Headers.Location.OriginalString, "/foo"); } + + [Theory] + [InlineData("IsFile")] + [InlineData("isfile")] + [InlineData("IsDirectory")] + [InlineData("isdirectory")] + public async Task VerifyIsFileAndIsDirectoryParsing(string matchType) + { + var options = new RewriteOptions().AddIISUrlRewrite(new StringReader($@" + + + + + + + + + + ")); + var builder = new WebHostBuilder() + .Configure(app => + { + app.UseRewriter(options); + }); + var server = new TestServer(builder); + + var response = await server.CreateClient().GetAsync("hey/hello"); + + Assert.Equal("/hey/hello/", response.Headers.Location.OriginalString); ; + } } }