IIS UrlRewrite Rule Application
This commit is contained in:
parent
bb4f5420d3
commit
5052a94cf7
|
|
@ -1,4 +1,8 @@
|
||||||
using Microsoft.AspNetCore.Builder;
|
// 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.
|
||||||
|
|
||||||
|
using System.IO;
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Rewrite;
|
using Microsoft.AspNetCore.Rewrite;
|
||||||
|
|
@ -9,7 +13,7 @@ namespace RewriteSample
|
||||||
{
|
{
|
||||||
public void Configure(IApplicationBuilder app, IHostingEnvironment hostingEnv)
|
public void Configure(IApplicationBuilder app, IHostingEnvironment hostingEnv)
|
||||||
{
|
{
|
||||||
app.UseRewriter(new UrlRewriteOptions()
|
app.UseRewriter(new RewriteOptions()
|
||||||
.ImportFromUrlRewrite(hostingEnv, "UrlRewrite.xml")
|
.ImportFromUrlRewrite(hostingEnv, "UrlRewrite.xml")
|
||||||
.ImportFromModRewrite(hostingEnv, "Rewrite.txt"));
|
.ImportFromModRewrite(hostingEnv, "Rewrite.txt"));
|
||||||
app.Run(context => context.Response.WriteAsync(context.Request.Path));
|
app.Run(context => context.Response.WriteAsync(context.Request.Path));
|
||||||
|
|
@ -21,6 +25,7 @@ namespace RewriteSample
|
||||||
var host = new WebHostBuilder()
|
var host = new WebHostBuilder()
|
||||||
.UseKestrel()
|
.UseKestrel()
|
||||||
.UseStartup<Startup>()
|
.UseStartup<Startup>()
|
||||||
|
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
host.Run();
|
host.Run();
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,12 @@
|
||||||
<rewrite>
|
<rewrite>
|
||||||
<rules>
|
<rules>
|
||||||
<rule name="Fail bad requests">
|
<rule name="Query String Rewrite">
|
||||||
<match url=".*"/>
|
<match url="page\.asp$" />
|
||||||
<conditions>
|
<conditions>
|
||||||
<add input="{HTTP_HOST}" pattern="localhost" negate="true" />
|
<add input="{QUERY_STRING}" pattern="p1=(\d+)" />
|
||||||
|
<add input="##{C:1}##_{QUERY_STRING}" pattern="##([^#]+)##_.*p2=(\d+)" />
|
||||||
</conditions>
|
</conditions>
|
||||||
<action type="AbortRequest" />
|
<action type="rewrite" url="newpage.aspx?param1={C:1}&param2={C:2}" appendQueryString="false"/>
|
||||||
</rule>
|
|
||||||
<rule name="Redirect from blog">
|
|
||||||
<match url="^blog/([_0-9a-z-]+)/([0-9]+)" />
|
|
||||||
<action type="Redirect" url="article/{R:2}/{R:1}" redirectType="Found" />
|
|
||||||
</rule>
|
|
||||||
<rule name="Rewrite to article.aspx">
|
|
||||||
<match url="^article/([0-9]+)/([_0-9a-z-]+)" />
|
|
||||||
<action type="Rewrite" url="article.aspx?id={R:1}&title={R:2}" />
|
|
||||||
</rule>
|
</rule>
|
||||||
</rules>
|
</rules>
|
||||||
</rewrite>
|
</rewrite>
|
||||||
|
|
@ -4,21 +4,21 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Microsoft.AspNetCore.Rewrite.RuleAbstraction;
|
using Microsoft.AspNetCore.Rewrite.Internal;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite
|
namespace Microsoft.AspNetCore.Rewrite
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The builder to a list of rules for <see cref="UrlRewriteOptions"/> and <see cref="UrlRewriteMiddleware"/>
|
/// The builder to a list of rules for <see cref="RewriteOptions"/> and <see cref="RewriteMiddleware"/>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class UrlRewriteOptionsAddRulesExtensions
|
public static class CodeRewriteExtensions
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a rule to the current rules.
|
/// Adds a rule to the current rules.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="options">The UrlRewrite options.</param>
|
/// <param name="options">The UrlRewrite options.</param>
|
||||||
/// <param name="rule">A rule to be added to the current rules.</param>
|
/// <param name="rule">A rule to be added to the current rules.</param>
|
||||||
public static UrlRewriteOptions AddRule(this UrlRewriteOptions options, Rule rule)
|
public static RewriteOptions AddRule(this RewriteOptions options, Rule rule)
|
||||||
{
|
{
|
||||||
options.Rules.Add(rule);
|
options.Rules.Add(rule);
|
||||||
return options;
|
return options;
|
||||||
|
|
@ -29,7 +29,7 @@ namespace Microsoft.AspNetCore.Rewrite
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="options">The UrlRewrite options.</param>
|
/// <param name="options">The UrlRewrite options.</param>
|
||||||
/// <param name="rules">A list of rules.</param>
|
/// <param name="rules">A list of rules.</param>
|
||||||
public static UrlRewriteOptions AddRules(this UrlRewriteOptions options, List<Rule> rules)
|
public static RewriteOptions AddRules(this RewriteOptions options, List<Rule> rules)
|
||||||
{
|
{
|
||||||
options.Rules.AddRange(rules);
|
options.Rules.AddRange(rules);
|
||||||
return options;
|
return options;
|
||||||
|
|
@ -43,7 +43,7 @@ namespace Microsoft.AspNetCore.Rewrite
|
||||||
/// <param name="newPath">The string to replace the path with (with capture parameters).</param>
|
/// <param name="newPath">The string to replace the path with (with capture parameters).</param>
|
||||||
/// <param name="stopRewriteOnSuccess">Whether or not to stop rewriting on success of rule.</param>
|
/// <param name="stopRewriteOnSuccess">Whether or not to stop rewriting on success of rule.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static UrlRewriteOptions RewritePath(this UrlRewriteOptions options, string regex, string newPath, bool stopRewriteOnSuccess = false)
|
public static RewriteOptions RewritePath(this RewriteOptions options, string regex, string newPath, bool stopRewriteOnSuccess = false)
|
||||||
{
|
{
|
||||||
options.Rules.Add(new PathRule { MatchPattern = new Regex(regex, RegexOptions.Compiled, TimeSpan.FromMilliseconds(1)), OnMatch = newPath, OnCompletion = stopRewriteOnSuccess ? Transformation.TerminatingRewrite : Transformation.Rewrite });
|
options.Rules.Add(new PathRule { MatchPattern = new Regex(regex, RegexOptions.Compiled, TimeSpan.FromMilliseconds(1)), OnMatch = newPath, OnCompletion = stopRewriteOnSuccess ? Transformation.TerminatingRewrite : Transformation.Rewrite });
|
||||||
return options;
|
return options;
|
||||||
|
|
@ -55,7 +55,7 @@ namespace Microsoft.AspNetCore.Rewrite
|
||||||
/// <param name="options">The Url rewrite options.</param>
|
/// <param name="options">The Url rewrite options.</param>
|
||||||
/// <param name="stopRewriteOnSuccess">Whether or not to stop rewriting on success of rule.</param>
|
/// <param name="stopRewriteOnSuccess">Whether or not to stop rewriting on success of rule.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static UrlRewriteOptions RewriteScheme(this UrlRewriteOptions options, bool stopRewriteOnSuccess = false)
|
public static RewriteOptions RewriteScheme(this RewriteOptions options, bool stopRewriteOnSuccess = false)
|
||||||
{
|
{
|
||||||
options.Rules.Add(new SchemeRule {OnCompletion = stopRewriteOnSuccess ? Transformation.TerminatingRewrite : Transformation.Rewrite });
|
options.Rules.Add(new SchemeRule {OnCompletion = stopRewriteOnSuccess ? Transformation.TerminatingRewrite : Transformation.Rewrite });
|
||||||
return options;
|
return options;
|
||||||
|
|
@ -69,7 +69,7 @@ namespace Microsoft.AspNetCore.Rewrite
|
||||||
/// <param name="newPath">The string to replace the path with (with capture parameters).</param>
|
/// <param name="newPath">The string to replace the path with (with capture parameters).</param>
|
||||||
/// <param name="stopRewriteOnSuccess">Whether or not to stop rewriting on success of rule.</param>
|
/// <param name="stopRewriteOnSuccess">Whether or not to stop rewriting on success of rule.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static UrlRewriteOptions RedirectPath(this UrlRewriteOptions options, string regex, string newPath, bool stopRewriteOnSuccess = false)
|
public static RewriteOptions RedirectPath(this RewriteOptions options, string regex, string newPath, bool stopRewriteOnSuccess = false)
|
||||||
{
|
{
|
||||||
options.Rules.Add(new PathRule { MatchPattern = new Regex(regex, RegexOptions.Compiled, TimeSpan.FromMilliseconds(1)), OnMatch = newPath, OnCompletion = Transformation.Redirect });
|
options.Rules.Add(new PathRule { MatchPattern = new Regex(regex, RegexOptions.Compiled, TimeSpan.FromMilliseconds(1)), OnMatch = newPath, OnCompletion = Transformation.Redirect });
|
||||||
return options;
|
return options;
|
||||||
|
|
@ -81,7 +81,7 @@ namespace Microsoft.AspNetCore.Rewrite
|
||||||
/// <param name="options">The Url rewrite options.</param>
|
/// <param name="options">The Url rewrite options.</param>
|
||||||
/// <param name="sslPort">The port to redirect the scheme to.</param>
|
/// <param name="sslPort">The port to redirect the scheme to.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static UrlRewriteOptions RedirectScheme(this UrlRewriteOptions options, int? sslPort)
|
public static RewriteOptions RedirectScheme(this RewriteOptions options, int? sslPort)
|
||||||
{
|
{
|
||||||
options.Rules.Add(new SchemeRule { SSLPort = sslPort, OnCompletion = Transformation.Redirect });
|
options.Rules.Add(new SchemeRule { SSLPort = sslPort, OnCompletion = Transformation.Redirect });
|
||||||
return options;
|
return options;
|
||||||
|
|
@ -95,7 +95,7 @@ namespace Microsoft.AspNetCore.Rewrite
|
||||||
/// <param name="transform"></param>
|
/// <param name="transform"></param>
|
||||||
/// <param name="description"></param>
|
/// <param name="description"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static UrlRewriteOptions CustomRule(this UrlRewriteOptions options, Func<UrlRewriteContext, RuleResult> onApplyRule, Transformation transform, string description = null)
|
public static RewriteOptions CustomRule(this RewriteOptions options, Func<RewriteContext, RuleResult> onApplyRule, Transformation transform, string description = null)
|
||||||
{
|
{
|
||||||
options.Rules.Add(new FunctionalRule { OnApplyRule = onApplyRule, OnCompletion = transform});
|
options.Rules.Add(new FunctionalRule { OnApplyRule = onApplyRule, OnCompletion = transform});
|
||||||
return options;
|
return options;
|
||||||
|
|
@ -3,12 +3,12 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.RuleAbstraction
|
namespace Microsoft.AspNetCore.Rewrite.Internal
|
||||||
{
|
{
|
||||||
public class FunctionalRule : Rule
|
public class FunctionalRule : Rule
|
||||||
{
|
{
|
||||||
public Func<UrlRewriteContext, RuleResult> OnApplyRule { get; set; }
|
public Func<RewriteContext, RuleResult> OnApplyRule { get; set; }
|
||||||
public Transformation OnCompletion { get; set; } = Transformation.Rewrite;
|
public Transformation OnCompletion { get; set; } = Transformation.Rewrite;
|
||||||
public override RuleResult ApplyRule(UrlRewriteContext context) => OnApplyRule(context);
|
public override RuleResult ApplyRule(RewriteContext context) => OnApplyRule(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// 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.
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.ModRewrite
|
namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
|
||||||
{
|
{
|
||||||
public class Condition
|
public class Condition
|
||||||
{
|
{
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.ModRewrite
|
namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
|
||||||
{
|
{
|
||||||
public class ConditionBuilder
|
public class ConditionBuilder
|
||||||
{
|
{
|
||||||
|
|
@ -2,9 +2,9 @@
|
||||||
// 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.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Microsoft.AspNetCore.Rewrite.Operands;
|
using Microsoft.AspNetCore.Rewrite.Internal.ModRewrite.Operands;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.ModRewrite
|
namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents the ConditionPattern for a mod_rewrite rule.
|
/// Represents the ConditionPattern for a mod_rewrite rule.
|
||||||
|
|
@ -21,7 +21,7 @@ namespace Microsoft.AspNetCore.Rewrite.ModRewrite
|
||||||
/// <param name="previous">The previous condition results (for backreferences).</param>
|
/// <param name="previous">The previous condition results (for backreferences).</param>
|
||||||
/// <param name="testString">The testString created from the <see cref="Pattern"/>.</param>
|
/// <param name="testString">The testString created from the <see cref="Pattern"/>.</param>
|
||||||
/// <returns>If the testString satisfies the condition</returns>
|
/// <returns>If the testString satisfies the condition</returns>
|
||||||
public bool? CheckConditionExpression(UrlRewriteContext context, Match previous, string testString)
|
public bool? CheckConditionExpression(RewriteContext context, Match previous, string testString)
|
||||||
{
|
{
|
||||||
return Operand.CheckOperation(previous, testString, context.FileProvider) ^ Invert;
|
return Operand.CheckOperation(previous, testString, context.FileProvider) ^ Invert;
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// 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.
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.ModRewrite
|
namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
|
||||||
{
|
{
|
||||||
public enum ConditionFlagType
|
public enum ConditionFlagType
|
||||||
{
|
{
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.ModRewrite
|
namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
|
||||||
{
|
{
|
||||||
// TODO Refactor Condition Flags and Rule Flags under base flag class
|
// TODO Refactor Condition Flags and Rule Flags under base flag class
|
||||||
public class ConditionFlags
|
public class ConditionFlags
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
using System;
|
using System;
|
||||||
using Microsoft.AspNetCore.Rewrite.Internal;
|
using Microsoft.AspNetCore.Rewrite.Internal;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.ModRewrite
|
namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Parses the "CondPattern" portion of the RewriteCond.
|
/// Parses the "CondPattern" portion of the RewriteCond.
|
||||||
|
|
@ -5,7 +5,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Microsoft.AspNetCore.Rewrite.Internal;
|
using Microsoft.AspNetCore.Rewrite.Internal;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.ModRewrite
|
namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Parses the TestString segment of the mod_rewrite condition.
|
/// Parses the TestString segment of the mod_rewrite condition.
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// 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.
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.ModRewrite
|
namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
|
||||||
{
|
{
|
||||||
public enum ConditionType
|
public enum ConditionType
|
||||||
{
|
{
|
||||||
|
|
@ -3,10 +3,9 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Microsoft.AspNetCore.Rewrite.Operands;
|
using Microsoft.AspNetCore.Rewrite.Internal.ModRewrite.Operands;
|
||||||
using Microsoft.AspNetCore.Rewrite.RuleAbstraction;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.ModRewrite
|
namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts a parsed expression into a mod_rewrite condition.
|
/// Converts a parsed expression into a mod_rewrite condition.
|
||||||
|
|
@ -4,9 +4,9 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Microsoft.AspNetCore.Rewrite.RuleAbstraction;
|
using Microsoft.AspNetCore.Rewrite.Internal;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.ModRewrite
|
namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.ModRewrite
|
namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Parses the flags
|
/// Parses the flags
|
||||||
|
|
@ -6,7 +6,7 @@ using System.Globalization;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Microsoft.Extensions.FileProviders;
|
using Microsoft.Extensions.FileProviders;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.Operands
|
namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite.Operands
|
||||||
{
|
{
|
||||||
public class IntegerOperand : Operand
|
public class IntegerOperand : Operand
|
||||||
{
|
{
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// 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.
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.Operands
|
namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite.Operands
|
||||||
{
|
{
|
||||||
public enum IntegerOperationType
|
public enum IntegerOperationType
|
||||||
{
|
{
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Microsoft.Extensions.FileProviders;
|
using Microsoft.Extensions.FileProviders;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.Operands
|
namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite.Operands
|
||||||
{
|
{
|
||||||
public abstract class Operand
|
public abstract class Operand
|
||||||
{
|
{
|
||||||
|
|
@ -5,7 +5,7 @@ using System;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Microsoft.Extensions.FileProviders;
|
using Microsoft.Extensions.FileProviders;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.Operands
|
namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite.Operands
|
||||||
{
|
{
|
||||||
public class PropertyOperand : Operand
|
public class PropertyOperand : Operand
|
||||||
{
|
{
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// 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.
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.Operands
|
namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite.Operands
|
||||||
{
|
{
|
||||||
public enum PropertyOperationType
|
public enum PropertyOperationType
|
||||||
{
|
{
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Microsoft.Extensions.FileProviders;
|
using Microsoft.Extensions.FileProviders;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.Operands
|
namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite.Operands
|
||||||
{
|
{
|
||||||
public class RegexOperand : Operand
|
public class RegexOperand : Operand
|
||||||
{
|
{
|
||||||
|
|
@ -5,7 +5,7 @@ using System;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Microsoft.Extensions.FileProviders;
|
using Microsoft.Extensions.FileProviders;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.Operands
|
namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite.Operands
|
||||||
{
|
{
|
||||||
public class StringOperand : Operand
|
public class StringOperand : Operand
|
||||||
{
|
{
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// 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.
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.Operands
|
namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite.Operands
|
||||||
{
|
{
|
||||||
public enum StringOperationType
|
public enum StringOperationType
|
||||||
{
|
{
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// 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.
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.ModRewrite
|
namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
|
||||||
{
|
{
|
||||||
public enum OperationType
|
public enum OperationType
|
||||||
{
|
{
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// 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.
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.ModRewrite
|
namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
|
||||||
{
|
{
|
||||||
public class ParsedModRewriteExpression
|
public class ParsedModRewriteExpression
|
||||||
{
|
{
|
||||||
|
|
@ -1,14 +1,12 @@
|
||||||
// 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;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Rewrite.ModRewrite;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.ModRewrite
|
namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Contains a sequence of pattern segments, which on obtaining the context, will create the appropriate
|
/// Contains a sequence of pattern segments, which on obtaining the context, will create the appropriate
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// 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.
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.ModRewrite
|
namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A Pattern segment contains a portion of the test string/ substitution segment with a type associated.
|
/// A Pattern segment contains a portion of the test string/ substitution segment with a type associated.
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.ModRewrite
|
namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
|
||||||
{
|
{
|
||||||
public class RuleBuilder
|
public class RuleBuilder
|
||||||
{
|
{
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// 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.
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.ModRewrite
|
namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
|
||||||
{
|
{
|
||||||
public enum RuleFlagType
|
public enum RuleFlagType
|
||||||
{
|
{
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.ModRewrite
|
namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
|
||||||
{
|
{
|
||||||
public class RuleFlags
|
public class RuleFlags
|
||||||
{
|
{
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.ModRewrite
|
namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
|
||||||
{
|
{
|
||||||
public static class RuleRegexParser
|
public static class RuleRegexParser
|
||||||
{
|
{
|
||||||
|
|
@ -9,7 +9,7 @@ using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Http.Features;
|
using Microsoft.AspNetCore.Http.Features;
|
||||||
using Microsoft.Net.Http.Headers;
|
using Microsoft.Net.Http.Headers;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.ModRewrite
|
namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// mod_rewrite lookups for specific string constants.
|
/// mod_rewrite lookups for specific string constants.
|
||||||
|
|
@ -5,7 +5,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Microsoft.AspNetCore.Rewrite.Internal;
|
using Microsoft.AspNetCore.Rewrite.Internal;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.ModRewrite
|
namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tokenizes a mod_rewrite rule, delimited by spaces.
|
/// Tokenizes a mod_rewrite rule, delimited by spaces.
|
||||||
|
|
@ -6,9 +6,8 @@ using System.Collections.Generic;
|
||||||
using Microsoft.Net.Http.Headers;
|
using Microsoft.Net.Http.Headers;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Rewrite.RuleAbstraction;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.ModRewrite
|
namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
|
||||||
{
|
{
|
||||||
public class ModRewriteRule : Rule
|
public class ModRewriteRule : Rule
|
||||||
{
|
{
|
||||||
|
|
@ -28,7 +27,7 @@ namespace Microsoft.AspNetCore.Rewrite.ModRewrite
|
||||||
Description = description;
|
Description = description;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override RuleResult ApplyRule(UrlRewriteContext context)
|
public override RuleResult ApplyRule(RewriteContext context)
|
||||||
{
|
{
|
||||||
// 1. Figure out which section of the string to match for the initial rule.
|
// 1. Figure out which section of the string to match for the initial rule.
|
||||||
var results = InitialRule.Operand.RegexOperation.Match(context.HttpContext.Request.Path.ToString());
|
var results = InitialRule.Operand.RegexOperation.Match(context.HttpContext.Request.Path.ToString());
|
||||||
|
|
@ -36,7 +35,7 @@ namespace Microsoft.AspNetCore.Rewrite.ModRewrite
|
||||||
string flagRes = null;
|
string flagRes = null;
|
||||||
if (CheckMatchResult(results.Success))
|
if (CheckMatchResult(results.Success))
|
||||||
{
|
{
|
||||||
return new RuleResult { Result = RuleTerminiation.Continue };
|
return RuleResult.Continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Flags.HasFlag(RuleFlagType.EscapeBackreference))
|
if (Flags.HasFlag(RuleFlagType.EscapeBackreference))
|
||||||
|
|
@ -49,7 +48,7 @@ namespace Microsoft.AspNetCore.Rewrite.ModRewrite
|
||||||
|
|
||||||
if (!CheckCondition(context, results, previous))
|
if (!CheckCondition(context, results, previous))
|
||||||
{
|
{
|
||||||
return new RuleResult { Result = RuleTerminiation.Continue };
|
return RuleResult.Continue;
|
||||||
}
|
}
|
||||||
// TODO add chained flag
|
// TODO add chained flag
|
||||||
|
|
||||||
|
|
@ -82,12 +81,12 @@ namespace Microsoft.AspNetCore.Rewrite.ModRewrite
|
||||||
if (Flags.HasFlag(RuleFlagType.Forbidden))
|
if (Flags.HasFlag(RuleFlagType.Forbidden))
|
||||||
{
|
{
|
||||||
context.HttpContext.Response.StatusCode = StatusCodes.Status403Forbidden;
|
context.HttpContext.Response.StatusCode = StatusCodes.Status403Forbidden;
|
||||||
return new RuleResult { Result = RuleTerminiation.ResponseComplete };
|
return RuleResult.ResponseComplete;
|
||||||
}
|
}
|
||||||
else if (Flags.HasFlag(RuleFlagType.Gone))
|
else if (Flags.HasFlag(RuleFlagType.Gone))
|
||||||
{
|
{
|
||||||
context.HttpContext.Response.StatusCode = StatusCodes.Status410Gone;
|
context.HttpContext.Response.StatusCode = StatusCodes.Status410Gone;
|
||||||
return new RuleResult { Result = RuleTerminiation.ResponseComplete };
|
return RuleResult.ResponseComplete;
|
||||||
}
|
}
|
||||||
else if (result == "-")
|
else if (result == "-")
|
||||||
{
|
{
|
||||||
|
|
@ -124,7 +123,7 @@ namespace Microsoft.AspNetCore.Rewrite.ModRewrite
|
||||||
context.HttpContext.Response.Headers[HeaderNames.Location] = "/" + result + context.HttpContext.Request.QueryString;
|
context.HttpContext.Response.Headers[HeaderNames.Location] = "/" + result + context.HttpContext.Request.QueryString;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new RuleResult { Result = RuleTerminiation.ResponseComplete };
|
return RuleResult.ResponseComplete;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -145,11 +144,11 @@ namespace Microsoft.AspNetCore.Rewrite.ModRewrite
|
||||||
}
|
}
|
||||||
if (Flags.HasFlag(RuleFlagType.Last) || Flags.HasFlag(RuleFlagType.End))
|
if (Flags.HasFlag(RuleFlagType.Last) || Flags.HasFlag(RuleFlagType.End))
|
||||||
{
|
{
|
||||||
return new RuleResult { Result = RuleTerminiation.StopRules };
|
return RuleResult.StopRules;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return new RuleResult { Result = RuleTerminiation.Continue };
|
return RuleResult.Continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -163,7 +162,7 @@ namespace Microsoft.AspNetCore.Rewrite.ModRewrite
|
||||||
return !(result.Value ^ InitialRule.Invert);
|
return !(result.Value ^ InitialRule.Invert);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool CheckCondition(UrlRewriteContext context, Match results, Match previous)
|
private bool CheckCondition(RewriteContext context, Match results, Match previous)
|
||||||
{
|
{
|
||||||
if (Conditions == null)
|
if (Conditions == null)
|
||||||
{
|
{
|
||||||
|
|
@ -3,14 +3,14 @@
|
||||||
|
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.RuleAbstraction
|
namespace Microsoft.AspNetCore.Rewrite.Internal
|
||||||
{
|
{
|
||||||
public class PathRule : Rule
|
public class PathRule : Rule
|
||||||
{
|
{
|
||||||
public Regex MatchPattern { get; set; }
|
public Regex MatchPattern { get; set; }
|
||||||
public string OnMatch { get; set; }
|
public string OnMatch { get; set; }
|
||||||
public Transformation OnCompletion { get; set; } = Transformation.Rewrite;
|
public Transformation OnCompletion { get; set; } = Transformation.Rewrite;
|
||||||
public override RuleResult ApplyRule(UrlRewriteContext context)
|
public override RuleResult ApplyRule(RewriteContext context)
|
||||||
{
|
{
|
||||||
var matches = MatchPattern.Match(context.HttpContext.Request.Path);
|
var matches = MatchPattern.Match(context.HttpContext.Request.Path);
|
||||||
if (matches.Success)
|
if (matches.Success)
|
||||||
|
|
@ -27,7 +27,7 @@ namespace Microsoft.AspNetCore.Rewrite.RuleAbstraction
|
||||||
path,
|
path,
|
||||||
req.QueryString);
|
req.QueryString);
|
||||||
context.HttpContext.Response.Redirect(newUrl);
|
context.HttpContext.Response.Redirect(newUrl);
|
||||||
return new RuleResult { Result = RuleTerminiation.ResponseComplete };
|
return RuleResult.ResponseComplete;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -35,14 +35,14 @@ namespace Microsoft.AspNetCore.Rewrite.RuleAbstraction
|
||||||
}
|
}
|
||||||
if (OnCompletion == Transformation.TerminatingRewrite)
|
if (OnCompletion == Transformation.TerminatingRewrite)
|
||||||
{
|
{
|
||||||
return new RuleResult { Result = RuleTerminiation.StopRules };
|
return RuleResult.StopRules;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return new RuleResult { Result = RuleTerminiation.Continue };
|
return RuleResult.Continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new RuleResult { Result = RuleTerminiation.Continue };
|
return RuleResult.Continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
// 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.
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.RuleAbstraction
|
namespace Microsoft.AspNetCore.Rewrite.Internal
|
||||||
{
|
{
|
||||||
public abstract class Rule
|
public abstract class Rule
|
||||||
{
|
{
|
||||||
public abstract RuleResult ApplyRule(UrlRewriteContext context);
|
public abstract RuleResult ApplyRule(RewriteContext context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
// 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 Microsoft.AspNetCore.Rewrite.Operands;
|
using Microsoft.AspNetCore.Rewrite.Internal.ModRewrite.Operands;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.RuleAbstraction
|
namespace Microsoft.AspNetCore.Rewrite.Internal
|
||||||
{
|
{
|
||||||
public class RuleExpression
|
public class RuleExpression
|
||||||
{
|
{
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Rewrite.Internal
|
||||||
|
{
|
||||||
|
public class RuleResult
|
||||||
|
{
|
||||||
|
public static RuleResult Continue = new RuleResult { Result = RuleTerminiation.Continue };
|
||||||
|
public static RuleResult ResponseComplete = new RuleResult { Result = RuleTerminiation.ResponseComplete };
|
||||||
|
public static RuleResult StopRules = new RuleResult { Result = RuleTerminiation.StopRules };
|
||||||
|
|
||||||
|
public RuleTerminiation Result { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,9 +1,12 @@
|
||||||
// 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.
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite
|
namespace Microsoft.AspNetCore.Rewrite.Internal
|
||||||
{
|
{
|
||||||
public class ModRewriteCreatorTest
|
public enum RuleTerminiation
|
||||||
{
|
{
|
||||||
|
Continue,
|
||||||
|
ResponseComplete,
|
||||||
|
StopRules
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4,13 +4,13 @@
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.RuleAbstraction
|
namespace Microsoft.AspNetCore.Rewrite.Internal
|
||||||
{
|
{
|
||||||
public class SchemeRule : Rule
|
public class SchemeRule : Rule
|
||||||
{
|
{
|
||||||
public int? SSLPort { get; set; }
|
public int? SSLPort { get; set; }
|
||||||
public Transformation OnCompletion { get; set; } = Transformation.Rewrite;
|
public Transformation OnCompletion { get; set; } = Transformation.Rewrite;
|
||||||
public override RuleResult ApplyRule(UrlRewriteContext context)
|
public override RuleResult ApplyRule(RewriteContext context)
|
||||||
{
|
{
|
||||||
|
|
||||||
// TODO this only does http to https, add more features in the future.
|
// TODO this only does http to https, add more features in the future.
|
||||||
|
|
@ -34,11 +34,11 @@ namespace Microsoft.AspNetCore.Rewrite.RuleAbstraction
|
||||||
context.HttpContext.Request.Host = host;
|
context.HttpContext.Request.Host = host;
|
||||||
if (OnCompletion == Transformation.TerminatingRewrite)
|
if (OnCompletion == Transformation.TerminatingRewrite)
|
||||||
{
|
{
|
||||||
return new RuleResult { Result = RuleTerminiation.StopRules };
|
return RuleResult.StopRules;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return new RuleResult { Result = RuleTerminiation.Continue };
|
return RuleResult.Continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -46,9 +46,9 @@ namespace Microsoft.AspNetCore.Rewrite.RuleAbstraction
|
||||||
|
|
||||||
var newUrl = new StringBuilder().Append("https://").Append(host).Append(req.PathBase).Append(req.Path).Append(req.QueryString);
|
var newUrl = new StringBuilder().Append("https://").Append(host).Append(req.PathBase).Append(req.Path).Append(req.QueryString);
|
||||||
context.HttpContext.Response.Redirect(newUrl.ToString());
|
context.HttpContext.Response.Redirect(newUrl.ToString());
|
||||||
return new RuleResult { Result = RuleTerminiation.ResponseComplete };
|
return RuleResult.ResponseComplete;
|
||||||
}
|
}
|
||||||
return new RuleResult { Result = RuleTerminiation.Continue }; ;
|
return RuleResult.Continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// 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.
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.RuleAbstraction
|
namespace Microsoft.AspNetCore.Rewrite.Internal
|
||||||
{
|
{
|
||||||
public enum Transformation
|
public enum Transformation
|
||||||
{
|
{
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// 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.
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.UrlRewrite
|
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite
|
||||||
{
|
{
|
||||||
public enum ActionType
|
public enum ActionType
|
||||||
{
|
{
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite
|
||||||
|
{
|
||||||
|
public class Condition
|
||||||
|
{
|
||||||
|
public Pattern Input { get; set; }
|
||||||
|
public UrlMatch Match { get; set; }
|
||||||
|
public MatchResults Evaluate(RewriteContext context, MatchResults ruleMatch, MatchResults condMatch)
|
||||||
|
{
|
||||||
|
var pattern = Input.Evaluate(context.HttpContext, ruleMatch, condMatch);
|
||||||
|
return Match.Evaluate(pattern, context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite
|
||||||
|
{
|
||||||
|
public class Conditions
|
||||||
|
{
|
||||||
|
public List<Condition> ConditionList { get; set; } = new List<Condition>();
|
||||||
|
public LogicalGrouping MatchType { get; set; } // default is MatchAll
|
||||||
|
public bool TrackingAllCaptures { get; set; }
|
||||||
|
|
||||||
|
public MatchResults Evaluate(RewriteContext context, MatchResults ruleMatch)
|
||||||
|
{
|
||||||
|
MatchResults prevCond = null;
|
||||||
|
var success = true;
|
||||||
|
foreach (var condition in ConditionList)
|
||||||
|
{
|
||||||
|
var res = condition.Evaluate(context, ruleMatch, prevCond);
|
||||||
|
success = (MatchType == LogicalGrouping.MatchAll ? (success && res.Success) : (success || res.Success));
|
||||||
|
prevCond = res;
|
||||||
|
}
|
||||||
|
return new MatchResults { Success = success, BackReference = prevCond?.BackReference };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,11 +3,9 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text.Encodings.Web;
|
using Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite.PatternSegments;
|
||||||
using Microsoft.AspNetCore.Rewrite.Internal;
|
|
||||||
using Microsoft.AspNetCore.Rewrite.UrlRewrite.PatternSegments;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.UrlRewrite
|
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// 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.
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.UrlRewrite
|
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite
|
||||||
{
|
{
|
||||||
public enum LogicalGrouping
|
public enum LogicalGrouping
|
||||||
{
|
{
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite
|
||||||
|
{
|
||||||
|
public class MatchResults
|
||||||
|
{
|
||||||
|
public GroupCollection BackReference { get; set; }
|
||||||
|
public bool Success { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// 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.
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.UrlRewrite
|
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite
|
||||||
{
|
{
|
||||||
public enum MatchType
|
public enum MatchType
|
||||||
{
|
{
|
||||||
|
|
@ -1,14 +1,10 @@
|
||||||
// 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.Text.RegularExpressions;
|
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.UrlRewrite
|
|
||||||
{
|
{
|
||||||
public class Condition
|
public class ParsedCondition
|
||||||
{
|
{
|
||||||
public Pattern Input { get; set; }
|
|
||||||
public Regex MatchPattern { get; set; }
|
|
||||||
public bool Negate { get; set; }
|
public bool Negate { get; set; }
|
||||||
public bool IgnoreCase { get; set; } = true;
|
public bool IgnoreCase { get; set; } = true;
|
||||||
public MatchType MatchType { get; set; } = MatchType.Pattern;
|
public MatchType MatchType { get; set; } = MatchType.Pattern;
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
// 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.
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.UrlRewrite
|
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite
|
||||||
{
|
{
|
||||||
public class UrlAction
|
public class ParsedUrlAction
|
||||||
{
|
{
|
||||||
public ActionType Type { get; set; }
|
public ActionType Type { get; set; }
|
||||||
public Pattern Url { get; set; }
|
public Pattern Url { get; set; }
|
||||||
public bool AppendQueryString { get; set; }
|
public bool AppendQueryString { get; set; } = true;
|
||||||
public bool LogRewrittenUrl { get; set; }
|
public bool LogRewrittenUrl { get; set; } // Ignoring this flag.
|
||||||
public RedirectType RedirectType { get; set; } = RedirectType.Permanent;
|
public RedirectType RedirectType { get; set; } = RedirectType.Permanent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
// 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.
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.RuleAbstraction
|
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite
|
||||||
{
|
{
|
||||||
public class RuleResult
|
public class ParsedUrlMatch
|
||||||
{
|
{
|
||||||
public RuleTerminiation Result { get; set; }
|
public bool IgnoreCase { get; set; }
|
||||||
|
public bool Negate { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3,23 +3,23 @@
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.UrlRewrite
|
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite
|
||||||
{
|
{
|
||||||
public class Pattern
|
public class Pattern
|
||||||
{
|
{
|
||||||
public IList<PatternSegment> PatternSegments { get; }
|
public IList<PatternSegment> PatternSegments { get; }
|
||||||
|
|
||||||
public Pattern(List<PatternSegment> patternSegments)
|
public Pattern(List<PatternSegment> patternSegments)
|
||||||
{
|
{
|
||||||
PatternSegments = patternSegments;
|
PatternSegments = patternSegments;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Evaluate(HttpContext context, Match ruleMatch, Match condMatch)
|
public string Evaluate(HttpContext context, MatchResults ruleMatch, MatchResults condMatch)
|
||||||
{
|
{
|
||||||
var strBuilder = new StringBuilder();
|
var strBuilder = new StringBuilder();
|
||||||
|
|
||||||
|
// TODO consider thread static for string builder - DAVID PERF
|
||||||
foreach (var pattern in PatternSegments)
|
foreach (var pattern in PatternSegments)
|
||||||
{
|
{
|
||||||
strBuilder.Append(pattern.Evaluate(context, ruleMatch, condMatch));
|
strBuilder.Append(pattern.Evaluate(context, ruleMatch, condMatch));
|
||||||
|
|
@ -1,15 +1,13 @@
|
||||||
// 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.Text.RegularExpressions;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.UrlRewrite
|
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite
|
||||||
{
|
{
|
||||||
public abstract class PatternSegment
|
public abstract class PatternSegment
|
||||||
{
|
{
|
||||||
// Match from prevRule, Match from prevCond
|
// Match from prevRule, Match from prevCond
|
||||||
public abstract string Evaluate(HttpContext context, Match ruleMatch, Match condMatch);
|
public abstract string Evaluate(HttpContext context, MatchResults ruleMatch, MatchResults condMatch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,10 +1,9 @@
|
||||||
// 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.Text.RegularExpressions;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.UrlRewrite.PatternSegments
|
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite.PatternSegments
|
||||||
{
|
{
|
||||||
public class ConditionMatchSegment : PatternSegment
|
public class ConditionMatchSegment : PatternSegment
|
||||||
{
|
{
|
||||||
|
|
@ -15,9 +14,9 @@ namespace Microsoft.AspNetCore.Rewrite.UrlRewrite.PatternSegments
|
||||||
Index = index;
|
Index = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Evaluate(HttpContext context, Match ruleMatch, Match condMatch)
|
public override string Evaluate(HttpContext context, MatchResults ruleMatch, MatchResults condMatch)
|
||||||
{
|
{
|
||||||
return condMatch?.Groups[Index]?.Value;
|
return condMatch?.BackReference[Index]?.Value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,10 +1,9 @@
|
||||||
// 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.Text.RegularExpressions;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.UrlRewrite.PatternSegments
|
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite.PatternSegments
|
||||||
{
|
{
|
||||||
public class HeaderSegment : PatternSegment
|
public class HeaderSegment : PatternSegment
|
||||||
{
|
{
|
||||||
|
|
@ -15,7 +14,7 @@ namespace Microsoft.AspNetCore.Rewrite.UrlRewrite.PatternSegments
|
||||||
Header = header;
|
Header = header;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Evaluate(HttpContext context, Match ruleMatch, Match condMatch)
|
public override string Evaluate(HttpContext context, MatchResults ruleMatch, MatchResults condMatch)
|
||||||
{
|
{
|
||||||
return context.Request.Headers[Header];
|
return context.Request.Headers[Header];
|
||||||
}
|
}
|
||||||
|
|
@ -1,14 +1,13 @@
|
||||||
// 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.Text.RegularExpressions;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.UrlRewrite.PatternSegments
|
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite.PatternSegments
|
||||||
{
|
{
|
||||||
public class IsHttpsSegment : PatternSegment
|
public class IsHttpsSegment : PatternSegment
|
||||||
{
|
{
|
||||||
public override string Evaluate(HttpContext context, Match ruleMatch, Match condMatch)
|
public override string Evaluate(HttpContext context, MatchResults ruleMatch, MatchResults condMatch)
|
||||||
{
|
{
|
||||||
return context.Request.IsHttps ? "ON" : "OFF";
|
return context.Request.IsHttps ? "ON" : "OFF";
|
||||||
}
|
}
|
||||||
|
|
@ -1,10 +1,9 @@
|
||||||
// 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.Text.RegularExpressions;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.UrlRewrite.PatternSegments
|
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite.PatternSegments
|
||||||
{
|
{
|
||||||
public class LiteralSegment : PatternSegment
|
public class LiteralSegment : PatternSegment
|
||||||
{
|
{
|
||||||
|
|
@ -15,7 +14,7 @@ namespace Microsoft.AspNetCore.Rewrite.UrlRewrite.PatternSegments
|
||||||
Literal = literal;
|
Literal = literal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Evaluate(HttpContext context, Match ruleMatch, Match condMatch)
|
public override string Evaluate(HttpContext context, MatchResults ruleMatch, MatchResults condMatch)
|
||||||
{
|
{
|
||||||
return Literal;
|
return Literal;
|
||||||
}
|
}
|
||||||
|
|
@ -1,14 +1,13 @@
|
||||||
// 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.Text.RegularExpressions;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.UrlRewrite.PatternSegments
|
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite.PatternSegments
|
||||||
{
|
{
|
||||||
public class LocalAddressSegment : PatternSegment
|
public class LocalAddressSegment : PatternSegment
|
||||||
{
|
{
|
||||||
public override string Evaluate(HttpContext context, Match ruleMatch, Match condMatch)
|
public override string Evaluate(HttpContext context, MatchResults ruleMatch, MatchResults condMatch)
|
||||||
{
|
{
|
||||||
return context.Connection.LocalIpAddress?.ToString();
|
return context.Connection.LocalIpAddress?.ToString();
|
||||||
}
|
}
|
||||||
|
|
@ -1,14 +1,13 @@
|
||||||
// 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.Text.RegularExpressions;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.UrlRewrite.PatternSegments
|
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite.PatternSegments
|
||||||
{
|
{
|
||||||
public class QueryStringSegment : PatternSegment
|
public class QueryStringSegment : PatternSegment
|
||||||
{
|
{
|
||||||
public override string Evaluate(HttpContext context, Match ruleMatch, Match condMatch)
|
public override string Evaluate(HttpContext context, MatchResults ruleMatch, MatchResults condMatch)
|
||||||
{
|
{
|
||||||
return context.Request.QueryString.ToString();
|
return context.Request.QueryString.ToString();
|
||||||
}
|
}
|
||||||
|
|
@ -1,14 +1,13 @@
|
||||||
// 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.Text.RegularExpressions;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.UrlRewrite.PatternSegments
|
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite.PatternSegments
|
||||||
{
|
{
|
||||||
public class RemoteAddressSegment : PatternSegment
|
public class RemoteAddressSegment : PatternSegment
|
||||||
{
|
{
|
||||||
public override string Evaluate(HttpContext context, Match ruleMatch, Match condMatch)
|
public override string Evaluate(HttpContext context, MatchResults ruleMatch, MatchResults condMatch)
|
||||||
{
|
{
|
||||||
return context.Connection.RemoteIpAddress?.ToString();
|
return context.Connection.RemoteIpAddress?.ToString();
|
||||||
}
|
}
|
||||||
|
|
@ -2,14 +2,13 @@
|
||||||
// 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.Globalization;
|
using System.Globalization;
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.UrlRewrite.PatternSegments
|
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite.PatternSegments
|
||||||
{
|
{
|
||||||
public class RemotePortSegment : PatternSegment
|
public class RemotePortSegment : PatternSegment
|
||||||
{
|
{
|
||||||
public override string Evaluate(HttpContext context, Match ruleMatch, Match condMatch)
|
public override string Evaluate(HttpContext context, MatchResults ruleMatch, MatchResults condMatch)
|
||||||
{
|
{
|
||||||
return context.Connection.RemotePort.ToString(CultureInfo.InvariantCulture);
|
return context.Connection.RemotePort.ToString(CultureInfo.InvariantCulture);
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite.PatternSegments
|
||||||
|
{
|
||||||
|
public class RequestFileNameSegment : PatternSegment
|
||||||
|
{
|
||||||
|
public override string Evaluate(HttpContext context, MatchResults ruleMatch, MatchResults condMatch)
|
||||||
|
{
|
||||||
|
return context.Request.Path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,10 +1,9 @@
|
||||||
// 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.Text.RegularExpressions;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.UrlRewrite.PatternSegments
|
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite.PatternSegments
|
||||||
{
|
{
|
||||||
public class RuleMatchSegment : PatternSegment
|
public class RuleMatchSegment : PatternSegment
|
||||||
{
|
{
|
||||||
|
|
@ -15,9 +14,9 @@ namespace Microsoft.AspNetCore.Rewrite.UrlRewrite.PatternSegments
|
||||||
Index = index;
|
Index = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Evaluate(HttpContext context, Match ruleMatch, Match condMatch)
|
public override string Evaluate(HttpContext context, MatchResults ruleMatch, MatchResults condMatch)
|
||||||
{
|
{
|
||||||
return ruleMatch?.Groups[Index]?.Value;
|
return ruleMatch?.BackReference[Index]?.Value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,10 +1,9 @@
|
||||||
// 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.Text.RegularExpressions;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.UrlRewrite.PatternSegments
|
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite.PatternSegments
|
||||||
{
|
{
|
||||||
public class ToLowerSegment : PatternSegment
|
public class ToLowerSegment : PatternSegment
|
||||||
{
|
{
|
||||||
|
|
@ -15,7 +14,7 @@ namespace Microsoft.AspNetCore.Rewrite.UrlRewrite.PatternSegments
|
||||||
Pattern = pattern;
|
Pattern = pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Evaluate(HttpContext context, Match ruleMatch, Match condMatch)
|
public override string Evaluate(HttpContext context, MatchResults ruleMatch, MatchResults condMatch)
|
||||||
{
|
{
|
||||||
var pattern = Pattern.Evaluate(context, ruleMatch, condMatch);
|
var pattern = Pattern.Evaluate(context, ruleMatch, condMatch);
|
||||||
return pattern.ToLowerInvariant();
|
return pattern.ToLowerInvariant();
|
||||||
|
|
@ -2,10 +2,9 @@
|
||||||
// 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.Text.Encodings.Web;
|
using System.Text.Encodings.Web;
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.UrlRewrite.PatternSegments
|
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite.PatternSegments
|
||||||
{
|
{
|
||||||
public class UrlEncodeSegment : PatternSegment
|
public class UrlEncodeSegment : PatternSegment
|
||||||
{
|
{
|
||||||
|
|
@ -16,7 +15,7 @@ namespace Microsoft.AspNetCore.Rewrite.UrlRewrite.PatternSegments
|
||||||
Pattern = pattern;
|
Pattern = pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Evaluate(HttpContext context, Match ruleMatch, Match condMatch)
|
public override string Evaluate(HttpContext context, MatchResults ruleMatch, MatchResults condMatch)
|
||||||
{
|
{
|
||||||
var pattern = Pattern.Evaluate(context, ruleMatch, condMatch);
|
var pattern = Pattern.Evaluate(context, ruleMatch, condMatch);
|
||||||
return UrlEncoder.Default.Encode(pattern);
|
return UrlEncoder.Default.Encode(pattern);
|
||||||
|
|
@ -1,16 +1,15 @@
|
||||||
// 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.Text.RegularExpressions;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.UrlRewrite.PatternSegments
|
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite.PatternSegments
|
||||||
{
|
{
|
||||||
public class UrlSegment : PatternSegment
|
public class UrlSegment : PatternSegment
|
||||||
{
|
{
|
||||||
public override string Evaluate(HttpContext context, Match ruleMatch, Match condMatch)
|
public override string Evaluate(HttpContext context, MatchResults ruleMatch, MatchResults condMatch)
|
||||||
{
|
{
|
||||||
return context.Request.Path.ToString();
|
return context.Request.Path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// 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.
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.UrlRewrite
|
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite
|
||||||
{
|
{
|
||||||
public enum PatternSyntax
|
public enum PatternSyntax
|
||||||
{
|
{
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// 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.
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.UrlRewrite
|
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite
|
||||||
{
|
{
|
||||||
public enum RedirectType
|
public enum RedirectType
|
||||||
{
|
{
|
||||||
|
|
@ -1,11 +1,10 @@
|
||||||
// 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.
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.UrlRewrite
|
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite
|
||||||
{
|
{
|
||||||
public static class RewriteTags
|
public static class RewriteTags
|
||||||
{
|
{
|
||||||
// TODO More strings to be added later once further implementations are added.
|
|
||||||
public const string Rewrite = "rewrite";
|
public const string Rewrite = "rewrite";
|
||||||
public const string GlobalRules = "globalRules";
|
public const string GlobalRules = "globalRules";
|
||||||
public const string Rules = "rules";
|
public const string Rules = "rules";
|
||||||
|
|
@ -27,7 +26,7 @@ namespace Microsoft.AspNetCore.Rewrite.UrlRewrite
|
||||||
public const string Input = "input";
|
public const string Input = "input";
|
||||||
public const string Pattern = "pattern";
|
public const string Pattern = "pattern";
|
||||||
public const string Type = "type";
|
public const string Type = "type";
|
||||||
public const string AppendQuery = "appendQuery";
|
public const string AppendQuery = "appendQueryString";
|
||||||
public const string LogRewrittenUrl = "logRewrittenUrl";
|
public const string LogRewrittenUrl = "logRewrittenUrl";
|
||||||
public const string RedirectType = "redirectType";
|
public const string RedirectType = "redirectType";
|
||||||
}
|
}
|
||||||
|
|
@ -2,16 +2,13 @@
|
||||||
// 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.Globalization;
|
using Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite.PatternSegments;
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.AspNetCore.Rewrite.UrlRewrite.PatternSegments;
|
|
||||||
using Microsoft.Net.Http.Headers;
|
using Microsoft.Net.Http.Headers;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.UrlRewrite
|
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite
|
||||||
{
|
{
|
||||||
public static class ServerVariables
|
public static class ServerVariables
|
||||||
{
|
{
|
||||||
public static PatternSegment FindServerVariable(string serverVariable)
|
public static PatternSegment FindServerVariable(string serverVariable)
|
||||||
{
|
{
|
||||||
switch(serverVariable)
|
switch(serverVariable)
|
||||||
|
|
@ -53,6 +50,8 @@ namespace Microsoft.AspNetCore.Rewrite.UrlRewrite
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
case "REMOTE_PORT":
|
case "REMOTE_PORT":
|
||||||
return new RemotePortSegment();
|
return new RemotePortSegment();
|
||||||
|
case "REQUEST_FILENAME":
|
||||||
|
return new RequestFileNameSegment();
|
||||||
default:
|
default:
|
||||||
throw new FormatException("Unrecognized server variable.");
|
throw new FormatException("Unrecognized server variable.");
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite
|
||||||
|
{
|
||||||
|
public abstract class UrlAction
|
||||||
|
{
|
||||||
|
public Pattern Url { get; set; }
|
||||||
|
|
||||||
|
public abstract RuleResult ApplyAction(HttpContext context, MatchResults ruleMatch, MatchResults condMatch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Rewrite.Internal;
|
||||||
|
using Microsoft.Net.Http.Headers;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite.UrlActions
|
||||||
|
{
|
||||||
|
public class RedirectAction : UrlAction
|
||||||
|
{
|
||||||
|
public int StatusCode { get; }
|
||||||
|
public RedirectAction(int statusCode, Pattern pattern)
|
||||||
|
{
|
||||||
|
StatusCode = statusCode;
|
||||||
|
Url = pattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override RuleResult ApplyAction(HttpContext context, MatchResults ruleMatch, MatchResults condMatch)
|
||||||
|
{
|
||||||
|
|
||||||
|
var pattern = Url.Evaluate(context, ruleMatch, condMatch);
|
||||||
|
context.Response.StatusCode = StatusCode;
|
||||||
|
|
||||||
|
// url can either contain the full url or the path and query
|
||||||
|
// always add to location header.
|
||||||
|
// TODO check for false positives
|
||||||
|
var split = pattern.IndexOf('?');
|
||||||
|
if (split >= 0)
|
||||||
|
{
|
||||||
|
var query = context.Request.QueryString.Add(new QueryString(pattern.Substring(split)));
|
||||||
|
// not using the response.redirect here because status codes may be 301, 302, 307, 308
|
||||||
|
context.Response.Headers[HeaderNames.Location] = pattern.Substring(0, split) + query;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
context.Response.Headers[HeaderNames.Location] = pattern;
|
||||||
|
}
|
||||||
|
return RuleResult.ResponseComplete;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Rewrite.Internal;
|
||||||
|
using Microsoft.Net.Http.Headers;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite.UrlActions
|
||||||
|
{
|
||||||
|
public class RedirectClearQueryAction : UrlAction
|
||||||
|
{
|
||||||
|
public int StatusCode { get; }
|
||||||
|
public RedirectClearQueryAction(int statusCode, Pattern pattern)
|
||||||
|
{
|
||||||
|
StatusCode = statusCode;
|
||||||
|
Url = pattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override RuleResult ApplyAction(HttpContext context, MatchResults ruleMatch, MatchResults condMatch)
|
||||||
|
{
|
||||||
|
var pattern = Url.Evaluate(context, ruleMatch, condMatch);
|
||||||
|
context.Response.StatusCode = StatusCode;
|
||||||
|
|
||||||
|
// we are clearing the query, so just put the pattern in the location header
|
||||||
|
context.Response.Headers[HeaderNames.Location] = pattern;
|
||||||
|
return RuleResult.ResponseComplete;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Http.Extensions;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite.UrlActions
|
||||||
|
{
|
||||||
|
public class RewriteAction : UrlAction
|
||||||
|
{
|
||||||
|
public RuleTerminiation Result { get; }
|
||||||
|
public bool ClearQuery { get; }
|
||||||
|
|
||||||
|
public RewriteAction(RuleTerminiation result, Pattern pattern, bool clearQuery)
|
||||||
|
{
|
||||||
|
Result = result;
|
||||||
|
Url = pattern;
|
||||||
|
ClearQuery = clearQuery;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override RuleResult ApplyAction(HttpContext context, MatchResults ruleMatch, MatchResults condMatch)
|
||||||
|
{
|
||||||
|
var pattern = Url.Evaluate(context, ruleMatch, condMatch);
|
||||||
|
|
||||||
|
if (ClearQuery)
|
||||||
|
{
|
||||||
|
context.Request.QueryString = new QueryString();
|
||||||
|
}
|
||||||
|
// TODO PERF, substrings, object creation, etc.
|
||||||
|
if (pattern.IndexOf("://") >= 0)
|
||||||
|
{
|
||||||
|
string scheme = null;
|
||||||
|
var host = new HostString();
|
||||||
|
var path = new PathString();
|
||||||
|
var query = new QueryString();
|
||||||
|
var fragment = new FragmentString();
|
||||||
|
UriHelper.FromAbsolute(pattern, out scheme, out host, out path, out query, out fragment);
|
||||||
|
|
||||||
|
context.Request.Scheme = scheme;
|
||||||
|
context.Request.Host = host;
|
||||||
|
context.Request.Path = path;
|
||||||
|
context.Request.QueryString = query.Add(context.Request.QueryString);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var split = pattern.IndexOf('?');
|
||||||
|
if (split >= 0)
|
||||||
|
{
|
||||||
|
context.Request.Path = new PathString("/" + pattern.Substring(0, split));
|
||||||
|
context.Request.QueryString = context.Request.QueryString.Add(new QueryString(pattern.Substring(split)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
context.Request.Path = new PathString("/" + pattern);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new RuleResult { Result = Result };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Rewrite.Internal;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite.UrlActions
|
||||||
|
{
|
||||||
|
public class VoidAction : UrlAction
|
||||||
|
{
|
||||||
|
// Explicitly say that nothing happens
|
||||||
|
public override RuleResult ApplyAction(HttpContext context, MatchResults ruleMatch, MatchResults condMatch)
|
||||||
|
{
|
||||||
|
return RuleResult.Continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite
|
||||||
|
{
|
||||||
|
public abstract class UrlMatch
|
||||||
|
{
|
||||||
|
public bool Negate { get; set; }
|
||||||
|
public abstract MatchResults Evaluate(string input, RewriteContext context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite.UrlMatches
|
||||||
|
{
|
||||||
|
public class ExactMatch : UrlMatch
|
||||||
|
{
|
||||||
|
public bool IgnoreCase { get; }
|
||||||
|
public string StringMatch { get; }
|
||||||
|
|
||||||
|
public ExactMatch(bool ignoreCase, string input, bool negate)
|
||||||
|
{
|
||||||
|
IgnoreCase = ignoreCase;
|
||||||
|
StringMatch = input;
|
||||||
|
Negate = negate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override MatchResults Evaluate(string pattern, RewriteContext context)
|
||||||
|
{
|
||||||
|
var pathMatch = string.Compare(pattern, StringMatch, IgnoreCase);
|
||||||
|
return new MatchResults { Success = ((pathMatch == 0) != Negate) };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite.UrlMatches
|
||||||
|
{
|
||||||
|
public class IsDirectoryMatch : UrlMatch
|
||||||
|
{
|
||||||
|
public IsDirectoryMatch( bool negate)
|
||||||
|
{
|
||||||
|
Negate = negate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override MatchResults Evaluate(string pattern, RewriteContext context)
|
||||||
|
{
|
||||||
|
var res = context.FileProvider.GetFileInfo(pattern).IsDirectory;
|
||||||
|
return new MatchResults { Success = (res != Negate) };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite.UrlMatches
|
||||||
|
{
|
||||||
|
public class IsFileMatch : UrlMatch
|
||||||
|
{
|
||||||
|
public IsFileMatch(bool negate)
|
||||||
|
{
|
||||||
|
Negate = negate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override MatchResults Evaluate(string pattern, RewriteContext context)
|
||||||
|
{
|
||||||
|
var res = context.FileProvider.GetFileInfo(pattern).Exists;
|
||||||
|
return new MatchResults { Success = (res != Negate) };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite.UrlMatches
|
||||||
|
{
|
||||||
|
public class RegexMatch : UrlMatch
|
||||||
|
{
|
||||||
|
private static readonly TimeSpan RegexTimeout = TimeSpan.FromMilliseconds(1);
|
||||||
|
|
||||||
|
public Regex Match { get; }
|
||||||
|
|
||||||
|
public RegexMatch(Regex match, bool negate)
|
||||||
|
{
|
||||||
|
Match = match;
|
||||||
|
Negate = negate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override MatchResults Evaluate(string pattern, RewriteContext context)
|
||||||
|
{
|
||||||
|
var res = Match.Match(pattern);
|
||||||
|
return new MatchResults { BackReference = res.Groups, Success = (res.Success != Negate)};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,316 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
using Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite.UrlActions;
|
||||||
|
using Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite.UrlMatches;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite
|
||||||
|
{
|
||||||
|
public static class UrlRewriteFileParser
|
||||||
|
{
|
||||||
|
private static readonly TimeSpan RegexTimeout = TimeSpan.FromMilliseconds(1);
|
||||||
|
|
||||||
|
public static List<UrlRewriteRule> Parse(TextReader reader)
|
||||||
|
{
|
||||||
|
var temp = XDocument.Load(reader);
|
||||||
|
var xmlRoot = temp.Descendants(RewriteTags.Rewrite).FirstOrDefault();
|
||||||
|
|
||||||
|
if (xmlRoot != null)
|
||||||
|
{
|
||||||
|
var result = new List<UrlRewriteRule>();
|
||||||
|
// TODO Global rules are currently not treated differently than normal rules, fix.
|
||||||
|
// See: https://github.com/aspnet/BasicMiddleware/issues/59
|
||||||
|
ParseRules(xmlRoot.Descendants(RewriteTags.GlobalRules).FirstOrDefault(), result, isGlobalRule: true);
|
||||||
|
ParseRules(xmlRoot.Descendants(RewriteTags.Rules).FirstOrDefault(), result, isGlobalRule: false);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ParseRules(XElement rules, List<UrlRewriteRule> result, bool isGlobalRule)
|
||||||
|
{
|
||||||
|
if (rules == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var rule in rules.Elements(RewriteTags.Rule))
|
||||||
|
{
|
||||||
|
var res = new UrlRewriteRule();
|
||||||
|
SetRuleAttributes(rule, res);
|
||||||
|
CreateUrlAction(rule.Element(RewriteTags.Action), res, isGlobalRule);
|
||||||
|
if (res.Enabled)
|
||||||
|
{
|
||||||
|
result.Add(res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SetRuleAttributes(XElement rule, UrlRewriteRule res)
|
||||||
|
{
|
||||||
|
|
||||||
|
res.Name = rule.Attribute(RewriteTags.Name)?.Value;
|
||||||
|
|
||||||
|
bool enabled;
|
||||||
|
if (bool.TryParse(rule.Attribute(RewriteTags.Enabled)?.Value, out enabled))
|
||||||
|
{
|
||||||
|
res.Enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
PatternSyntax patternSyntax;
|
||||||
|
if (Enum.TryParse(rule.Attribute(RewriteTags.PatternSyntax)?.Value, out patternSyntax))
|
||||||
|
{
|
||||||
|
res.PatternSyntax = patternSyntax;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool stopProcessing;
|
||||||
|
if (bool.TryParse(rule.Attribute(RewriteTags.StopProcessing)?.Value, out stopProcessing))
|
||||||
|
{
|
||||||
|
res.StopProcessing = stopProcessing;
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateMatch(rule.Element(RewriteTags.Match), res);
|
||||||
|
CreateConditions(rule.Element(RewriteTags.Conditions), res);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CreateMatch(XElement match, UrlRewriteRule res)
|
||||||
|
{
|
||||||
|
if (match == null)
|
||||||
|
{
|
||||||
|
throw new FormatException("Rules must have an associated match.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var matchRes = new ParsedUrlMatch();
|
||||||
|
|
||||||
|
bool parBool;
|
||||||
|
if (bool.TryParse(match.Attribute(RewriteTags.IgnoreCase)?.Value, out parBool))
|
||||||
|
{
|
||||||
|
matchRes.IgnoreCase = parBool;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bool.TryParse(match.Attribute(RewriteTags.Negate)?.Value, out parBool))
|
||||||
|
{
|
||||||
|
matchRes.Negate = parBool;
|
||||||
|
}
|
||||||
|
|
||||||
|
var parsedInputString = match.Attribute(RewriteTags.Url)?.Value;
|
||||||
|
|
||||||
|
switch (res.PatternSyntax)
|
||||||
|
{
|
||||||
|
case PatternSyntax.ECMAScript:
|
||||||
|
{
|
||||||
|
if (matchRes.IgnoreCase)
|
||||||
|
{
|
||||||
|
var regex = new Regex(parsedInputString, RegexOptions.Compiled | RegexOptions.IgnoreCase, RegexTimeout);
|
||||||
|
res.InitialMatch = new RegexMatch(regex, matchRes.Negate);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var regex = new Regex(parsedInputString, RegexOptions.Compiled, RegexTimeout);
|
||||||
|
res.InitialMatch = new RegexMatch(regex, matchRes.Negate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PatternSyntax.WildCard:
|
||||||
|
throw new NotImplementedException("Wildcard syntax is not supported.");
|
||||||
|
case PatternSyntax.ExactMatch:
|
||||||
|
res.InitialMatch = new ExactMatch(matchRes.IgnoreCase, parsedInputString, matchRes.Negate);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static void CreateConditions(XElement conditions, UrlRewriteRule res)
|
||||||
|
{
|
||||||
|
// This is to avoid nullptr exception on referencing conditions.
|
||||||
|
res.Conditions = new Conditions();
|
||||||
|
if (conditions == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogicalGrouping grouping;
|
||||||
|
if (Enum.TryParse(conditions.Attribute(RewriteTags.MatchType)?.Value, out grouping))
|
||||||
|
{
|
||||||
|
res.Conditions.MatchType = grouping;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool parBool;
|
||||||
|
if (bool.TryParse(conditions.Attribute(RewriteTags.TrackingAllCaptures)?.Value, out parBool))
|
||||||
|
{
|
||||||
|
res.Conditions.TrackingAllCaptures = parBool;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var cond in conditions.Elements(RewriteTags.Add))
|
||||||
|
{
|
||||||
|
CreateCondition(cond, res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CreateCondition(XElement condition, UrlRewriteRule res)
|
||||||
|
{
|
||||||
|
|
||||||
|
var parsedCondRes = new ParsedCondition();
|
||||||
|
|
||||||
|
bool parBool;
|
||||||
|
if (bool.TryParse(condition.Attribute(RewriteTags.IgnoreCase)?.Value, out parBool))
|
||||||
|
{
|
||||||
|
parsedCondRes.IgnoreCase = parBool;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bool.TryParse(condition.Attribute(RewriteTags.Negate)?.Value, out parBool))
|
||||||
|
{
|
||||||
|
parsedCondRes.Negate = parBool;
|
||||||
|
}
|
||||||
|
|
||||||
|
MatchType matchType;
|
||||||
|
if (Enum.TryParse(condition.Attribute(RewriteTags.MatchType)?.Value, out matchType))
|
||||||
|
{
|
||||||
|
parsedCondRes.MatchType = matchType;
|
||||||
|
}
|
||||||
|
|
||||||
|
var parsedString = condition.Attribute(RewriteTags.Input)?.Value;
|
||||||
|
if (parsedString == null)
|
||||||
|
{
|
||||||
|
throw new FormatException("Null input for condition");
|
||||||
|
}
|
||||||
|
|
||||||
|
var input = InputParser.ParseInputString(parsedString);
|
||||||
|
|
||||||
|
switch (res.PatternSyntax)
|
||||||
|
{
|
||||||
|
case PatternSyntax.ECMAScript:
|
||||||
|
{
|
||||||
|
switch (parsedCondRes.MatchType)
|
||||||
|
{
|
||||||
|
case MatchType.Pattern:
|
||||||
|
{
|
||||||
|
parsedString = condition.Attribute(RewriteTags.Pattern)?.Value;
|
||||||
|
if (parsedString == null)
|
||||||
|
{
|
||||||
|
throw new FormatException("Pattern match does not have an associated pattern attribute in condition.");
|
||||||
|
}
|
||||||
|
Regex regex = null;
|
||||||
|
|
||||||
|
if (parsedCondRes.IgnoreCase)
|
||||||
|
{
|
||||||
|
regex = new Regex(parsedString, RegexOptions.Compiled | RegexOptions.IgnoreCase, RegexTimeout);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
regex = new Regex(parsedString, RegexOptions.Compiled, RegexTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
res.Conditions.ConditionList.Add(new Condition { Input = input, Match = new RegexMatch(regex, parsedCondRes.Negate) });
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MatchType.IsDirectory:
|
||||||
|
{
|
||||||
|
res.Conditions.ConditionList.Add(new Condition { Input = input, Match = new IsDirectoryMatch(parsedCondRes.Negate) });
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MatchType.IsFile:
|
||||||
|
{
|
||||||
|
res.Conditions.ConditionList.Add(new Condition { Input = input, Match = new IsFileMatch(parsedCondRes.Negate) });
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new FormatException("Unrecognized matchType.");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PatternSyntax.WildCard:
|
||||||
|
throw new NotImplementedException("Wildcard syntax is not supported.");
|
||||||
|
case PatternSyntax.ExactMatch:
|
||||||
|
parsedString = condition.Attribute(RewriteTags.Pattern)?.Value;
|
||||||
|
if (parsedString == null)
|
||||||
|
{
|
||||||
|
throw new FormatException("Pattern match does not have an associated pattern attribute in condition.");
|
||||||
|
}
|
||||||
|
res.Conditions.ConditionList.Add(new Condition { Input = input, Match = new ExactMatch(parsedCondRes.IgnoreCase, parsedString, parsedCondRes.Negate) });
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new FormatException("Unrecognized pattern syntax.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CreateUrlAction(XElement urlAction, UrlRewriteRule res, bool globalRule)
|
||||||
|
{
|
||||||
|
if (urlAction == null)
|
||||||
|
{
|
||||||
|
throw new FormatException("Action is a required element of a rule.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var actionRes = new ParsedUrlAction();
|
||||||
|
|
||||||
|
ActionType actionType;
|
||||||
|
if (Enum.TryParse(urlAction.Attribute(RewriteTags.Type)?.Value, out actionType))
|
||||||
|
{
|
||||||
|
actionRes.Type = actionType;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool parseBool;
|
||||||
|
if (bool.TryParse(urlAction.Attribute(RewriteTags.AppendQuery)?.Value, out parseBool))
|
||||||
|
{
|
||||||
|
actionRes.AppendQueryString = parseBool;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bool.TryParse(urlAction.Attribute(RewriteTags.LogRewrittenUrl)?.Value, out parseBool))
|
||||||
|
{
|
||||||
|
actionRes.LogRewrittenUrl = parseBool;
|
||||||
|
}
|
||||||
|
|
||||||
|
RedirectType redirectType;
|
||||||
|
if (Enum.TryParse(urlAction.Attribute(RewriteTags.RedirectType)?.Value, out redirectType))
|
||||||
|
{
|
||||||
|
actionRes.RedirectType = redirectType;
|
||||||
|
}
|
||||||
|
|
||||||
|
actionRes.Url = InputParser.ParseInputString(urlAction.Attribute(RewriteTags.Url)?.Value);
|
||||||
|
|
||||||
|
CreateUrlActionFromParsedAction(actionRes, globalRule, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void CreateUrlActionFromParsedAction(ParsedUrlAction actionRes, bool globalRule, UrlRewriteRule res)
|
||||||
|
{
|
||||||
|
switch (actionRes.Type)
|
||||||
|
{
|
||||||
|
case ActionType.None:
|
||||||
|
res.Action = new VoidAction();
|
||||||
|
break;
|
||||||
|
case ActionType.Rewrite:
|
||||||
|
if (actionRes.AppendQueryString)
|
||||||
|
{
|
||||||
|
res.Action = new RewriteAction(res.StopProcessing ? RuleTerminiation.StopRules : RuleTerminiation.Continue, actionRes.Url, clearQuery: false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
res.Action = new RewriteAction(res.StopProcessing ? RuleTerminiation.StopRules : RuleTerminiation.Continue, actionRes.Url, clearQuery: true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ActionType.Redirect:
|
||||||
|
if (actionRes.AppendQueryString)
|
||||||
|
{
|
||||||
|
res.Action = new RedirectAction((int)actionRes.RedirectType, actionRes.Url);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
res.Action = new RedirectClearQueryAction((int)actionRes.RedirectType, actionRes.Url);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ActionType.AbortRequest:
|
||||||
|
throw new FormatException("Abort requests are not supported.");
|
||||||
|
case ActionType.CustomResponse:
|
||||||
|
// TODO
|
||||||
|
throw new FormatException("Custom Responses are not supported");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite
|
||||||
|
{
|
||||||
|
public class UrlRewriteRule : Rule
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public bool Enabled { get; set; } = true;
|
||||||
|
public PatternSyntax PatternSyntax { get; set; }
|
||||||
|
public bool StopProcessing { get; set; }
|
||||||
|
public UrlMatch InitialMatch { get; set; }
|
||||||
|
public Conditions Conditions { get; set; }
|
||||||
|
public UrlAction Action { get; set; }
|
||||||
|
|
||||||
|
public override RuleResult ApplyRule(RewriteContext context)
|
||||||
|
{
|
||||||
|
if (!Enabled)
|
||||||
|
{
|
||||||
|
return RuleResult.Continue;
|
||||||
|
}
|
||||||
|
// Due to the path string always having a leading slash,
|
||||||
|
// remove it from the path before regex comparison
|
||||||
|
var initMatchRes = InitialMatch.Evaluate(context.HttpContext.Request.Path.ToString().Substring(1), context);
|
||||||
|
|
||||||
|
if (!initMatchRes.Success)
|
||||||
|
{
|
||||||
|
return RuleResult.Continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var condMatchRes = Conditions.Evaluate(context, initMatchRes);
|
||||||
|
if (!condMatchRes.Success)
|
||||||
|
{
|
||||||
|
return RuleResult.Continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// at this point we know the rule passed, evaluate the replacement.
|
||||||
|
return Action.ApplyAction(context.HttpContext, initMatchRes, condMatchRes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
|
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||||
<PropertyGroup Label="Globals">
|
<PropertyGroup Label="Globals">
|
||||||
<ProjectGuid>0e7ca1a7-1dc3-4ce6-b9c7-1688fe1410f1</ProjectGuid>
|
<ProjectGuid>0e7ca1a7-1dc3-4ce6-b9c7-1688fe1410f1</ProjectGuid>
|
||||||
<RootNamespace>Microsoft.AspNetCore.Rewrite</RootNamespace>
|
<RootNamespace>Microsoft.AspNetCore.Rewrite</RootNamespace>
|
||||||
|
|
@ -17,5 +17,5 @@
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<SchemaVersion>2.0</SchemaVersion>
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Targets" Condition="'$(VSToolsPath)' != ''" />
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Rewrite.ModRewrite;
|
using Microsoft.AspNetCore.Rewrite.Internal.ModRewrite;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite
|
namespace Microsoft.AspNetCore.Rewrite
|
||||||
{
|
{
|
||||||
|
|
@ -16,16 +16,16 @@ namespace Microsoft.AspNetCore.Rewrite
|
||||||
/// <param name="options">The UrlRewrite options.</param>
|
/// <param name="options">The UrlRewrite options.</param>
|
||||||
/// <param name="hostingEnv"></param>
|
/// <param name="hostingEnv"></param>
|
||||||
/// <param name="filePath">The path to the file containing mod_rewrite rules.</param>
|
/// <param name="filePath">The path to the file containing mod_rewrite rules.</param>
|
||||||
public static UrlRewriteOptions ImportFromModRewrite(this UrlRewriteOptions options, IHostingEnvironment hostingEnv, string filePath)
|
public static RewriteOptions ImportFromModRewrite(this RewriteOptions options, IHostingEnvironment hostingEnv, string filePath)
|
||||||
{
|
{
|
||||||
if (options == null)
|
if (options == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("UrlRewriteOptions is null");
|
throw new ArgumentNullException(nameof(options));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hostingEnv == null)
|
if (hostingEnv == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("HostingEnvironment is null");
|
throw new ArgumentNullException(nameof(hostingEnv));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(filePath))
|
if (string.IsNullOrEmpty(filePath))
|
||||||
|
|
@ -46,36 +46,39 @@ namespace Microsoft.AspNetCore.Rewrite
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="options">The UrlRewrite options.</param>
|
/// <param name="options">The UrlRewrite options.</param>
|
||||||
/// <param name="reader">Text reader containing a stream of mod_rewrite rules.</param>
|
/// <param name="reader">Text reader containing a stream of mod_rewrite rules.</param>
|
||||||
public static UrlRewriteOptions ImportFromModRewrite(this UrlRewriteOptions options, TextReader reader)
|
public static RewriteOptions ImportFromModRewrite(this RewriteOptions options, TextReader reader)
|
||||||
{
|
{
|
||||||
|
if (options == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(options));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reader == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(reader));
|
||||||
|
}
|
||||||
options.Rules.AddRange(FileParser.Parse(reader));
|
options.Rules.AddRange(FileParser.Parse(reader));
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a mod_rewrite rule to the current rules.
|
/// Adds a mod_rewrite rule to the current rules.
|
||||||
/// Additional properties (conditions, flags) for the rule can be added through the action.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="options">The UrlRewrite options.</param>
|
/// <param name="options">The UrlRewrite options.</param>
|
||||||
/// <param name="rule">The literal string of a mod_rewrite rule:
|
/// <param name="rule">The literal string of a mod_rewrite rule:
|
||||||
/// "RewriteRule Pattern Substitution [Flags]"</param>
|
/// "RewriteRule Pattern Substitution [Flags]"</param>
|
||||||
/// <param name="action">Action to perform on the <see cref="RuleBuilder"/> </param>
|
public static RewriteOptions AddModRewriteRule(this RewriteOptions options, string rule)
|
||||||
public static UrlRewriteOptions AddModRewriteRule(this UrlRewriteOptions options, string rule, Action<RuleBuilder> action)
|
|
||||||
{
|
{
|
||||||
var builder = new RuleBuilder(rule);
|
if (options == null)
|
||||||
action(builder);
|
{
|
||||||
options.Rules.Add(builder.Build());
|
throw new ArgumentNullException(nameof(options));
|
||||||
return options;
|
}
|
||||||
}
|
|
||||||
|
if (rule == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(rule));
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds a mod_rewrite rule to the current rules.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="options">The UrlRewrite options.</param>
|
|
||||||
/// <param name="rule">The literal string of a mod_rewrite rule:
|
|
||||||
/// "RewriteRule Pattern Substitution [Flags]"</param>
|
|
||||||
public static UrlRewriteOptions AddModRewriteRule(this UrlRewriteOptions options, string rule)
|
|
||||||
{
|
|
||||||
var builder = new RuleBuilder(rule);
|
var builder = new RuleBuilder(rule);
|
||||||
options.Rules.Add(builder.Build());
|
options.Rules.Add(builder.Build());
|
||||||
return options;
|
return options;
|
||||||
|
|
@ -9,7 +9,7 @@ namespace Microsoft.AspNetCore.Rewrite
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The UrlRewrite Context contains the HttpContext of the request and the file provider to check conditions.
|
/// The UrlRewrite Context contains the HttpContext of the request and the file provider to check conditions.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class UrlRewriteContext
|
public class RewriteContext
|
||||||
{
|
{
|
||||||
public HttpContext HttpContext { get; set; }
|
public HttpContext HttpContext { get; set; }
|
||||||
public IFileProvider FileProvider { get; set; }
|
public IFileProvider FileProvider { get; set; }
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using Microsoft.AspNetCore.Rewrite;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Builder
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Extension methods for the <see cref="RewriteMiddleware"/>
|
||||||
|
/// </summary>
|
||||||
|
public static class RewriteExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if a given Url matches rules and conditions, and modifies the HttpContext on match.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="app"></param>
|
||||||
|
/// <param name="options">Options for urlrewrite.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static IApplicationBuilder UseRewriter(this IApplicationBuilder app, RewriteOptions options)
|
||||||
|
{
|
||||||
|
if (app == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(app));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(options));
|
||||||
|
}
|
||||||
|
// put middleware in pipeline
|
||||||
|
return app.UseMiddleware<RewriteMiddleware>(options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,7 +5,7 @@ using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Rewrite.RuleAbstraction;
|
using Microsoft.AspNetCore.Rewrite.Internal;
|
||||||
using Microsoft.Extensions.FileProviders;
|
using Microsoft.Extensions.FileProviders;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite
|
namespace Microsoft.AspNetCore.Rewrite
|
||||||
|
|
@ -13,19 +13,19 @@ namespace Microsoft.AspNetCore.Rewrite
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a middleware that rewrites urls imported from mod_rewrite, UrlRewrite, and code.
|
/// Represents a middleware that rewrites urls imported from mod_rewrite, UrlRewrite, and code.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class UrlRewriteMiddleware
|
public class RewriteMiddleware
|
||||||
{
|
{
|
||||||
private readonly RequestDelegate _next;
|
private readonly RequestDelegate _next;
|
||||||
private readonly UrlRewriteOptions _options;
|
private readonly RewriteOptions _options;
|
||||||
private readonly IFileProvider _fileProvider;
|
private readonly IFileProvider _fileProvider;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new instance of <see cref="UrlRewriteMiddleware"/>
|
/// Creates a new instance of <see cref="RewriteMiddleware"/>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="next">The delegate representing the next middleware in the request pipeline.</param>
|
/// <param name="next">The delegate representing the next middleware in the request pipeline.</param>
|
||||||
/// <param name="hostingEnv">The Hosting Environment.</param>
|
/// <param name="hostingEnv">The Hosting Environment.</param>
|
||||||
/// <param name="options">The middleware options, containing the rules to apply.</param>
|
/// <param name="options">The middleware options, containing the rules to apply.</param>
|
||||||
public UrlRewriteMiddleware(RequestDelegate next, IHostingEnvironment hostingEnv, UrlRewriteOptions options)
|
public RewriteMiddleware(RequestDelegate next, IHostingEnvironment hostingEnv, RewriteOptions options)
|
||||||
{
|
{
|
||||||
if (next == null)
|
if (next == null)
|
||||||
{
|
{
|
||||||
|
|
@ -53,7 +53,7 @@ namespace Microsoft.AspNetCore.Rewrite
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(context));
|
throw new ArgumentNullException(nameof(context));
|
||||||
}
|
}
|
||||||
var urlContext = new UrlRewriteContext { HttpContext = context, FileProvider = _fileProvider };
|
var urlContext = new RewriteContext { HttpContext = context, FileProvider = _fileProvider };
|
||||||
foreach (var rule in _options.Rules)
|
foreach (var rule in _options.Rules)
|
||||||
{
|
{
|
||||||
// Apply the rule
|
// Apply the rule
|
||||||
|
|
@ -2,15 +2,15 @@
|
||||||
// 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.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Microsoft.AspNetCore.Rewrite.RuleAbstraction;
|
using Microsoft.AspNetCore.Rewrite.Internal;
|
||||||
using Microsoft.Extensions.FileProviders;
|
using Microsoft.Extensions.FileProviders;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite
|
namespace Microsoft.AspNetCore.Rewrite
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Options for the <see cref="UrlRewriteMiddleware"/>
|
/// Options for the <see cref="RewriteMiddleware"/>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class UrlRewriteOptions
|
public class RewriteOptions
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The ordered list of rules to apply to the context.
|
/// The ordered list of rules to apply to the context.
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.RuleAbstraction
|
|
||||||
{
|
|
||||||
public enum RuleTerminiation
|
|
||||||
{
|
|
||||||
Continue,
|
|
||||||
ResponseComplete,
|
|
||||||
StopRules
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.UrlRewrite
|
|
||||||
{
|
|
||||||
public class Conditions
|
|
||||||
{
|
|
||||||
public List<Condition> ConditionList { get; set; } = new List<Condition>();
|
|
||||||
public LogicalGrouping MatchType { get; set; } // default is MatchAll
|
|
||||||
public bool TrackingAllCaptures { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.UrlRewrite
|
|
||||||
{
|
|
||||||
public class InitialMatch
|
|
||||||
{
|
|
||||||
public Regex Url { get; set; } // TODO must be a non-empty string, throw in check after parsing?
|
|
||||||
public bool IgnoreCase { get; set; } = true;
|
|
||||||
public bool Negate { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,44 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Microsoft.AspNetCore.Rewrite.UrlRewrite;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite
|
|
||||||
{
|
|
||||||
public static class UrlRewriteExtensions
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Imports rules from a mod_rewrite file and adds the rules to current rules.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="options">The UrlRewrite options.</param>
|
|
||||||
/// <param name="hostingEnv"></param>
|
|
||||||
/// <param name="filePath">The path to the file containing urlrewrite rules.</param>
|
|
||||||
public static UrlRewriteOptions ImportFromUrlRewrite(this UrlRewriteOptions options, IHostingEnvironment hostingEnv, string filePath)
|
|
||||||
{
|
|
||||||
if (options == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException("UrlRewriteOptions is null");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hostingEnv == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException("HostingEnvironment is null");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(filePath))
|
|
||||||
{
|
|
||||||
throw new ArgumentException(nameof(filePath));
|
|
||||||
}
|
|
||||||
|
|
||||||
var path = Path.Combine(hostingEnv.ContentRootPath, filePath);
|
|
||||||
using (var stream = File.OpenRead(path))
|
|
||||||
{
|
|
||||||
options.Rules.AddRange(UrlRewriteFileParser.Parse(new StreamReader(stream)));
|
|
||||||
};
|
|
||||||
return options;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,228 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using System.Xml.Linq;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.UrlRewrite
|
|
||||||
{
|
|
||||||
// TODO rename
|
|
||||||
public static class UrlRewriteFileParser
|
|
||||||
{
|
|
||||||
private static readonly TimeSpan RegexTimeout = TimeSpan.FromMilliseconds(1);
|
|
||||||
public static List<UrlRewriteRule> Parse(TextReader reader)
|
|
||||||
{
|
|
||||||
var temp = XDocument.Load(reader);
|
|
||||||
var xmlRoot = temp.Descendants(RewriteTags.Rewrite);
|
|
||||||
var rules = new List<UrlRewriteRule>();
|
|
||||||
|
|
||||||
if (xmlRoot != null)
|
|
||||||
{
|
|
||||||
// there is a valid rewrite block, go through each rule and process
|
|
||||||
GetGlobalRules(xmlRoot.Descendants(RewriteTags.GlobalRules), rules);
|
|
||||||
GetRules(xmlRoot.Descendants(RewriteTags.Rules), rules);
|
|
||||||
}
|
|
||||||
return rules;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void GetGlobalRules(IEnumerable<XElement> globalRules, List<UrlRewriteRule> result)
|
|
||||||
{
|
|
||||||
foreach (var rule in globalRules.Elements(RewriteTags.Rule) ?? Enumerable.Empty<XElement>())
|
|
||||||
{
|
|
||||||
var res = new UrlRewriteRule();
|
|
||||||
SetRuleAttributes(rule, res);
|
|
||||||
// TODO handle full url with global rules - may or may not support
|
|
||||||
res.Action = CreateUrlAction(rule.Element(RewriteTags.Action));
|
|
||||||
result.Add(res);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void GetRules(IEnumerable<XElement> rules, List<UrlRewriteRule> result)
|
|
||||||
{
|
|
||||||
// TODO Better null check?
|
|
||||||
foreach (var rule in rules.Elements(RewriteTags.Rule) ?? Enumerable.Empty<XElement>())
|
|
||||||
{
|
|
||||||
var res = new UrlRewriteRule();
|
|
||||||
SetRuleAttributes(rule, res);
|
|
||||||
res.Action = CreateUrlAction(rule.Element(RewriteTags.Action));
|
|
||||||
result.Add(res);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void SetRuleAttributes(XElement rule, UrlRewriteRule res)
|
|
||||||
{
|
|
||||||
if (rule == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
res.Name = rule.Attribute(RewriteTags.Name)?.Value;
|
|
||||||
|
|
||||||
bool enabled;
|
|
||||||
if (bool.TryParse(rule.Attribute(RewriteTags.Enabled)?.Value, out enabled))
|
|
||||||
{
|
|
||||||
res.Enabled = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
PatternSyntax patternSyntax;
|
|
||||||
if (Enum.TryParse(rule.Attribute(RewriteTags.PatternSyntax)?.Value, out patternSyntax))
|
|
||||||
{
|
|
||||||
res.PatternSyntax = patternSyntax;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool stopProcessing;
|
|
||||||
if (bool.TryParse(rule.Attribute(RewriteTags.StopProcessing)?.Value, out stopProcessing))
|
|
||||||
{
|
|
||||||
res.StopProcessing = stopProcessing;
|
|
||||||
}
|
|
||||||
|
|
||||||
res.Match = CreateMatch(rule.Element(RewriteTags.Match));
|
|
||||||
res.Conditions = CreateConditions(rule.Element(RewriteTags.Conditions));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static InitialMatch CreateMatch(XElement match)
|
|
||||||
{
|
|
||||||
if (match == null)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
var matchRes = new InitialMatch();
|
|
||||||
|
|
||||||
bool parBool;
|
|
||||||
if (bool.TryParse(match.Attribute(RewriteTags.IgnoreCase)?.Value, out parBool))
|
|
||||||
{
|
|
||||||
matchRes.IgnoreCase = parBool;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bool.TryParse(match.Attribute(RewriteTags.Negate)?.Value, out parBool))
|
|
||||||
{
|
|
||||||
matchRes.Negate = parBool;
|
|
||||||
}
|
|
||||||
|
|
||||||
var parsedInputString = match.Attribute(RewriteTags.Url)?.Value;
|
|
||||||
|
|
||||||
if (matchRes.IgnoreCase)
|
|
||||||
{
|
|
||||||
matchRes.Url = new Regex(parsedInputString, RegexOptions.IgnoreCase | RegexOptions.Compiled, RegexTimeout);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
matchRes.Url = new Regex(parsedInputString, RegexOptions.Compiled, RegexTimeout);
|
|
||||||
}
|
|
||||||
return matchRes;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static Conditions CreateConditions(XElement conditions)
|
|
||||||
{
|
|
||||||
var condRes = new Conditions();
|
|
||||||
if (conditions == null)
|
|
||||||
{
|
|
||||||
return condRes; // TODO make sure no null exception on Conditions
|
|
||||||
}
|
|
||||||
|
|
||||||
LogicalGrouping grouping;
|
|
||||||
if (Enum.TryParse(conditions.Attribute(RewriteTags.MatchType)?.Value, out grouping))
|
|
||||||
{
|
|
||||||
condRes.MatchType = grouping;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool parBool;
|
|
||||||
if (bool.TryParse(conditions.Attribute(RewriteTags.TrackingAllCaptures)?.Value, out parBool))
|
|
||||||
{
|
|
||||||
condRes.TrackingAllCaptures = parBool;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var cond in conditions.Elements(RewriteTags.Add))
|
|
||||||
{
|
|
||||||
condRes.ConditionList.Add(CreateCondition(cond));
|
|
||||||
}
|
|
||||||
return condRes;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Condition CreateCondition(XElement condition)
|
|
||||||
{
|
|
||||||
if (condition == null)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
var condRes = new Condition();
|
|
||||||
|
|
||||||
bool parBool;
|
|
||||||
if (bool.TryParse(condition.Attribute(RewriteTags.IgnoreCase)?.Value, out parBool))
|
|
||||||
{
|
|
||||||
condRes.IgnoreCase = parBool;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bool.TryParse(condition.Attribute(RewriteTags.Negate)?.Value, out parBool))
|
|
||||||
{
|
|
||||||
condRes.Negate = parBool;
|
|
||||||
}
|
|
||||||
|
|
||||||
MatchType matchType;
|
|
||||||
if (Enum.TryParse(condition.Attribute(RewriteTags.MatchPattern)?.Value, out matchType))
|
|
||||||
{
|
|
||||||
condRes.MatchType = matchType;
|
|
||||||
}
|
|
||||||
|
|
||||||
var parsedInputString = condition.Attribute(RewriteTags.Input)?.Value;
|
|
||||||
if (parsedInputString != null)
|
|
||||||
{
|
|
||||||
condRes.Input = InputParser.ParseInputString(parsedInputString);
|
|
||||||
}
|
|
||||||
|
|
||||||
parsedInputString = condition.Attribute(RewriteTags.Pattern)?.Value;
|
|
||||||
|
|
||||||
if (condRes.IgnoreCase)
|
|
||||||
{
|
|
||||||
condRes.MatchPattern = new Regex(parsedInputString, RegexOptions.IgnoreCase | RegexOptions.Compiled, RegexTimeout);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
condRes.MatchPattern = new Regex(parsedInputString, RegexOptions.Compiled, RegexTimeout);
|
|
||||||
}
|
|
||||||
return condRes;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static UrlAction CreateUrlAction(XElement urlAction)
|
|
||||||
{
|
|
||||||
if (urlAction == null)
|
|
||||||
{
|
|
||||||
throw new FormatException("Action is a required element of a rule.");
|
|
||||||
}
|
|
||||||
var actionRes = new UrlAction();
|
|
||||||
|
|
||||||
ActionType actionType;
|
|
||||||
if (Enum.TryParse(urlAction.Attribute(RewriteTags.Type)?.Value, out actionType))
|
|
||||||
{
|
|
||||||
actionRes.Type = actionType;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool parseBool;
|
|
||||||
if (bool.TryParse(urlAction.Attribute(RewriteTags.AppendQuery)?.Value, out parseBool))
|
|
||||||
{
|
|
||||||
actionRes.AppendQueryString = parseBool;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bool.TryParse(urlAction.Attribute(RewriteTags.LogRewrittenUrl)?.Value, out parseBool))
|
|
||||||
{
|
|
||||||
actionRes.LogRewrittenUrl = parseBool;
|
|
||||||
}
|
|
||||||
|
|
||||||
RedirectType redirectType;
|
|
||||||
if (Enum.TryParse(urlAction.Attribute(RewriteTags.RedirectType)?.Value, out redirectType))
|
|
||||||
{
|
|
||||||
actionRes.RedirectType = redirectType;
|
|
||||||
}
|
|
||||||
|
|
||||||
actionRes.Url = InputParser.ParseInputString(urlAction.Attribute(RewriteTags.Url)?.Value);
|
|
||||||
return actionRes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using Microsoft.AspNetCore.Rewrite.RuleAbstraction;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite.UrlRewrite
|
|
||||||
{
|
|
||||||
public class UrlRewriteRule : Rule
|
|
||||||
{
|
|
||||||
public string Name { get; set; }
|
|
||||||
public bool Enabled { get; set; } = true;
|
|
||||||
public PatternSyntax PatternSyntax { get; set; }
|
|
||||||
public bool StopProcessing { get; set; }
|
|
||||||
public InitialMatch Match { get; set; }
|
|
||||||
public Conditions Conditions { get; set; }
|
|
||||||
public UrlAction Action { get; set; }
|
|
||||||
|
|
||||||
public override RuleResult ApplyRule(UrlRewriteContext context)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -2,34 +2,67 @@
|
||||||
// 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;
|
using System.IO;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Builder
|
namespace Microsoft.AspNetCore.Rewrite
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Extension methods for the <see cref="UrlRewriteMiddleware"/>
|
|
||||||
/// </summary>
|
|
||||||
public static class UrlRewriteExtensions
|
public static class UrlRewriteExtensions
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks if a given Url matches rules and conditions, and modifies the HttpContext on match.
|
/// Imports rules from a mod_rewrite file and adds the rules to current rules.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="app"></param>
|
/// <param name="options">The UrlRewrite options.</param>
|
||||||
/// <param name="options">Options for urlrewrite.</param>
|
/// <param name="hostingEnv"></param>
|
||||||
/// <returns></returns>
|
/// <param name="filePath">The path to the file containing urlrewrite rules.</param>
|
||||||
public static IApplicationBuilder UseRewriter(this IApplicationBuilder app, UrlRewriteOptions options)
|
public static RewriteOptions ImportFromUrlRewrite(this RewriteOptions options, IHostingEnvironment hostingEnv, string filePath)
|
||||||
{
|
{
|
||||||
if (app == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(app));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options == null)
|
if (options == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(options));
|
throw new ArgumentNullException(nameof(options));
|
||||||
}
|
}
|
||||||
// put middleware in pipeline
|
|
||||||
return app.UseMiddleware<UrlRewriteMiddleware>(options);
|
if (hostingEnv == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(hostingEnv));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(filePath))
|
||||||
|
{
|
||||||
|
throw new ArgumentException(nameof(filePath));
|
||||||
|
}
|
||||||
|
|
||||||
|
var path = Path.Combine(hostingEnv.ContentRootPath, filePath);
|
||||||
|
using (var stream = File.OpenRead(path))
|
||||||
|
{
|
||||||
|
options.Rules.AddRange(UrlRewriteFileParser.Parse(new StreamReader(stream)));
|
||||||
|
};
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Imports rules from a mod_rewrite file and adds the rules to current rules.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="options">The UrlRewrite options.</param>
|
||||||
|
/// <param name="stream">The text reader stream.</param>
|
||||||
|
public static RewriteOptions ImportFromUrlRewrite(this RewriteOptions options, TextReader stream)
|
||||||
|
{
|
||||||
|
if (options == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(options));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stream == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(nameof(stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
using (stream)
|
||||||
|
{
|
||||||
|
options.Rules.AddRange(UrlRewriteFileParser.Parse(stream));
|
||||||
|
};
|
||||||
|
return options;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
// 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 Microsoft.AspNetCore.Rewrite.ModRewrite;
|
using Microsoft.AspNetCore.Rewrite.Internal.ModRewrite;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite
|
namespace Microsoft.AspNetCore.Rewrite.Tests.ModRewrite
|
||||||
{
|
{
|
||||||
public class ConditionActionTest
|
public class ConditionActionTest
|
||||||
{
|
{
|
||||||
|
|
@ -3,10 +3,10 @@
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Microsoft.AspNetCore.Rewrite.ModRewrite;
|
using Microsoft.AspNetCore.Rewrite.Internal.ModRewrite;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite
|
namespace Microsoft.AspNetCore.Rewrite.Tests.ModRewrite
|
||||||
{
|
{
|
||||||
public class FlagParserTest
|
public class FlagParserTest
|
||||||
{
|
{
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
// 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 Microsoft.AspNetCore.Rewrite.ModRewrite;
|
using Microsoft.AspNetCore.Rewrite.Internal.ModRewrite;
|
||||||
using Microsoft.AspNetCore.Rewrite.Operands;
|
using Microsoft.AspNetCore.Rewrite.Internal.ModRewrite.Operands;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace RewriteTest
|
namespace Microsoft.AspNetCore.Rewrite.Tests.ModRewrite
|
||||||
{
|
{
|
||||||
// This file tests an input of a list of tokens and verifies that the appropriate condition is obtained
|
// This file tests an input of a list of tokens and verifies that the appropriate condition is obtained
|
||||||
public class ModRewriteConditionBuilderTest
|
public class ModRewriteConditionBuilderTest
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue