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 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) { 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) { 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) { 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 static Microsoft.AspNetCore.Rewrite.RewriteOptions AddRewrite(this Microsoft.AspNetCore.Rewrite.RewriteOptions options, string regex, string replacement, bool skipRemainingRules) { throw null; }
|
||||||
}
|
}
|
||||||
public enum RuleResult
|
public enum RuleResult
|
||||||
|
|
@ -129,8 +132,10 @@ namespace Microsoft.AspNetCore.Rewrite.Internal
|
||||||
}
|
}
|
||||||
public partial class RedirectToWwwRule : Microsoft.AspNetCore.Rewrite.IRule
|
public partial class RedirectToWwwRule : Microsoft.AspNetCore.Rewrite.IRule
|
||||||
{
|
{
|
||||||
|
public readonly string[] _domains;
|
||||||
public readonly int _statusCode;
|
public readonly int _statusCode;
|
||||||
public RedirectToWwwRule(int statusCode) { }
|
public RedirectToWwwRule(int statusCode) { }
|
||||||
|
public RedirectToWwwRule(int statusCode, params string[] domains) { }
|
||||||
public virtual void ApplyRule(Microsoft.AspNetCore.Rewrite.RewriteContext context) { }
|
public virtual void ApplyRule(Microsoft.AspNetCore.Rewrite.RewriteContext context) { }
|
||||||
}
|
}
|
||||||
public partial class RewriteRule : Microsoft.AspNetCore.Rewrite.IRule
|
public partial class RewriteRule : Microsoft.AspNetCore.Rewrite.IRule
|
||||||
|
|
|
||||||
|
|
@ -12,15 +12,33 @@ namespace Microsoft.AspNetCore.Rewrite.Internal
|
||||||
public class RedirectToWwwRule : IRule
|
public class RedirectToWwwRule : IRule
|
||||||
{
|
{
|
||||||
public readonly int _statusCode;
|
public readonly int _statusCode;
|
||||||
|
public readonly string[] _domains;
|
||||||
|
|
||||||
public RedirectToWwwRule(int statusCode)
|
public RedirectToWwwRule(int statusCode)
|
||||||
{
|
{
|
||||||
_statusCode = 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)
|
public virtual void ApplyRule(RewriteContext context)
|
||||||
{
|
{
|
||||||
var req = context.HttpContext.Request;
|
var req = context.HttpContext.Request;
|
||||||
|
|
||||||
if (req.Host.Host.Equals("localhost", StringComparison.OrdinalIgnoreCase))
|
if (req.Host.Host.Equals("localhost", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
context.Result = RuleResult.ContinueRules;
|
context.Result = RuleResult.ContinueRules;
|
||||||
|
|
@ -33,6 +51,26 @@ namespace Microsoft.AspNetCore.Rewrite.Internal
|
||||||
return;
|
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 wwwHost = new HostString($"www.{req.Host.Value}");
|
||||||
var newUrl = UriHelper.BuildAbsolute(req.Scheme, wwwHost, req.PathBase, req.Path, req.QueryString);
|
var newUrl = UriHelper.BuildAbsolute(req.Scheme, wwwHost, req.PathBase, req.Path, req.QueryString);
|
||||||
var response = context.HttpContext.Response;
|
var response = context.HttpContext.Response;
|
||||||
|
|
|
||||||
|
|
@ -128,6 +128,17 @@ namespace Microsoft.AspNetCore.Rewrite
|
||||||
return AddRedirectToWww(options, statusCode: StatusCodes.Status308PermanentRedirect);
|
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>
|
/// <summary>
|
||||||
/// Redirect the request to the www subdomain if the incoming request is non-www.
|
/// Redirect the request to the www subdomain if the incoming request is non-www.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -137,6 +148,16 @@ namespace Microsoft.AspNetCore.Rewrite
|
||||||
return AddRedirectToWww(options, statusCode: StatusCodes.Status307TemporaryRedirect);
|
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>
|
/// <summary>
|
||||||
/// Redirect the request to the www subdomain if the incoming request is non-www.
|
/// Redirect the request to the www subdomain if the incoming request is non-www.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -147,5 +168,17 @@ namespace Microsoft.AspNetCore.Rewrite
|
||||||
options.Rules.Add(new RedirectToWwwRule(statusCode));
|
options.Rules.Add(new RedirectToWwwRule(statusCode));
|
||||||
return options;
|
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);
|
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