diff --git a/samples/RewriteSample/Startup.cs b/samples/RewriteSample/Startup.cs
index ea80638c30..85918d2459 100644
--- a/samples/RewriteSample/Startup.cs
+++ b/samples/RewriteSample/Startup.cs
@@ -27,7 +27,7 @@ namespace RewriteSample
// TODO make this startup do something useful.
app.UseRewriter(new RewriteOptions()
- .Rewrite(@"foo/(\d+)", "foo?id={R:1}")
+ .Rewrite(@"foo/(\d+)", "foo?id=$1")
.ImportFromUrlRewrite(hostingEnv, "UrlRewrite.xml")
.ImportFromModRewrite(hostingEnv, "Rewrite.txt"));
diff --git a/src/Microsoft.AspNetCore.Rewrite/Internal/CodeRules/RedirectRule.cs b/src/Microsoft.AspNetCore.Rewrite/Internal/CodeRules/RedirectRule.cs
new file mode 100644
index 0000000000..7c33bd426f
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Rewrite/Internal/CodeRules/RedirectRule.cs
@@ -0,0 +1,66 @@
+// 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;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Net.Http.Headers;
+
+namespace Microsoft.AspNetCore.Rewrite.Internal.CodeRules
+{
+ public class RedirectRule : Rule
+ {
+ private readonly TimeSpan _regexTimeout = TimeSpan.FromSeconds(1);
+ public Regex InitialMatch { get; }
+ public string Replacement { get; }
+ public int StatusCode { get; }
+ public RedirectRule(string regex, string replacement, int statusCode)
+ {
+ InitialMatch = new Regex(regex, RegexOptions.Compiled | RegexOptions.CultureInvariant, _regexTimeout);
+ Replacement = replacement;
+ StatusCode = statusCode;
+ }
+
+ public override void ApplyRule(RewriteContext context)
+ {
+ var path = context.HttpContext.Request.Path;
+ Match initMatchResults;
+ if (path == PathString.Empty)
+ {
+ initMatchResults = InitialMatch.Match(path.ToString());
+ }
+ else
+ {
+ initMatchResults = InitialMatch.Match(path.ToString().Substring(1));
+ }
+
+ if (initMatchResults.Success)
+ {
+ var newPath = initMatchResults.Result(Replacement);
+ var response = context.HttpContext.Response;
+ response.StatusCode = StatusCode;
+
+ if (newPath.IndexOf("://", StringComparison.Ordinal) == -1 && !newPath.StartsWith("/"))
+ {
+ newPath = '/' + newPath;
+ }
+
+ var split = newPath.IndexOf('?');
+ if (split >= 0)
+ {
+ var query = context.HttpContext.Request.QueryString.Add(
+ QueryString.FromUriComponent(
+ newPath.Substring(split)));
+ // not using the HttpContext.Response.redirect here because status codes may be 301, 302, 307, 308
+ response.Headers[HeaderNames.Location] = newPath.Substring(0, split) + query;
+ }
+ else
+ {
+ response.Headers[HeaderNames.Location] = newPath;
+ }
+
+ context.Result = RuleTermination.ResponseComplete;
+ }
+ }
+ }
+}
diff --git a/src/Microsoft.AspNetCore.Rewrite/Internal/CodeRules/RewriteRule.cs b/src/Microsoft.AspNetCore.Rewrite/Internal/CodeRules/RewriteRule.cs
new file mode 100644
index 0000000000..4892a3d467
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Rewrite/Internal/CodeRules/RewriteRule.cs
@@ -0,0 +1,94 @@
+// 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;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Http.Extensions;
+
+namespace Microsoft.AspNetCore.Rewrite.Internal.CodeRules
+{
+ public class RewriteRule : Rule
+ {
+ private readonly string ForwardSlash = "/";
+ private readonly TimeSpan _regexTimeout = TimeSpan.FromSeconds(1);
+ public Regex InitialMatch { get; }
+ public string Replacement { get; }
+ public bool StopProcessing { get; }
+ public RewriteRule(string regex, string replacement, bool stopProcessing)
+ {
+ InitialMatch = new Regex(regex, RegexOptions.Compiled | RegexOptions.CultureInvariant, _regexTimeout);
+ Replacement = replacement;
+ StopProcessing = stopProcessing;
+ }
+
+ public override void ApplyRule(RewriteContext context)
+ {
+ var path = context.HttpContext.Request.Path;
+ Match initMatchResults;
+ if (path == PathString.Empty)
+ {
+ initMatchResults = InitialMatch.Match(path.ToString());
+ }
+ else
+ {
+ initMatchResults = InitialMatch.Match(path.ToString().Substring(1));
+ }
+
+ if (initMatchResults.Success)
+ {
+ var result = initMatchResults.Result(Replacement);
+ var request = context.HttpContext.Request;
+
+ if (result.IndexOf("://", StringComparison.Ordinal) >= 0)
+ {
+ string scheme;
+ HostString host;
+ PathString pathString;
+ QueryString query;
+ FragmentString fragment;
+ UriHelper.FromAbsolute(result, out scheme, out host, out pathString, out query, out fragment);
+
+ request.Scheme = scheme;
+ request.Host = host;
+ request.Path = pathString;
+ request.QueryString = query.Add(request.QueryString);
+ }
+ else
+ {
+ var split = result.IndexOf('?');
+ if (split >= 0)
+ {
+ var newPath = result.Substring(0, split);
+ if (newPath.StartsWith(ForwardSlash))
+ {
+ request.Path = PathString.FromUriComponent(newPath);
+ }
+ else
+ {
+ request.Path = PathString.FromUriComponent(ForwardSlash + newPath);
+ }
+ request.QueryString = request.QueryString.Add(
+ QueryString.FromUriComponent(
+ result.Substring(split)));
+ }
+ else
+ {
+ if (result.StartsWith(ForwardSlash))
+ {
+ request.Path = PathString.FromUriComponent(result);
+ }
+ else
+ {
+ request.Path = PathString.FromUriComponent(ForwardSlash + result);
+ }
+ }
+ }
+ if (StopProcessing)
+ {
+ context.Result = RuleTermination.StopRules;
+ }
+ }
+ }
+ }
+}
diff --git a/src/Microsoft.AspNetCore.Rewrite/Internal/ModRewrite/ModRewriteRedirectAction.cs b/src/Microsoft.AspNetCore.Rewrite/Internal/ModRewrite/ModRewriteRedirectAction.cs
deleted file mode 100644
index 6198b1a35e..0000000000
--- a/src/Microsoft.AspNetCore.Rewrite/Internal/ModRewrite/ModRewriteRedirectAction.cs
+++ /dev/null
@@ -1,70 +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.Http;
-using Microsoft.Net.Http.Headers;
-
-namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
-{
- public class ModRewriteRedirectAction : UrlAction
- {
- public int StatusCode { get; }
- public bool QueryStringAppend { get; }
- public bool QueryStringDelete { get; }
- public bool EscapeBackReferences { get; }
-
- public ModRewriteRedirectAction(
- int statusCode,
- Pattern pattern,
- bool queryStringAppend,
- bool queryStringDelete,
- bool escapeBackReferences)
- {
- StatusCode = statusCode;
- Url = pattern;
- QueryStringAppend = queryStringAppend;
- QueryStringDelete = queryStringDelete;
- EscapeBackReferences = escapeBackReferences;
- }
-
- public override void ApplyAction(RewriteContext context, MatchResults ruleMatch, MatchResults condMatch)
- {
- var pattern = Url.Evaluate(context, ruleMatch, condMatch);
- if (EscapeBackReferences)
- {
- // because escapebackreferences will be encapsulated by the pattern, just escape the pattern
- pattern = Uri.EscapeDataString(pattern);
- }
- context.HttpContext.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 && QueryStringAppend)
- {
- var query = context.HttpContext.Request.QueryString.Add(
- QueryString.FromUriComponent(
- pattern.Substring(split)));
-
- // not using the response.redirect here because status codes may be 301, 302, 307, 308
- context.HttpContext.Response.Headers[HeaderNames.Location] = pattern.Substring(0, split) + query;
- }
- else
- {
- // If the request url has a query string and the target does not, append the query string
- // by default.
- if (QueryStringDelete)
- {
- context.HttpContext.Response.Headers[HeaderNames.Location] = pattern;
- }
- else
- {
- context.HttpContext.Response.Headers[HeaderNames.Location] = pattern + context.HttpContext.Request.QueryString;
- }
- }
- context.Result = RuleTermination.ResponseComplete;
- }
- }
-}
diff --git a/src/Microsoft.AspNetCore.Rewrite/Internal/ModRewrite/ModRewriteRewriteAction.cs b/src/Microsoft.AspNetCore.Rewrite/Internal/ModRewrite/ModRewriteRewriteAction.cs
deleted file mode 100644
index 1186f3f8f9..0000000000
--- a/src/Microsoft.AspNetCore.Rewrite/Internal/ModRewrite/ModRewriteRewriteAction.cs
+++ /dev/null
@@ -1,113 +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.Http;
-using Microsoft.AspNetCore.Http.Extensions;
-
-namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
-{
- public class ModRewriteRewriteAction : UrlAction
- {
- private readonly string ForwardSlash = "/";
- public RuleTermination Result { get; }
- public bool QueryStringAppend { get; }
- public bool QueryStringDelete { get; }
- public bool EscapeBackReferences { get; }
-
- public ModRewriteRewriteAction(
- RuleTermination result,
- Pattern pattern,
- bool queryStringAppend,
- bool queryStringDelete,
- bool escapeBackReferences)
- {
- Result = result;
- Url = pattern;
- QueryStringAppend = queryStringAppend;
- QueryStringDelete = queryStringDelete;
- EscapeBackReferences = escapeBackReferences;
- }
-
- public override void ApplyAction(RewriteContext context, MatchResults ruleMatch, MatchResults condMatch)
- {
- var pattern = Url.Evaluate(context, ruleMatch, condMatch);
-
- // TODO PERF, substrings, object creation, etc.
- if (pattern.IndexOf("://", StringComparison.Ordinal) >= 0)
- {
- string scheme;
- HostString host;
- PathString path;
- QueryString query;
- FragmentString fragment;
- UriHelper.FromAbsolute(pattern, out scheme, out host, out path, out query, out fragment);
-
- if (query.HasValue)
- {
- if (QueryStringAppend)
- {
- context.HttpContext.Request.QueryString = context.HttpContext.Request.QueryString.Add(query);
- }
- else
- {
- context.HttpContext.Request.QueryString = query;
- }
- }
- else if (QueryStringDelete)
- {
- context.HttpContext.Request.QueryString = QueryString.Empty;
- }
-
- context.HttpContext.Request.Scheme = scheme;
- context.HttpContext.Request.Host = host;
- context.HttpContext.Request.Path = path;
- }
- else
- {
- var split = pattern.IndexOf('?');
- if (split >= 0)
- {
- var path = pattern.Substring(0, split);
- if (path.StartsWith(ForwardSlash))
- {
- context.HttpContext.Request.Path = PathString.FromUriComponent(path);
- }
- else
- {
- context.HttpContext.Request.Path = PathString.FromUriComponent(ForwardSlash + path);
- }
-
- if (QueryStringAppend)
- {
- context.HttpContext.Request.QueryString = context.HttpContext.Request.QueryString.Add(
- QueryString.FromUriComponent(
- pattern.Substring(split)));
- }
- else
- {
- context.HttpContext.Request.QueryString = QueryString.FromUriComponent(
- pattern.Substring(split));
- }
- }
- else
- {
- if (pattern.StartsWith(ForwardSlash))
- {
- context.HttpContext.Request.Path = PathString.FromUriComponent(pattern);
- }
- else
- {
- context.HttpContext.Request.Path = PathString.FromUriComponent(ForwardSlash + pattern);
- }
-
- if (QueryStringDelete)
- {
- context.HttpContext.Request.QueryString = QueryString.Empty;
- }
- }
- }
- context.Result = Result;
- }
- }
-}
diff --git a/src/Microsoft.AspNetCore.Rewrite/Internal/ModRewrite/RuleBuilder.cs b/src/Microsoft.AspNetCore.Rewrite/Internal/ModRewrite/RuleBuilder.cs
index be83b1f76e..8d578feed8 100644
--- a/src/Microsoft.AspNetCore.Rewrite/Internal/ModRewrite/RuleBuilder.cs
+++ b/src/Microsoft.AspNetCore.Rewrite/Internal/ModRewrite/RuleBuilder.cs
@@ -210,13 +210,13 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
{
throw new FormatException(Resources.FormatError_InputParserInvalidInteger(statusCode, -1));
}
- _action = new ModRewriteRedirectAction(res, pattern, queryStringAppend, queryStringDelete, escapeBackReference);
+ _action = new RedirectAction(res, pattern, queryStringAppend, queryStringDelete, escapeBackReference);
}
else
{
var last = flags.HasFlag(FlagType.End) || flags.HasFlag(FlagType.Last);
var termination = last ? RuleTermination.StopRules : RuleTermination.Continue;
- _action = new ModRewriteRewriteAction(termination, pattern, queryStringAppend, queryStringDelete, escapeBackReference);
+ _action = new RewriteAction(termination, pattern, queryStringAppend, queryStringDelete, escapeBackReference);
}
}
}
diff --git a/src/Microsoft.AspNetCore.Rewrite/Internal/UrlActions/RedirectAction.cs b/src/Microsoft.AspNetCore.Rewrite/Internal/UrlActions/RedirectAction.cs
index f73baad942..ef616c16b5 100644
--- a/src/Microsoft.AspNetCore.Rewrite/Internal/UrlActions/RedirectAction.cs
+++ b/src/Microsoft.AspNetCore.Rewrite/Internal/UrlActions/RedirectAction.cs
@@ -2,7 +2,9 @@
// 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 Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Rewrite.Internal.PatternSegments;
using Microsoft.Net.Http.Headers;
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlActions
@@ -10,41 +12,80 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.UrlActions
public class RedirectAction : UrlAction
{
public int StatusCode { get; }
- public bool AppendQueryString { get; }
+ public bool QueryStringAppend { get; }
+ public bool QueryStringDelete { get; }
+ public bool EscapeBackReferences { get; }
- public RedirectAction(int statusCode, Pattern pattern, bool appendQueryString)
+ public RedirectAction(
+ int statusCode,
+ Pattern pattern,
+ bool queryStringAppend,
+ bool queryStringDelete,
+ bool escapeBackReferences)
{
StatusCode = statusCode;
Url = pattern;
- AppendQueryString = appendQueryString;
+ QueryStringAppend = queryStringAppend;
+ QueryStringDelete = queryStringDelete;
+ EscapeBackReferences = escapeBackReferences;
+ }
+
+ public RedirectAction(
+ int statusCode,
+ Pattern pattern,
+ bool queryStringAppend)
+ : this(
+ statusCode,
+ pattern,
+ queryStringAppend,
+ queryStringDelete: true,
+ escapeBackReferences: false)
+ {
+
}
public override void ApplyAction(RewriteContext context, MatchResults ruleMatch, MatchResults condMatch)
{
var pattern = Url.Evaluate(context, ruleMatch, condMatch);
- context.HttpContext.Response.StatusCode = StatusCode;
+ var response = context.HttpContext.Response;
+ if (EscapeBackReferences)
+ {
+ // because escapebackreferences will be encapsulated by the pattern, just escape the pattern
+ pattern = Uri.EscapeDataString(pattern);
+ }
- // TODO IIS guarantees that there will be a leading slash
if (pattern.IndexOf("://", StringComparison.Ordinal) == -1 && !pattern.StartsWith("/"))
{
pattern = '/' + pattern;
}
+ 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 && AppendQueryString)
+ if (split >= 0 && QueryStringAppend)
{
var query = context.HttpContext.Request.QueryString.Add(
QueryString.FromUriComponent(
pattern.Substring(split)));
- // not using the HttpContext.Response.redirect here because status codes may be 301, 302, 307, 308
- context.HttpContext.Response.Headers[HeaderNames.Location] = pattern.Substring(0, split) + query;
+
+ // not using the response.redirect here because status codes may be 301, 302, 307, 308
+ response.Headers[HeaderNames.Location] = pattern.Substring(0, split) + query;
}
else
{
- context.HttpContext.Response.Headers[HeaderNames.Location] = pattern;
+ // If the request url has a query string and the target does not, append the query string
+ // by default.
+ if (QueryStringDelete)
+ {
+ response.Headers[HeaderNames.Location] = pattern;
+ }
+ else
+ {
+ response.Headers[HeaderNames.Location] = pattern + context.HttpContext.Request.QueryString;
+ }
}
context.Result = RuleTermination.ResponseComplete;
}
diff --git a/src/Microsoft.AspNetCore.Rewrite/Internal/UrlActions/RewriteAction.cs b/src/Microsoft.AspNetCore.Rewrite/Internal/UrlActions/RewriteAction.cs
index 13683a875f..c95bf909a6 100644
--- a/src/Microsoft.AspNetCore.Rewrite/Internal/UrlActions/RewriteAction.cs
+++ b/src/Microsoft.AspNetCore.Rewrite/Internal/UrlActions/RewriteAction.cs
@@ -11,24 +11,48 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.UrlActions
{
private readonly string ForwardSlash = "/";
public RuleTermination Result { get; }
- public bool ClearQuery { get; }
+ public bool QueryStringAppend { get; }
+ public bool QueryStringDelete { get; }
+ public bool EscapeBackReferences { get; }
- public RewriteAction(RuleTermination result, Pattern pattern, bool clearQuery)
+ public RewriteAction(
+ RuleTermination result,
+ Pattern pattern,
+ bool queryStringAppend,
+ bool queryStringDelete,
+ bool escapeBackReferences)
{
Result = result;
Url = pattern;
- ClearQuery = clearQuery;
+ QueryStringAppend = queryStringAppend;
+ QueryStringDelete = queryStringDelete;
+ EscapeBackReferences = escapeBackReferences;
+ }
+
+ public RewriteAction(
+ RuleTermination result,
+ Pattern pattern,
+ bool queryStringAppend):
+ this (result,
+ pattern,
+ queryStringAppend,
+ queryStringDelete: false,
+ escapeBackReferences: false)
+ {
+
}
public override void ApplyAction(RewriteContext context, MatchResults ruleMatch, MatchResults condMatch)
{
var pattern = Url.Evaluate(context, ruleMatch, condMatch);
-
- if (ClearQuery)
+ var request = context.HttpContext.Request;
+ if (EscapeBackReferences)
{
- context.HttpContext.Request.QueryString = QueryString.Empty;
+ // because escapebackreferences will be encapsulated by the pattern, just escape the pattern
+ pattern = Uri.EscapeDataString(pattern);
}
+ // TODO PERF, substrings, object creation, etc.
if (pattern.IndexOf("://", StringComparison.Ordinal) >= 0)
{
string scheme;
@@ -38,10 +62,25 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.UrlActions
FragmentString fragment;
UriHelper.FromAbsolute(pattern, out scheme, out host, out path, out query, out fragment);
- context.HttpContext.Request.Scheme = scheme;
- context.HttpContext.Request.Host = host;
- context.HttpContext.Request.Path = path;
- context.HttpContext.Request.QueryString = query.Add(context.HttpContext.Request.QueryString);
+ if (query.HasValue)
+ {
+ if (QueryStringAppend)
+ {
+ request.QueryString = request.QueryString.Add(query);
+ }
+ else
+ {
+ request.QueryString = query;
+ }
+ }
+ else if (QueryStringDelete)
+ {
+ request.QueryString = QueryString.Empty;
+ }
+
+ request.Scheme = scheme;
+ request.Host = host;
+ request.Path = path;
}
else
{
@@ -51,25 +90,39 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.UrlActions
var path = pattern.Substring(0, split);
if (path.StartsWith(ForwardSlash))
{
- context.HttpContext.Request.Path = PathString.FromUriComponent(path);
+ request.Path = PathString.FromUriComponent(path);
}
else
{
- context.HttpContext.Request.Path = PathString.FromUriComponent(ForwardSlash + path);
+ request.Path = PathString.FromUriComponent(ForwardSlash + path);
+ }
+
+ if (QueryStringAppend)
+ {
+ request.QueryString = request.QueryString.Add(
+ QueryString.FromUriComponent(
+ pattern.Substring(split)));
+ }
+ else
+ {
+ request.QueryString = QueryString.FromUriComponent(
+ pattern.Substring(split));
}
- context.HttpContext.Request.QueryString = context.HttpContext.Request.QueryString.Add(
- QueryString.FromUriComponent(
- pattern.Substring(split)));
}
else
{
if (pattern.StartsWith(ForwardSlash))
{
- context.HttpContext.Request.Path = PathString.FromUriComponent(pattern);
+ request.Path = PathString.FromUriComponent(pattern);
}
else
{
- context.HttpContext.Request.Path = PathString.FromUriComponent(ForwardSlash + pattern);
+ request.Path = PathString.FromUriComponent(ForwardSlash + pattern);
+ }
+
+ if (QueryStringDelete)
+ {
+ request.QueryString = QueryString.Empty;
}
}
}
diff --git a/src/Microsoft.AspNetCore.Rewrite/Internal/UrlRewrite/UrlRewriteRuleBuilder.cs b/src/Microsoft.AspNetCore.Rewrite/Internal/UrlRewrite/UrlRewriteRuleBuilder.cs
index bb8f2e8e7c..38d942912c 100644
--- a/src/Microsoft.AspNetCore.Rewrite/Internal/UrlRewrite/UrlRewriteRuleBuilder.cs
+++ b/src/Microsoft.AspNetCore.Rewrite/Internal/UrlRewrite/UrlRewriteRuleBuilder.cs
@@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Rewrite.Internal.ModRewrite;
using Microsoft.AspNetCore.Rewrite.Internal.UrlActions;
using Microsoft.AspNetCore.Rewrite.Internal.UrlMatches;
@@ -46,7 +47,7 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite
break;
case ActionType.Rewrite:
_action = new RewriteAction(stopProcessing ? RuleTermination.StopRules : RuleTermination.Continue,
- url, clearQuery: !appendQueryString);
+ url, appendQueryString);
break;
case ActionType.Redirect:
_action = new RedirectAction(statusCode, url, appendQueryString);
diff --git a/src/Microsoft.AspNetCore.Rewrite/RewriteOptionsExtensions.cs b/src/Microsoft.AspNetCore.Rewrite/RewriteOptionsExtensions.cs
index e0cf65479f..76c4a1e791 100644
--- a/src/Microsoft.AspNetCore.Rewrite/RewriteOptionsExtensions.cs
+++ b/src/Microsoft.AspNetCore.Rewrite/RewriteOptionsExtensions.cs
@@ -42,11 +42,11 @@ namespace Microsoft.AspNetCore.Rewrite
///
/// The Rewrite options.
/// The regex string to compare with.
- /// If the regex matches, what to replace HttpContext with.
+ /// If the regex matches, what to replace HttpContext with.
/// The Rewrite options.
- public static RewriteOptions Rewrite(this RewriteOptions options, string regex, string urlPattern)
+ public static RewriteOptions Rewrite(this RewriteOptions options, string regex, string replacement)
{
- return Rewrite(options, regex, urlPattern, stopProcessing: false);
+ return Rewrite(options, regex, replacement, stopProcessing: false);
}
///
@@ -54,17 +54,12 @@ namespace Microsoft.AspNetCore.Rewrite
///
/// The Rewrite options.
/// The regex string to compare with.
- /// If the regex matches, what to replace the uri with.
+ /// If the regex matches, what to replace the uri with.
/// If the regex matches, conditionally stop processing other rules.
/// The Rewrite options.
- public static RewriteOptions Rewrite(this RewriteOptions options, string regex, string urlPattern, bool stopProcessing)
+ public static RewriteOptions Rewrite(this RewriteOptions options, string regex, string replacement, bool stopProcessing)
{
- var builder = new UrlRewriteRuleBuilder();
- var pattern = new InputParser().ParseInputString(urlPattern);
-
- builder.AddUrlMatch(regex);
- builder.AddUrlAction(pattern, actionType: ActionType.Rewrite, stopProcessing: stopProcessing);
- options.Rules.Add(builder.Build());
+ options.Rules.Add(new RewriteRule(regex, replacement, stopProcessing));
return options;
}
@@ -73,11 +68,11 @@ namespace Microsoft.AspNetCore.Rewrite
///
/// The Rewrite options.
/// The regex string to compare with.
- /// If the regex matches, what to replace the uri with.
+ /// If the regex matches, what to replace the uri with.
/// The Rewrite options.
- public static RewriteOptions Redirect(this RewriteOptions options, string regex, string urlPattern)
+ public static RewriteOptions Redirect(this RewriteOptions options, string regex, string replacement)
{
- return Redirect(options, regex, urlPattern, statusCode: 302);
+ return Redirect(options, regex, replacement, statusCode: 302);
}
///
@@ -85,21 +80,19 @@ namespace Microsoft.AspNetCore.Rewrite
///
/// The Rewrite options.
/// The regex string to compare with.
- /// If the regex matches, what to replace the uri with.
+ /// If the regex matches, what to replace the uri with.
/// The status code to add to the response.
/// The Rewrite options.
- public static RewriteOptions Redirect(this RewriteOptions options, string regex, string urlPattern, int statusCode)
+ public static RewriteOptions Redirect(this RewriteOptions options, string regex, string replacement, int statusCode)
{
- var builder = new UrlRewriteRuleBuilder();
- var pattern = new InputParser().ParseInputString(urlPattern);
-
- builder.AddUrlMatch(regex);
- builder.AddUrlAction(pattern, actionType: ActionType.Redirect, stopProcessing: false);
- options.Rules.Add(builder.Build());
+ options.Rules.Add(new RedirectRule(regex, replacement, statusCode));
return options;
}
- // TODO 301 overload
+ public static RewriteOptions RedirectToHttpsPermanent(this RewriteOptions options)
+ {
+ return RedirectToHttps(options, statusCode: 301, sslPort: null);
+ }
///
/// Redirect a request to https if the incoming request is http
diff --git a/test/Microsoft.AspNetCore.Rewrite.Tests/CodeRules/MiddlewareTests.cs b/test/Microsoft.AspNetCore.Rewrite.Tests/CodeRules/MiddlewareTests.cs
index ce73843067..bb284b74a5 100644
--- a/test/Microsoft.AspNetCore.Rewrite.Tests/CodeRules/MiddlewareTests.cs
+++ b/test/Microsoft.AspNetCore.Rewrite.Tests/CodeRules/MiddlewareTests.cs
@@ -16,7 +16,7 @@ namespace Microsoft.AspNetCore.Rewrite.Tests.CodeRules
[Fact]
public async Task CheckRewritePath()
{
- var options = new RewriteOptions().Rewrite("(.*)", "http://example.com/{R:1}");
+ var options = new RewriteOptions().Rewrite("(.*)", "http://example.com/$1");
var builder = new WebHostBuilder()
.Configure(app =>
{
@@ -39,7 +39,7 @@ namespace Microsoft.AspNetCore.Rewrite.Tests.CodeRules
[Fact]
public async Task CheckRedirectPath()
{
- var options = new RewriteOptions().Redirect("(.*)","http://example.com/{R:1}", statusCode: 301);
+ var options = new RewriteOptions().Redirect("(.*)","http://example.com/$1", statusCode: 301);
var builder = new WebHostBuilder()
.Configure(app =>
{
diff --git a/test/Microsoft.AspNetCore.Rewrite.Tests/UrlRewrite/FileParserTests.cs b/test/Microsoft.AspNetCore.Rewrite.Tests/UrlRewrite/FileParserTests.cs
index 43a8bac189..4512d9328b 100644
--- a/test/Microsoft.AspNetCore.Rewrite.Tests/UrlRewrite/FileParserTests.cs
+++ b/test/Microsoft.AspNetCore.Rewrite.Tests/UrlRewrite/FileParserTests.cs
@@ -5,6 +5,7 @@ using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using Microsoft.AspNetCore.Rewrite.Internal;
+using Microsoft.AspNetCore.Rewrite.Internal.ModRewrite;
using Microsoft.AspNetCore.Rewrite.Internal.UrlActions;
using Microsoft.AspNetCore.Rewrite.Internal.UrlMatches;
using Microsoft.AspNetCore.Rewrite.Internal.UrlRewrite;
@@ -146,7 +147,7 @@ namespace Microsoft.AspNetCore.Rewrite.Tests.UrlRewrite
)
{
return new UrlRewriteRule(name, new RegexMatch(new Regex("^OFF$"), false), conditions,
- new RewriteAction(RuleTermination.Continue, new InputParser().ParseInputString(url), clearQuery: false));
+ new RewriteAction(RuleTermination.Continue, new InputParser().ParseInputString(url), queryStringAppend: false));
}
// TODO make rules comparable?