Adds path base to redirect location and tests

This commit is contained in:
Justin Kotalik 2016-09-02 10:12:59 -07:00
parent f99a9be4d0
commit 57c1f877e3
5 changed files with 75 additions and 7 deletions

View File

@ -34,6 +34,8 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.CodeRules
public override void ApplyRule(RewriteContext context) public override void ApplyRule(RewriteContext context)
{ {
var path = context.HttpContext.Request.Path; var path = context.HttpContext.Request.Path;
var pathBase = context.HttpContext.Request.PathBase;
Match initMatchResults; Match initMatchResults;
if (path == PathString.Empty) if (path == PathString.Empty)
{ {
@ -54,7 +56,7 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.CodeRules
if (string.IsNullOrEmpty(newPath)) if (string.IsNullOrEmpty(newPath))
{ {
response.Headers[HeaderNames.Location] = "/"; response.Headers[HeaderNames.Location] = pathBase.HasValue ? pathBase.Value : "/";
return; return;
} }
@ -70,11 +72,11 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.CodeRules
QueryString.FromUriComponent( QueryString.FromUriComponent(
newPath.Substring(split))); newPath.Substring(split)));
// not using the HttpContext.Response.redirect here because status codes may be 301, 302, 307, 308 // 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; response.Headers[HeaderNames.Location] = pathBase + newPath.Substring(0, split) + query;
} }
else else
{ {
response.Headers[HeaderNames.Location] = newPath; response.Headers[HeaderNames.Location] = pathBase + newPath;
} }
} }
} }

View File

@ -47,6 +47,7 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.UrlActions
{ {
var pattern = Url.Evaluate(context, ruleMatch, condMatch); var pattern = Url.Evaluate(context, ruleMatch, condMatch);
var response = context.HttpContext.Response; var response = context.HttpContext.Response;
var pathBase = context.HttpContext.Request.PathBase;
if (EscapeBackReferences) if (EscapeBackReferences)
{ {
// because escapebackreferences will be encapsulated by the pattern, just escape the pattern // because escapebackreferences will be encapsulated by the pattern, just escape the pattern
@ -55,7 +56,7 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.UrlActions
if (string.IsNullOrEmpty(pattern)) if (string.IsNullOrEmpty(pattern))
{ {
response.Headers[HeaderNames.Location] = "/"; response.Headers[HeaderNames.Location] = pathBase.HasValue ? pathBase.Value : "/";
return; return;
} }
@ -77,7 +78,7 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.UrlActions
pattern.Substring(split))); pattern.Substring(split)));
// not using the response.redirect here because status codes may be 301, 302, 307, 308 // not using the response.redirect here because status codes may be 301, 302, 307, 308
response.Headers[HeaderNames.Location] = pattern.Substring(0, split) + query; response.Headers[HeaderNames.Location] = pathBase + pattern.Substring(0, split) + query;
} }
else else
{ {
@ -85,11 +86,11 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.UrlActions
// by default. // by default.
if (QueryStringDelete) if (QueryStringDelete)
{ {
response.Headers[HeaderNames.Location] = pattern; response.Headers[HeaderNames.Location] = pathBase + pattern;
} }
else else
{ {
response.Headers[HeaderNames.Location] = pattern + context.HttpContext.Request.QueryString; response.Headers[HeaderNames.Location] = pathBase + pattern + context.HttpContext.Request.QueryString;
} }
} }
context.Result = RuleTermination.ResponseComplete; context.Result = RuleTermination.ResponseComplete;

View File

@ -102,5 +102,24 @@ namespace Microsoft.AspNetCore.Rewrite.Tests.CodeRules
Assert.Equal(response, "/"); Assert.Equal(response, "/");
} }
[Fact]
public async Task SettingPathBase()
{
var options = new RewriteOptions().AddRedirect("(.*)", "$1");
var builder = new WebHostBuilder()
.Configure(app =>
{
app.UseRewriter(options);
app.Run(context => context.Response.WriteAsync(
context.Request.Path +
context.Request.QueryString));
});
var server = new TestServer(builder) {BaseAddress = new Uri("http://localhost:5000/foo")};
var response = await server.CreateClient().GetAsync("");
Assert.Equal(response.Headers.Location.OriginalString, "/foo");
}
} }
} }

View File

@ -1,6 +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.
using System;
using System.IO; using System.IO;
using System.Net; using System.Net;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -286,5 +287,24 @@ namespace Microsoft.AspNetCore.Rewrite.Tests.ModRewrite
var response = await server.CreateClient().GetStringAsync(input); var response = await server.CreateClient().GetStringAsync(input);
Assert.Equal(response, "/"); Assert.Equal(response, "/");
} }
[Fact]
public async Task Invoke_CaptureEmptyStringInRegexAssertLocationHeaderContainsPathBase()
{
var options = new RewriteOptions().AddApacheModRewrite(new StringReader(@"RewriteRule ^(.*)$ $1 [R=301,L]"));
var builder = new WebHostBuilder()
.Configure(app =>
{
app.UseRewriter(options);
app.Run(context => context.Response.WriteAsync(
context.Request.Path +
context.Request.QueryString));
});
var server = new TestServer(builder) { BaseAddress = new Uri("http://localhost:5000/foo") };
var response = await server.CreateClient().GetAsync("");
Assert.Equal(response.Headers.Location.OriginalString, "/foo");
}
} }
} }

View File

@ -310,5 +310,31 @@ namespace Microsoft.AspNetCore.Rewrite.Tests.UrlRewrite
Assert.Equal(response, "/"); Assert.Equal(response, "/");
} }
[Fact]
public async Task Invoke_CaptureEmptyStringInRegexAssertLocationHeaderContainsPathBase()
{
var options = new RewriteOptions().AddIISUrlRewrite(new StringReader(@"<rewrite>
<rules>
<rule name=""Test"">
<match url=""(.*)"" />
<action type=""Redirect"" url=""{R:1}"" />
</rule>
</rules>
</rewrite>"));
var builder = new WebHostBuilder()
.Configure(app =>
{
app.UseRewriter(options);
app.Run(context => context.Response.WriteAsync(
context.Request.Path +
context.Request.QueryString));
});
var server = new TestServer(builder) { BaseAddress = new Uri("http://localhost:5000/foo") };
var response = await server.CreateClient().GetAsync("");
Assert.Equal(response.Headers.Location.OriginalString, "/foo");
}
} }
} }