Modifies .Rewrite and .Redirect to use normal regex syntax for backreferences
This commit is contained in:
parent
28133b6808
commit
4a06b37280
|
|
@ -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"));
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -42,11 +42,11 @@ namespace Microsoft.AspNetCore.Rewrite
|
|||
/// </summary>
|
||||
/// <param name="options">The Rewrite options.</param>
|
||||
/// <param name="regex">The regex string to compare with.</param>
|
||||
/// <param name="urlPattern">If the regex matches, what to replace HttpContext with.</param>
|
||||
/// <param name="replacement">If the regex matches, what to replace HttpContext with.</param>
|
||||
/// <returns>The Rewrite options.</returns>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -54,17 +54,12 @@ namespace Microsoft.AspNetCore.Rewrite
|
|||
/// </summary>
|
||||
/// <param name="options">The Rewrite options.</param>
|
||||
/// <param name="regex">The regex string to compare with.</param>
|
||||
/// <param name="urlPattern">If the regex matches, what to replace the uri with.</param>
|
||||
/// <param name="replacement">If the regex matches, what to replace the uri with.</param>
|
||||
/// <param name="stopProcessing">If the regex matches, conditionally stop processing other rules.</param>
|
||||
/// <returns>The Rewrite options.</returns>
|
||||
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
|
|||
/// </summary>
|
||||
/// <param name="options">The Rewrite options.</param>
|
||||
/// <param name="regex">The regex string to compare with.</param>
|
||||
/// <param name="urlPattern">If the regex matches, what to replace the uri with.</param>
|
||||
/// <param name="replacement">If the regex matches, what to replace the uri with.</param>
|
||||
/// <returns>The Rewrite options.</returns>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -85,21 +80,19 @@ namespace Microsoft.AspNetCore.Rewrite
|
|||
/// </summary>
|
||||
/// <param name="options">The Rewrite options.</param>
|
||||
/// <param name="regex">The regex string to compare with.</param>
|
||||
/// <param name="urlPattern">If the regex matches, what to replace the uri with.</param>
|
||||
/// <param name="replacement">If the regex matches, what to replace the uri with.</param>
|
||||
/// <param name="statusCode">The status code to add to the response.</param>
|
||||
/// <returns>The Rewrite options.</returns>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Redirect a request to https if the incoming request is http
|
||||
|
|
|
|||
|
|
@ -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 =>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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?
|
||||
|
|
|
|||
Loading…
Reference in New Issue