Skip to content

Commit

Permalink
Add RedirectHttpResult.IsLocalUrl() (dotnet#57363)
Browse files Browse the repository at this point in the history
Add `IsLocalUrl()` method to `RedirectHttpResult`, which is just a wrapper around `SharedUrlHelper.IsLocalUrl()`.

Resolves dotnet#56770.
  • Loading branch information
martincostello committed Aug 16, 2024
1 parent bc0ed99 commit 8fd758f
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/Http/Http.Results/src/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Microsoft.AspNetCore.Http.HttpResults.InternalServerError<TValue>
Microsoft.AspNetCore.Http.HttpResults.InternalServerError<TValue>.ExecuteAsync(Microsoft.AspNetCore.Http.HttpContext! httpContext) -> System.Threading.Tasks.Task!
Microsoft.AspNetCore.Http.HttpResults.InternalServerError<TValue>.StatusCode.get -> int
Microsoft.AspNetCore.Http.HttpResults.InternalServerError<TValue>.Value.get -> TValue?
static Microsoft.AspNetCore.Http.HttpResults.RedirectHttpResult.IsLocalUrl(string? url) -> bool
static Microsoft.AspNetCore.Http.Results.InternalServerError() -> Microsoft.AspNetCore.Http.IResult!
static Microsoft.AspNetCore.Http.Results.InternalServerError<TValue>(TValue? error) -> Microsoft.AspNetCore.Http.IResult!
static Microsoft.AspNetCore.Http.Results.Problem(string? detail = null, string? instance = null, int? statusCode = null, string? title = null, string? type = null, System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string!, object?>>? extensions = null) -> Microsoft.AspNetCore.Http.IResult!
Expand Down
12 changes: 12 additions & 0 deletions src/Http/Http.Results/src/RedirectHttpResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,18 @@ public Task ExecuteAsync(HttpContext httpContext)
return Task.CompletedTask;
}

/// <summary>
/// Returns a value that indicates whether the URL is local. A URL is considered
/// local if it does not have a host / authority part and it has an absolute path.
/// URLs using virtual paths (<c>'~/'</c>) are also local.
/// </summary>
/// <param name="url">The URL.</param>
/// <returns>
/// <see langword="true"/> if the URL is local; otherwise, <see langword="false"/>.
/// </returns>
public static bool IsLocalUrl([NotNullWhen(true)][StringSyntax(StringSyntaxAttribute.Uri)] string? url)
=> SharedUrlHelper.IsLocalUrl(url);

private static partial class Log
{
[LoggerMessage(1, LogLevel.Information,
Expand Down
50 changes: 50 additions & 0 deletions src/Http/Http.Results/test/RedirectResultTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,56 @@ public void ExecuteAsync_ThrowsArgumentNullException_WhenHttpContextIsNull()
Assert.ThrowsAsync<ArgumentNullException>("httpContext", () => result.ExecuteAsync(httpContext));
}

[Theory]
[InlineData("/")]
[InlineData("/test/path")]
[InlineData("/test/path?foo=bar#baz")]
[InlineData("~/")]
[InlineData("~/Home/About")]
public void IsLocalUrl_True_ForLocalUrl(string url)
{
// Act
var actual = RedirectHttpResult.IsLocalUrl(url);

// Assert
Assert.True(actual);
}

[Theory]
[InlineData(null)]
[InlineData("")]
[InlineData("//")]
[InlineData("/\\")]
[InlineData("//foo")]
[InlineData("/\\foo")]
[InlineData("Home/About")]
[InlineData("test/path")]
[InlineData("http://www.example.com")]
[InlineData("https://example.com/non-local-url/example")]
[InlineData("https://example.com/non-local-url/example?foo=bar#baz")]
public void IsLocalUrl_False_ForNonLocalUrl(string url)
{
// Act
var actual = RedirectHttpResult.IsLocalUrl(url);

// Assert
Assert.False(actual);
}

[Theory]
[InlineData("~//")]
[InlineData("~/\\")]
[InlineData("~//foo")]
[InlineData("~/\\foo")]
public void IsLocalUrl_False_ForNonLocalUrlTilde(string url)
{
// Act
var actual = RedirectHttpResult.IsLocalUrl(url);

// Assert
Assert.False(actual);
}

protected override Task ExecuteAsync(HttpContext httpContext, string contentPath)
{
var redirectResult = new RedirectHttpResult(contentPath, false, false);
Expand Down

0 comments on commit 8fd758f

Please sign in to comment.