Add www to root domain redirects (#12997)
This commit is contained in:
parent
d4f7a199c7
commit
a23dd41428
|
|
@ -54,6 +54,12 @@ namespace Microsoft.AspNetCore.Rewrite
|
||||||
public static Microsoft.AspNetCore.Rewrite.RewriteOptions AddRedirectToHttps(this Microsoft.AspNetCore.Rewrite.RewriteOptions options, int statusCode) { throw null; }
|
public static Microsoft.AspNetCore.Rewrite.RewriteOptions AddRedirectToHttps(this Microsoft.AspNetCore.Rewrite.RewriteOptions options, int statusCode) { throw null; }
|
||||||
public static Microsoft.AspNetCore.Rewrite.RewriteOptions AddRedirectToHttps(this Microsoft.AspNetCore.Rewrite.RewriteOptions options, int statusCode, int? sslPort) { throw null; }
|
public static Microsoft.AspNetCore.Rewrite.RewriteOptions AddRedirectToHttps(this Microsoft.AspNetCore.Rewrite.RewriteOptions options, int statusCode, int? sslPort) { throw null; }
|
||||||
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 AddRedirectToNonWww(this Microsoft.AspNetCore.Rewrite.RewriteOptions options) { throw null; }
|
||||||
|
public static Microsoft.AspNetCore.Rewrite.RewriteOptions AddRedirectToNonWww(this Microsoft.AspNetCore.Rewrite.RewriteOptions options, int statusCode) { throw null; }
|
||||||
|
public static Microsoft.AspNetCore.Rewrite.RewriteOptions AddRedirectToNonWww(this Microsoft.AspNetCore.Rewrite.RewriteOptions options, int statusCode, params string[] domains) { throw null; }
|
||||||
|
public static Microsoft.AspNetCore.Rewrite.RewriteOptions AddRedirectToNonWww(this Microsoft.AspNetCore.Rewrite.RewriteOptions options, params string[] domains) { throw null; }
|
||||||
|
public static Microsoft.AspNetCore.Rewrite.RewriteOptions AddRedirectToNonWwwPermanent(this Microsoft.AspNetCore.Rewrite.RewriteOptions options) { throw null; }
|
||||||
|
public static Microsoft.AspNetCore.Rewrite.RewriteOptions AddRedirectToNonWwwPermanent(this Microsoft.AspNetCore.Rewrite.RewriteOptions options, params string[] domains) { 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, int statusCode, params string[] domains) { throw null; }
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ namespace Microsoft.AspNetCore.Rewrite.Logging
|
||||||
private static readonly Action<ILogger, Exception> _modRewriteMatchedRule;
|
private static readonly Action<ILogger, Exception> _modRewriteMatchedRule;
|
||||||
private static readonly Action<ILogger, Exception> _redirectedToHttps;
|
private static readonly Action<ILogger, Exception> _redirectedToHttps;
|
||||||
private static readonly Action<ILogger, Exception> _redirectedToWww;
|
private static readonly Action<ILogger, Exception> _redirectedToWww;
|
||||||
|
private static readonly Action<ILogger, Exception> _redirectedToNonWww;
|
||||||
private static readonly Action<ILogger, string, Exception> _redirectedRequest;
|
private static readonly Action<ILogger, string, Exception> _redirectedRequest;
|
||||||
private static readonly Action<ILogger, string, Exception> _rewrittenRequest;
|
private static readonly Action<ILogger, string, Exception> _rewrittenRequest;
|
||||||
private static readonly Action<ILogger, string, Exception> _abortedRequest;
|
private static readonly Action<ILogger, string, Exception> _abortedRequest;
|
||||||
|
|
@ -88,6 +89,11 @@ namespace Microsoft.AspNetCore.Rewrite.Logging
|
||||||
LogLevel.Information,
|
LogLevel.Information,
|
||||||
new EventId(13, "RedirectedToWww"),
|
new EventId(13, "RedirectedToWww"),
|
||||||
"Request redirected to www");
|
"Request redirected to www");
|
||||||
|
|
||||||
|
_redirectedToNonWww = LoggerMessage.Define(
|
||||||
|
LogLevel.Information,
|
||||||
|
new EventId(14, "RedirectedToNonWww"),
|
||||||
|
"Request redirected to root domain from www subdomain");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void RewriteMiddlewareRequestContinueResults(this ILogger logger, string currentUrl)
|
public static void RewriteMiddlewareRequestContinueResults(this ILogger logger, string currentUrl)
|
||||||
|
|
@ -135,6 +141,11 @@ namespace Microsoft.AspNetCore.Rewrite.Logging
|
||||||
_redirectedToWww(logger, null);
|
_redirectedToWww(logger, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void RedirectedToNonWww(this ILogger logger)
|
||||||
|
{
|
||||||
|
_redirectedToNonWww(logger, null);
|
||||||
|
}
|
||||||
|
|
||||||
public static void RedirectedRequest(this ILogger logger, string redirectedUrl)
|
public static void RedirectedRequest(this ILogger logger, string redirectedUrl)
|
||||||
{
|
{
|
||||||
_redirectedRequest(logger, redirectedUrl, null);
|
_redirectedRequest(logger, redirectedUrl, null);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
// 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.Rewrite.Logging;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Rewrite
|
||||||
|
{
|
||||||
|
internal class RedirectToNonWwwRule : IRule
|
||||||
|
{
|
||||||
|
private const string WwwDot = "www.";
|
||||||
|
|
||||||
|
private readonly string[] _domains;
|
||||||
|
private readonly int _statusCode;
|
||||||
|
|
||||||
|
public RedirectToNonWwwRule(int statusCode)
|
||||||
|
{
|
||||||
|
_statusCode = statusCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RedirectToNonWwwRule(int statusCode, params string[] domains)
|
||||||
|
{
|
||||||
|
if (domains == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(domains));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (domains.Length < 1)
|
||||||
|
{
|
||||||
|
throw new ArgumentException($"One or more {nameof(domains)} must be provided.");
|
||||||
|
}
|
||||||
|
|
||||||
|
_domains = domains;
|
||||||
|
_statusCode = statusCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ApplyRule(RewriteContext context)
|
||||||
|
{
|
||||||
|
var request = context.HttpContext.Request;
|
||||||
|
|
||||||
|
var hostInDomains = RedirectToWwwHelper.IsHostInDomains(request, _domains);
|
||||||
|
|
||||||
|
if (!hostInDomains)
|
||||||
|
{
|
||||||
|
context.Result = RuleResult.ContinueRules;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!request.Host.Value.StartsWith(WwwDot, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
context.Result = RuleResult.ContinueRules;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RedirectToWwwHelper.SetRedirect(
|
||||||
|
context,
|
||||||
|
new HostString(request.Host.Value.Substring(4)), // We verified the hostname begins with "www." already.
|
||||||
|
_statusCode);
|
||||||
|
|
||||||
|
context.Logger.RedirectedToNonWww();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
// 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.Net.Http.Headers;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Rewrite
|
||||||
|
{
|
||||||
|
internal static class RedirectToWwwHelper
|
||||||
|
{
|
||||||
|
private const string Localhost = "localhost";
|
||||||
|
|
||||||
|
public static bool IsHostInDomains(HttpRequest request, string[] domains)
|
||||||
|
{
|
||||||
|
if (request.Host.Host.Equals(Localhost, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (domains != null)
|
||||||
|
{
|
||||||
|
var isHostInDomains = false;
|
||||||
|
|
||||||
|
foreach (var domain in domains)
|
||||||
|
{
|
||||||
|
if (domain.Equals(request.Host.Host, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
isHostInDomains = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isHostInDomains)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetRedirect(RewriteContext context, HostString newHost, int statusCode)
|
||||||
|
{
|
||||||
|
var request = context.HttpContext.Request;
|
||||||
|
var response = context.HttpContext.Response;
|
||||||
|
|
||||||
|
var newUrl = UriHelper.BuildAbsolute(
|
||||||
|
request.Scheme,
|
||||||
|
newHost,
|
||||||
|
request.PathBase,
|
||||||
|
request.Path,
|
||||||
|
request.QueryString);
|
||||||
|
|
||||||
|
response.StatusCode = statusCode;
|
||||||
|
response.Headers[HeaderNames.Location] = newUrl;
|
||||||
|
context.Result = RuleResult.EndResponse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,16 +3,16 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Http.Extensions;
|
|
||||||
using Microsoft.AspNetCore.Rewrite.Logging;
|
using Microsoft.AspNetCore.Rewrite.Logging;
|
||||||
using Microsoft.Net.Http.Headers;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Rewrite
|
namespace Microsoft.AspNetCore.Rewrite
|
||||||
{
|
{
|
||||||
internal class RedirectToWwwRule : IRule
|
internal class RedirectToWwwRule : IRule
|
||||||
{
|
{
|
||||||
public readonly int _statusCode;
|
private const string WwwDot = "www.";
|
||||||
public readonly string[] _domains;
|
|
||||||
|
private readonly string[] _domains;
|
||||||
|
private readonly int _statusCode;
|
||||||
|
|
||||||
public RedirectToWwwRule(int statusCode)
|
public RedirectToWwwRule(int statusCode)
|
||||||
{
|
{
|
||||||
|
|
@ -28,55 +28,36 @@ namespace Microsoft.AspNetCore.Rewrite
|
||||||
|
|
||||||
if (domains.Length < 1)
|
if (domains.Length < 1)
|
||||||
{
|
{
|
||||||
throw new ArgumentException(nameof(domains));
|
throw new ArgumentException($"One or more {nameof(domains)} must be provided.");
|
||||||
}
|
}
|
||||||
|
|
||||||
_domains = domains;
|
_domains = domains;
|
||||||
_statusCode = statusCode;
|
_statusCode = statusCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void ApplyRule(RewriteContext context)
|
public void ApplyRule(RewriteContext context)
|
||||||
{
|
{
|
||||||
var req = context.HttpContext.Request;
|
var req = context.HttpContext.Request;
|
||||||
|
|
||||||
if (req.Host.Host.Equals("localhost", StringComparison.OrdinalIgnoreCase))
|
var hostInDomains = RedirectToWwwHelper.IsHostInDomains(req, _domains);
|
||||||
|
|
||||||
|
if (!hostInDomains)
|
||||||
{
|
{
|
||||||
context.Result = RuleResult.ContinueRules;
|
context.Result = RuleResult.ContinueRules;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req.Host.Value.StartsWith("www.", StringComparison.OrdinalIgnoreCase))
|
if (req.Host.Value.StartsWith(WwwDot, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
context.Result = RuleResult.ContinueRules;
|
context.Result = RuleResult.ContinueRules;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_domains != null)
|
RedirectToWwwHelper.SetRedirect(
|
||||||
{
|
context,
|
||||||
var isHostInDomains = false;
|
new HostString($"www.{context.HttpContext.Request.Host.Value}"),
|
||||||
|
_statusCode);
|
||||||
|
|
||||||
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;
|
|
||||||
response.StatusCode = _statusCode;
|
|
||||||
response.Headers[HeaderNames.Location] = newUrl;
|
|
||||||
context.Result = RuleResult.EndResponse;
|
|
||||||
context.Logger.RedirectedToWww();
|
context.Logger.RedirectedToWww();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -179,5 +179,68 @@ namespace Microsoft.AspNetCore.Rewrite
|
||||||
options.Rules.Add(new RedirectToWwwRule(statusCode, domains));
|
options.Rules.Add(new RedirectToWwwRule(statusCode, domains));
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Permanently redirects the request to the root domain if the request is from the www subdomain.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="options">The <see cref="RewriteOptions"/>.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static RewriteOptions AddRedirectToNonWwwPermanent(this RewriteOptions options)
|
||||||
|
{
|
||||||
|
return AddRedirectToNonWww(options, statusCode: StatusCodes.Status308PermanentRedirect);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Permanently redirects the request to the root domain if the request is from the www subdomain.
|
||||||
|
/// </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 AddRedirectToNonWwwPermanent(this RewriteOptions options, params string[] domains)
|
||||||
|
{
|
||||||
|
return AddRedirectToNonWww(options, statusCode: StatusCodes.Status308PermanentRedirect, domains);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Redirect the request to the root domain if the incoming request is from the www subdomain.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="options">The <see cref="RewriteOptions"/>.</param>
|
||||||
|
public static RewriteOptions AddRedirectToNonWww(this RewriteOptions options)
|
||||||
|
{
|
||||||
|
return AddRedirectToNonWww(options, statusCode: StatusCodes.Status307TemporaryRedirect);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Redirect the request to the root domain if the incoming request is from the www subdomain.
|
||||||
|
/// </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 AddRedirectToNonWww(this RewriteOptions options, params string[] domains)
|
||||||
|
{
|
||||||
|
return AddRedirectToNonWww(options, statusCode: StatusCodes.Status307TemporaryRedirect, domains);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Redirect the request to the root domain if the incoming request is from the www subdomain.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="options">The <see cref="RewriteOptions"/>.</param>
|
||||||
|
/// <param name="statusCode">The status code to add to the response.</param>
|
||||||
|
public static RewriteOptions AddRedirectToNonWww(this RewriteOptions options, int statusCode)
|
||||||
|
{
|
||||||
|
options.Rules.Add(new RedirectToNonWwwRule(statusCode));
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Redirect the request to the root domain if the incoming request is from the www subdomain.
|
||||||
|
/// </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 AddRedirectToNonWww(this RewriteOptions options, int statusCode, params string[] domains)
|
||||||
|
{
|
||||||
|
options.Rules.Add(new RedirectToNonWwwRule(statusCode, domains));
|
||||||
|
return options;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// 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;
|
||||||
|
|
@ -232,6 +232,65 @@ namespace Microsoft.AspNetCore.Rewrite.Tests.CodeRules
|
||||||
Assert.Null(response.Headers.Location);
|
Assert.Null(response.Headers.Location);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(StatusCodes.Status301MovedPermanently)]
|
||||||
|
[InlineData(StatusCodes.Status302Found)]
|
||||||
|
[InlineData(StatusCodes.Status307TemporaryRedirect)]
|
||||||
|
[InlineData(StatusCodes.Status308PermanentRedirect)]
|
||||||
|
public async Task CheckRedirectToNonWwwWithStatusCode(int statusCode)
|
||||||
|
{
|
||||||
|
var options = new RewriteOptions().AddRedirectToNonWww(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://www.example.com"));
|
||||||
|
|
||||||
|
Assert.Equal("https://example.com/", response.Headers.Location.OriginalString);
|
||||||
|
Assert.Equal(statusCode, (int)response.StatusCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("http://www.example.com", "http://example.com/")]
|
||||||
|
[InlineData("https://www.example.com", "https://example.com/")]
|
||||||
|
[InlineData("http://www.example.com:8081", "http://example.com:8081/")]
|
||||||
|
[InlineData("http://www.example.com:8081/example?q=1", "http://example.com:8081/example?q=1")]
|
||||||
|
public async Task CheckRedirectToNonWww(string requestUri, string redirectUri)
|
||||||
|
{
|
||||||
|
var options = new RewriteOptions().AddRedirectToNonWww();
|
||||||
|
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 CheckPermanentRedirectToNonWww()
|
||||||
|
{
|
||||||
|
var options = new RewriteOptions().AddRedirectToNonWwwPermanent();
|
||||||
|
var builder = new WebHostBuilder()
|
||||||
|
.Configure(app =>
|
||||||
|
{
|
||||||
|
app.UseRewriter(options);
|
||||||
|
});
|
||||||
|
var server = new TestServer(builder);
|
||||||
|
|
||||||
|
var response = await server.CreateClient().GetAsync(new Uri("https://www.example.com"));
|
||||||
|
|
||||||
|
Assert.Equal("https://example.com/", response.Headers.Location.OriginalString);
|
||||||
|
Assert.Equal(StatusCodes.Status308PermanentRedirect, (int)response.StatusCode);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task CheckIfEmptyStringRedirectCorrectly()
|
public async Task CheckIfEmptyStringRedirectCorrectly()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue