Add option to limit domains on AddRedirectToWww (#9676)
This commit is contained in:
parent
2ed7be91e0
commit
124064ef47
|
|
@ -56,7 +56,10 @@ namespace Microsoft.AspNetCore.Rewrite
|
|||
public static Microsoft.AspNetCore.Rewrite.RewriteOptions AddRedirectToHttpsPermanent(this Microsoft.AspNetCore.Rewrite.RewriteOptions options) { throw null; }
|
||||
public static Microsoft.AspNetCore.Rewrite.RewriteOptions AddRedirectToWww(this Microsoft.AspNetCore.Rewrite.RewriteOptions options) { throw null; }
|
||||
public static Microsoft.AspNetCore.Rewrite.RewriteOptions AddRedirectToWww(this Microsoft.AspNetCore.Rewrite.RewriteOptions options, int statusCode) { throw null; }
|
||||
public static Microsoft.AspNetCore.Rewrite.RewriteOptions AddRedirectToWww(this Microsoft.AspNetCore.Rewrite.RewriteOptions options, int statusCode, params string[] domains) { throw null; }
|
||||
public static Microsoft.AspNetCore.Rewrite.RewriteOptions AddRedirectToWww(this Microsoft.AspNetCore.Rewrite.RewriteOptions options, params string[] domains) { throw null; }
|
||||
public static Microsoft.AspNetCore.Rewrite.RewriteOptions AddRedirectToWwwPermanent(this Microsoft.AspNetCore.Rewrite.RewriteOptions options) { throw null; }
|
||||
public static Microsoft.AspNetCore.Rewrite.RewriteOptions AddRedirectToWwwPermanent(this Microsoft.AspNetCore.Rewrite.RewriteOptions options, params string[] domains) { throw null; }
|
||||
public static Microsoft.AspNetCore.Rewrite.RewriteOptions AddRewrite(this Microsoft.AspNetCore.Rewrite.RewriteOptions options, string regex, string replacement, bool skipRemainingRules) { throw null; }
|
||||
}
|
||||
public enum RuleResult
|
||||
|
|
@ -129,8 +132,10 @@ namespace Microsoft.AspNetCore.Rewrite.Internal
|
|||
}
|
||||
public partial class RedirectToWwwRule : Microsoft.AspNetCore.Rewrite.IRule
|
||||
{
|
||||
public readonly string[] _domains;
|
||||
public readonly int _statusCode;
|
||||
public RedirectToWwwRule(int statusCode) { }
|
||||
public RedirectToWwwRule(int statusCode, params string[] domains) { }
|
||||
public virtual void ApplyRule(Microsoft.AspNetCore.Rewrite.RewriteContext context) { }
|
||||
}
|
||||
public partial class RewriteRule : Microsoft.AspNetCore.Rewrite.IRule
|
||||
|
|
|
|||
|
|
@ -12,15 +12,33 @@ namespace Microsoft.AspNetCore.Rewrite.Internal
|
|||
public class RedirectToWwwRule : IRule
|
||||
{
|
||||
public readonly int _statusCode;
|
||||
public readonly string[] _domains;
|
||||
|
||||
public RedirectToWwwRule(int statusCode)
|
||||
{
|
||||
_statusCode = statusCode;
|
||||
}
|
||||
|
||||
public RedirectToWwwRule(int statusCode, params string[] domains)
|
||||
{
|
||||
if (domains == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(domains));
|
||||
}
|
||||
|
||||
if (domains.Length < 1)
|
||||
{
|
||||
throw new ArgumentException(nameof(domains));
|
||||
}
|
||||
|
||||
_domains = domains;
|
||||
_statusCode = statusCode;
|
||||
}
|
||||
|
||||
public virtual void ApplyRule(RewriteContext context)
|
||||
{
|
||||
var req = context.HttpContext.Request;
|
||||
|
||||
if (req.Host.Host.Equals("localhost", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
context.Result = RuleResult.ContinueRules;
|
||||
|
|
@ -33,6 +51,26 @@ namespace Microsoft.AspNetCore.Rewrite.Internal
|
|||
return;
|
||||
}
|
||||
|
||||
if (_domains != null)
|
||||
{
|
||||
var isHostInDomains = false;
|
||||
|
||||
foreach (var domain in _domains)
|
||||
{
|
||||
if (domain.Equals(req.Host.Host, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
isHostInDomains = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isHostInDomains)
|
||||
{
|
||||
context.Result = RuleResult.ContinueRules;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var wwwHost = new HostString($"www.{req.Host.Value}");
|
||||
var newUrl = UriHelper.BuildAbsolute(req.Scheme, wwwHost, req.PathBase, req.Path, req.QueryString);
|
||||
var response = context.HttpContext.Response;
|
||||
|
|
|
|||
|
|
@ -128,6 +128,17 @@ namespace Microsoft.AspNetCore.Rewrite
|
|||
return AddRedirectToWww(options, statusCode: StatusCodes.Status308PermanentRedirect);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Permanently redirects the request to the www subdomain if the request is non-www.
|
||||
/// </summary>
|
||||
/// <param name="options">The <see cref="RewriteOptions"/>.</param>
|
||||
/// <param name="domains">Limit the rule to apply only on the specified domain(s).</param>
|
||||
/// <returns></returns>
|
||||
public static RewriteOptions AddRedirectToWwwPermanent(this RewriteOptions options, params string[] domains)
|
||||
{
|
||||
return AddRedirectToWww(options, statusCode: StatusCodes.Status308PermanentRedirect, domains);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Redirect the request to the www subdomain if the incoming request is non-www.
|
||||
/// </summary>
|
||||
|
|
@ -137,6 +148,16 @@ namespace Microsoft.AspNetCore.Rewrite
|
|||
return AddRedirectToWww(options, statusCode: StatusCodes.Status307TemporaryRedirect);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Redirect the request to the www subdomain if the incoming request is non-www.
|
||||
/// </summary>
|
||||
/// <param name="options">The <see cref="RewriteOptions"/>.</param>
|
||||
/// <param name="domains">Limit the rule to apply only on the specified domain(s).</param>
|
||||
public static RewriteOptions AddRedirectToWww(this RewriteOptions options, params string[] domains)
|
||||
{
|
||||
return AddRedirectToWww(options, statusCode: StatusCodes.Status307TemporaryRedirect, domains);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Redirect the request to the www subdomain if the incoming request is non-www.
|
||||
/// </summary>
|
||||
|
|
@ -147,5 +168,17 @@ namespace Microsoft.AspNetCore.Rewrite
|
|||
options.Rules.Add(new RedirectToWwwRule(statusCode));
|
||||
return options;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Redirect the request to the www subdomain if the incoming request is non-www.
|
||||
/// </summary>
|
||||
/// <param name="options">The <see cref="RewriteOptions"/>.</param>
|
||||
/// <param name="statusCode">The status code to add to the response.</param>
|
||||
/// <param name="domains">Limit the rule to apply only on the specified domain(s).</param>
|
||||
public static RewriteOptions AddRedirectToWww(this RewriteOptions options, int statusCode, params string[] domains)
|
||||
{
|
||||
options.Rules.Add(new RedirectToWwwRule(statusCode, domains));
|
||||
return options;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -284,5 +284,86 @@ namespace Microsoft.AspNetCore.Rewrite.Tests.CodeRules
|
|||
|
||||
Assert.Equal("/foo", response.Headers.Location.OriginalString);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("http://example.com")]
|
||||
[InlineData("https://example.com")]
|
||||
[InlineData("http://example.com:8081")]
|
||||
[InlineData("https://example.com:8081")]
|
||||
[InlineData("https://example.com:8081/example?q=1")]
|
||||
public async Task CheckNoRedirectToWwwInNonWhitelistedDomains(string requestUri)
|
||||
{
|
||||
var options = new RewriteOptions().AddRedirectToWww("example2.com");
|
||||
var builder = new WebHostBuilder()
|
||||
.Configure(app =>
|
||||
{
|
||||
app.UseRewriter(options);
|
||||
});
|
||||
var server = new TestServer(builder);
|
||||
|
||||
var response = await server.CreateClient().GetAsync(new Uri(requestUri));
|
||||
|
||||
Assert.Null(response.Headers.Location);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("http://example.com/", "http://www.example.com/")]
|
||||
[InlineData("https://example.com/", "https://www.example.com/")]
|
||||
[InlineData("http://example.com:8081", "http://www.example.com:8081/")]
|
||||
[InlineData("http://example.com:8081/example?q=1", "http://www.example.com:8081/example?q=1")]
|
||||
public async Task CheckRedirectToWwwInWhitelistedDomains(string requestUri, string redirectUri)
|
||||
{
|
||||
var options = new RewriteOptions().AddRedirectToWww("example.com");
|
||||
var builder = new WebHostBuilder()
|
||||
.Configure(app =>
|
||||
{
|
||||
app.UseRewriter(options);
|
||||
});
|
||||
var server = new TestServer(builder);
|
||||
|
||||
var response = await server.CreateClient().GetAsync(new Uri(requestUri));
|
||||
|
||||
Assert.Equal(redirectUri, response.Headers.Location.OriginalString);
|
||||
Assert.Equal(StatusCodes.Status307TemporaryRedirect, (int)response.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CheckPermanentRedirectToWwwInWhitelistedDomains()
|
||||
{
|
||||
var options = new RewriteOptions().AddRedirectToWwwPermanent("example.com");
|
||||
var builder = new WebHostBuilder()
|
||||
.Configure(app =>
|
||||
{
|
||||
app.UseRewriter(options);
|
||||
});
|
||||
var server = new TestServer(builder);
|
||||
|
||||
var response = await server.CreateClient().GetAsync(new Uri("https://example.com"));
|
||||
|
||||
Assert.Equal("https://www.example.com/", response.Headers.Location.OriginalString);
|
||||
Assert.Equal(StatusCodes.Status308PermanentRedirect, (int)response.StatusCode);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(StatusCodes.Status301MovedPermanently)]
|
||||
[InlineData(StatusCodes.Status302Found)]
|
||||
[InlineData(StatusCodes.Status307TemporaryRedirect)]
|
||||
[InlineData(StatusCodes.Status308PermanentRedirect)]
|
||||
public async Task CheckRedirectToWwwWithStatusCodeInWhitelistedDomains(int statusCode)
|
||||
{
|
||||
var options = new RewriteOptions().AddRedirectToWww(statusCode: statusCode, "example.com");
|
||||
var builder = new WebHostBuilder()
|
||||
.Configure(app =>
|
||||
{
|
||||
app.UseRewriter(options);
|
||||
});
|
||||
var server = new TestServer(builder);
|
||||
|
||||
var response = await server.CreateClient().GetAsync(new Uri("https://example.com"));
|
||||
|
||||
Assert.Equal("https://www.example.com/", response.Headers.Location.OriginalString);
|
||||
Assert.Equal(statusCode, (int)response.StatusCode);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue