Adding RedirectToWwwRule and extension (#297)
This commit is contained in:
parent
840756bdde
commit
103190796f
|
|
@ -16,6 +16,7 @@ namespace Microsoft.AspNetCore.Rewrite.Logging
|
|||
private static readonly Action<ILogger, Exception> _modRewriteDidNotMatchRule;
|
||||
private static readonly Action<ILogger, Exception> _modRewriteMatchedRule;
|
||||
private static readonly Action<ILogger, Exception> _redirectedToHttps;
|
||||
private static readonly Action<ILogger, Exception> _redirectedToWww;
|
||||
private static readonly Action<ILogger, string, Exception> _redirectSummary;
|
||||
private static readonly Action<ILogger, string, Exception> _rewriteSummary;
|
||||
private static readonly Action<ILogger, string, Exception> _abortedRequest;
|
||||
|
|
@ -82,6 +83,11 @@ namespace Microsoft.AspNetCore.Rewrite.Logging
|
|||
LogLevel.Debug,
|
||||
12,
|
||||
"Request to {requestedUrl} was ended");
|
||||
|
||||
_redirectedToWww = LoggerMessage.Define(
|
||||
LogLevel.Information,
|
||||
13,
|
||||
"Request redirected to www");
|
||||
}
|
||||
|
||||
public static void RewriteMiddlewareRequestContinueResults(this ILogger logger, string currentUrl)
|
||||
|
|
@ -124,6 +130,11 @@ namespace Microsoft.AspNetCore.Rewrite.Logging
|
|||
_redirectedToHttps(logger, null);
|
||||
}
|
||||
|
||||
public static void RedirectedToWww(this ILogger logger)
|
||||
{
|
||||
_redirectedToWww(logger, null);
|
||||
}
|
||||
|
||||
public static void RedirectedSummary(this ILogger logger, string redirectedUrl)
|
||||
{
|
||||
_redirectSummary(logger, redirectedUrl, null);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
// 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;
|
||||
using Microsoft.AspNetCore.Rewrite.Logging;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
namespace Microsoft.AspNetCore.Rewrite.Internal
|
||||
{
|
||||
public class RedirectToWwwRule : IRule
|
||||
{
|
||||
public readonly int _statusCode;
|
||||
|
||||
public RedirectToWwwRule(int statusCode)
|
||||
{
|
||||
_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;
|
||||
return;
|
||||
}
|
||||
|
||||
if (req.Host.Value.StartsWith("www.", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
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;
|
||||
response.StatusCode = _statusCode;
|
||||
response.Headers[HeaderNames.Location] = newUrl;
|
||||
context.Result = RuleResult.EndResponse;
|
||||
context.Logger?.RedirectedToWww();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -117,5 +117,35 @@ namespace Microsoft.AspNetCore.Rewrite
|
|||
options.Rules.Add(new RedirectToHttpsRule { StatusCode = statusCode, SSLPort = sslPort });
|
||||
return options;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Permanently redirects the request to the www subdomain if the request is non-www.
|
||||
/// </summary>
|
||||
/// <param name="options">The <see cref="RewriteOptions"/>.</param>
|
||||
/// <returns></returns>
|
||||
public static RewriteOptions AddRedirectToWwwPermanent(this RewriteOptions options)
|
||||
{
|
||||
return AddRedirectToWww(options, statusCode: StatusCodes.Status308PermanentRedirect);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Redirect the request to the www subdomain if the incoming request is non-www.
|
||||
/// </summary>
|
||||
/// <param name="options">The <see cref="RewriteOptions"/>.</param>
|
||||
public static RewriteOptions AddRedirectToWww(this RewriteOptions options)
|
||||
{
|
||||
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="statusCode">The status code to add to the response.</param>
|
||||
public static RewriteOptions AddRedirectToWww(this RewriteOptions options, int statusCode)
|
||||
{
|
||||
options.Rules.Add(new RedirectToWwwRule(statusCode));
|
||||
return options;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -147,6 +147,91 @@ namespace Microsoft.AspNetCore.Rewrite.Tests.CodeRules
|
|||
Assert.Equal(StatusCodes.Status301MovedPermanently, (int)response.StatusCode);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(StatusCodes.Status301MovedPermanently)]
|
||||
[InlineData(StatusCodes.Status302Found)]
|
||||
[InlineData(StatusCodes.Status307TemporaryRedirect)]
|
||||
[InlineData(StatusCodes.Status308PermanentRedirect)]
|
||||
public async Task CheckRedirectToWwwWithStatusCode(int statusCode)
|
||||
{
|
||||
var options = new RewriteOptions().AddRedirectToWww(statusCode: statusCode);
|
||||
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);
|
||||
}
|
||||
|
||||
[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 CheckRedirectToWww(string requestUri, string redirectUri)
|
||||
{
|
||||
var options = new RewriteOptions().AddRedirectToWww();
|
||||
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 CheckPermanentRedirectToWww()
|
||||
{
|
||||
var options = new RewriteOptions().AddRedirectToWwwPermanent();
|
||||
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("http://www.example.com")]
|
||||
[InlineData("https://www.example.com")]
|
||||
[InlineData("http://www.example.com:8081")]
|
||||
[InlineData("https://www.example.com:8081")]
|
||||
[InlineData("https://www.example.com:8081/example?q=1")]
|
||||
[InlineData("http://localhost")]
|
||||
[InlineData("https://localhost")]
|
||||
[InlineData("http://localhost:8081")]
|
||||
[InlineData("https://localhost:8081")]
|
||||
[InlineData("https://localhost:8081/example?q=1")]
|
||||
public async Task CheckNoRedirectToWww(string requestUri)
|
||||
{
|
||||
var options = new RewriteOptions().AddRedirectToWww();
|
||||
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);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CheckIfEmptyStringRedirectCorrectly()
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue