Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/aspnetcore.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Middleware/Rewrite/src/RedirectRule.cs72
-rw-r--r--src/Middleware/Rewrite/test/MiddlewareTests.cs23
2 files changed, 67 insertions, 28 deletions
diff --git a/src/Middleware/Rewrite/src/RedirectRule.cs b/src/Middleware/Rewrite/src/RedirectRule.cs
index e9b502295e..edce6c2c0a 100644
--- a/src/Middleware/Rewrite/src/RedirectRule.cs
+++ b/src/Middleware/Rewrite/src/RedirectRule.cs
@@ -4,8 +4,9 @@
using System;
using System.Text.RegularExpressions;
using Microsoft.AspNetCore.Http;
-using Microsoft.Net.Http.Headers;
+using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Rewrite.Logging;
+using Microsoft.Net.Http.Headers;
namespace Microsoft.AspNetCore.Rewrite
{
@@ -34,13 +35,14 @@ namespace Microsoft.AspNetCore.Rewrite
public virtual void ApplyRule(RewriteContext context)
{
- var path = context.HttpContext.Request.Path;
- var pathBase = context.HttpContext.Request.PathBase;
+ var request = context.HttpContext.Request;
+ var path = request.Path;
+ var pathBase = request.PathBase;
Match initMatchResults;
- if (path == PathString.Empty)
+ if (!path.HasValue)
{
- initMatchResults = InitialMatch.Match(path.ToString());
+ initMatchResults = InitialMatch.Match(string.Empty);
}
else
{
@@ -56,31 +58,55 @@ namespace Microsoft.AspNetCore.Rewrite
response.StatusCode = StatusCode;
context.Result = RuleResult.EndResponse;
- if (string.IsNullOrEmpty(newPath))
- {
- response.Headers[HeaderNames.Location] = pathBase.HasValue ? pathBase.Value : "/";
- return;
- }
-
- if (newPath.IndexOf(Uri.SchemeDelimiter, StringComparison.Ordinal) == -1 && newPath[0] != '/')
- {
- newPath = '/' + newPath;
- }
+ string encodedPath;
- var split = newPath.IndexOf('?');
- if (split >= 0)
+ if (string.IsNullOrEmpty(newPath))
{
- 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] = pathBase + newPath.Substring(0, split) + query.ToUriComponent();
+ encodedPath = pathBase.HasValue ? pathBase.Value : "/";
}
else
{
- response.Headers[HeaderNames.Location] = pathBase + newPath + context.HttpContext.Request.QueryString.ToUriComponent();
+ var host = default(HostString);
+ var schemeSplit = newPath.IndexOf(Uri.SchemeDelimiter, StringComparison.Ordinal);
+ if (schemeSplit >= 0)
+ {
+ schemeSplit += Uri.SchemeDelimiter.Length;
+ var pathSplit = newPath.IndexOf('/', schemeSplit);
+
+ if (pathSplit == -1)
+ {
+ host = new HostString(newPath.Substring(schemeSplit));
+ newPath = "/";
+ }
+ else
+ {
+ host = new HostString(newPath.Substring(schemeSplit, pathSplit - schemeSplit));
+ newPath = newPath.Substring(pathSplit);
+ }
+ }
+
+ if (newPath[0] != '/')
+ {
+ newPath = '/' + newPath;
+ }
+
+ var resolvedQuery = request.QueryString;
+ var resolvedPath = newPath;
+ var querySplit = newPath.IndexOf('?');
+ if (querySplit >= 0)
+ {
+ resolvedQuery = request.QueryString.Add(QueryString.FromUriComponent(newPath.Substring(querySplit)));
+ resolvedPath = newPath.Substring(0, querySplit);
+ }
+
+ encodedPath = host.HasValue
+ ? UriHelper.BuildAbsolute(request.Scheme, host, pathBase, resolvedPath, resolvedQuery, default)
+ : UriHelper.BuildRelative(pathBase, resolvedPath, resolvedQuery, default);
}
+ // not using the HttpContext.Response.redirect here because status codes may be 301, 302, 307, 308
+ response.Headers[HeaderNames.Location] = encodedPath;
+
context.Logger.RedirectedRequest(newPath);
}
}
diff --git a/src/Middleware/Rewrite/test/MiddlewareTests.cs b/src/Middleware/Rewrite/test/MiddlewareTests.cs
index dbffe3e4e3..01ade6733a 100644
--- a/src/Middleware/Rewrite/test/MiddlewareTests.cs
+++ b/src/Middleware/Rewrite/test/MiddlewareTests.cs
@@ -46,10 +46,19 @@ namespace Microsoft.AspNetCore.Rewrite.Tests.CodeRules
Assert.Equal("http://example.com/foo", response);
}
- [Fact]
- public async Task CheckRedirectPath()
+ [Theory]
+ [InlineData("(.*)", "http://example.com/$1", null, "path", "http://example.com/path")]
+ [InlineData("(.*)", "http://example.com", null, "", "http://example.com/")]
+ [InlineData("(z*)", "$1", null, "path", "/")]
+ [InlineData("(z*)", "http://example.com/$1", null, "path", "http://example.com/")]
+ [InlineData("(z*)", "$1", "http://example.com/pathBase", "/pathBase/path", "/pathBase")]
+ [InlineData("path/(.*)", "path?value=$1", null, "path/value", "/path?value=value")]
+ [InlineData("path/(.*)", "path?param=$1", null, "path/value?param1=OtherValue", "/path?param1=OtherValue&param=value")]
+ [InlineData("path/(.*)", "http://example.com/pathBase/path?param=$1", "http://example.com/pathBase", "path/value?param1=OtherValue", "http://example.com/pathBase/path?param1=OtherValue&param=value")]
+ [InlineData("path/(.*)", "http://hoψst.com/pÂthBase/path?parãm=$1", "http://example.com/pathBase", "path/value?päram1=OtherValüe", "http://xn--host-cpd.com/p%C3%82thBase/path?p%C3%A4ram1=OtherVal%C3%BCe&parãm=value")]
+ public async Task CheckRedirectPath(string pattern, string replacement, string baseAddress, string requestUrl, string expectedUrl)
{
- var options = new RewriteOptions().AddRedirect("(.*)", "http://example.com/$1", statusCode: StatusCodes.Status301MovedPermanently);
+ var options = new RewriteOptions().AddRedirect(pattern, replacement, statusCode: StatusCodes.Status301MovedPermanently);
using var host = new HostBuilder()
.ConfigureWebHost(webHostBuilder =>
{
@@ -64,10 +73,14 @@ namespace Microsoft.AspNetCore.Rewrite.Tests.CodeRules
await host.StartAsync();
var server = host.GetTestServer();
+ if (!string.IsNullOrEmpty(baseAddress))
+ {
+ server.BaseAddress = new Uri(baseAddress);
+ }
- var response = await server.CreateClient().GetAsync("foo");
+ var response = await server.CreateClient().GetAsync(requestUrl);
- Assert.Equal("http://example.com/foo", response.Headers.Location.OriginalString);
+ Assert.Equal(expectedUrl, response.Headers.Location.OriginalString);
}
[Fact]