Skip to content

Commit

Permalink
Add Redirect and RedirectPermanent to HttpResponseBase/HttpResponseWr…
Browse files Browse the repository at this point in the history
…apper (#473)

Fixes #472
  • Loading branch information
AvremelM authored Mar 11, 2024
1 parent 4e5cd12 commit 08d532b
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,10 @@ public partial class HttpResponseBase
public virtual void ClearContent() { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
public virtual void ClearHeaders() { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
public virtual void End() { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
public virtual void Redirect(string url) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
public virtual void Redirect(string url, bool endResponse) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
public virtual void RedirectPermanent(string url) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
public virtual void RedirectPermanent(string url, bool endResponse) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
public virtual void SetCookie(System.Web.HttpCookie cookie) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
public virtual void TransmitFile(string filename) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
public virtual void TransmitFile(string filename, long offset, long length) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
Expand Down Expand Up @@ -569,6 +573,10 @@ public partial class HttpResponseWrapper : System.Web.HttpResponseBase
public override void ClearContent() { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
public override void ClearHeaders() { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
public override void End() { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
public override void Redirect(string url) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
public override void Redirect(string url, bool endResponse) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
public override void RedirectPermanent(string url) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
public override void RedirectPermanent(string url, bool endResponse) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
public override void SetCookie(System.Web.HttpCookie cookie) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
public override void TransmitFile(string filename) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
public override void TransmitFile(string filename, long offset, long length) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
Expand Down
13 changes: 13 additions & 0 deletions src/Microsoft.AspNetCore.SystemWebAdapters/HttpResponseBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,19 @@ public virtual Stream Filter

public virtual void TransmitFile(string filename, long offset, long length) => throw new NotImplementedException();


[SuppressMessage("Design", "CA1054:URI parameters should not be strings", Justification = Constants.ApiFromAspNet)]
public virtual void Redirect(string url) => throw new NotImplementedException();

[SuppressMessage("Design", "CA1054:URI parameters should not be strings", Justification = Constants.ApiFromAspNet)]
public virtual void Redirect(string url, bool endResponse) => throw new NotImplementedException();

[SuppressMessage("Design", "CA1054:URI parameters should not be strings", Justification = Constants.ApiFromAspNet)]
public virtual void RedirectPermanent(string url) => throw new NotImplementedException();

[SuppressMessage("Design", "CA1054:URI parameters should not be strings", Justification = Constants.ApiFromAspNet)]
public virtual void RedirectPermanent(string url, bool endResponse) => throw new NotImplementedException();

[return: NotNullIfNotNull(nameof(response))]
public static implicit operator HttpResponseBase?(HttpResponseCore? response) => response?.HttpContext.AsSystemWebBase().Response;
}
Expand Down
14 changes: 14 additions & 0 deletions src/Microsoft.AspNetCore.SystemWebAdapters/HttpResponseWrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,5 +129,19 @@ public override Stream Filter
public override void TransmitFile(string filename, long offset, long length) => _response.TransmitFile(filename, offset, length);

public override void WriteFile(string filename) => _response.WriteFile(filename);


[SuppressMessage("Design", "CA1054:URI parameters should not be strings", Justification = Constants.ApiFromAspNet)]
public override void Redirect(string url) => _response.Redirect(url);

[SuppressMessage("Design", "CA1054:URI parameters should not be strings", Justification = Constants.ApiFromAspNet)]
public override void Redirect(string url, bool endResponse) => _response.Redirect(url, endResponse);

[SuppressMessage("Design", "CA1054:URI parameters should not be strings", Justification = Constants.ApiFromAspNet)]
public override void RedirectPermanent(string url) => _response.RedirectPermanent(url);

[SuppressMessage("Design", "CA1054:URI parameters should not be strings", Justification = Constants.ApiFromAspNet)]
public override void RedirectPermanent(string url, bool endResponse) => _response.RedirectPermanent(url, endResponse);

}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,127 @@
using System;
using System.Web;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.SystemWebAdapters.Features;
using Microsoft.AspNetCore.SystemWebAdapters.Internal;
using Microsoft.Extensions.Options;
using Microsoft.Net.Http.Headers;
using Moq;
using Xunit;

namespace Microsoft.AspNetCore.SystemWebAdapters.Tests
{
public class HttpServerUtilityWrapperTests
public class HttpResponseWrapperTests
{
[Fact]
public void Constructor()
{
Assert.Throws<ArgumentNullException>(() => new HttpServerUtilityWrapper(null!));
}
Assert.Throws<ArgumentNullException>(() => new HttpResponseWrapper(null!));
}

[InlineData("/", "~", "/", true, null)]
[InlineData("/", "~", "/", true, false)]
[InlineData("/", "~", "/", true, true)]
[InlineData("/", "~", "/", false, null)]
[InlineData("/", "~", "/", false, false)]
[InlineData("/", "~", "/", false, true)]

[InlineData("/", "~/dir", "/dir", true, null)]
[InlineData("/", "~/dir", "/dir", true, false)]
[InlineData("/", "~/dir", "/dir", true, true)]
[InlineData("/", "~/dir", "/dir", false, null)]
[InlineData("/", "~/dir", "/dir", false, false)]
[InlineData("/", "~/dir", "/dir", false, true)]

[InlineData("/", "/dir", "/dir", true, null)]
[InlineData("/", "/dir", "/dir", true, false)]
[InlineData("/", "/dir", "/dir", true, true)]
[InlineData("/", "/dir", "/dir", false, null)]
[InlineData("/", "/dir", "/dir", false, false)]
[InlineData("/", "/dir", "/dir", false, true)]

[InlineData("/dir1/", "/dir2", "/dir2", true, null)]
[InlineData("/dir1/", "/dir2", "/dir2", true, false)]
[InlineData("/dir1/", "/dir2", "/dir2", true, true)]
[InlineData("/dir1/", "/dir2", "/dir2", false, null)]
[InlineData("/dir1/", "/dir2", "/dir2", false, false)]
[InlineData("/dir1/", "/dir2", "/dir2", false, true)]

[InlineData("/dir1/", "~/dir2", "/dir1/dir2", true, null)]
[InlineData("/dir1/", "~/dir2", "/dir1/dir2", true, false)]
[InlineData("/dir1/", "~/dir2", "/dir1/dir2", true, true)]
[InlineData("/dir1/", "~/dir2", "/dir1/dir2", false, null)]
[InlineData("/dir1/", "~/dir2", "/dir1/dir2", false, false)]
[InlineData("/dir1/", "~/dir2", "/dir1/dir2", false, true)]

[InlineData("/dir1/", "", "/", true, null)]
[InlineData("/dir1/", "", "/", true, false)]
[InlineData("/dir1/", "", "/", true, true)]
[InlineData("/dir1/", "", "/", false, null)]
[InlineData("/dir1/", "", "/", false, false)]
[InlineData("/dir1/", "", "/", false, true)]

[Theory]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1054:URI-like parameters should not be strings", Justification = "Testing")]
public void Redirect(string vdir, string url, string resolved, bool permanent, bool? endResponse)
{
// Arrange
var isEndCalled = endResponse ?? true;

var options = new SystemWebAdaptersOptions
{
AppDomainAppVirtualPath = vdir,
};

var services = new Mock<IServiceProvider>();
services.Setup(s => s.GetService(typeof(IOptions<SystemWebAdaptersOptions>))).Returns(Options.Create(options));

var endFeature = new Mock<IHttpResponseEndFeature>();
endFeature.SetupAllProperties();

var context = new DefaultHttpContext();
context.Features.Set(endFeature.Object);
context.Features.Set(new Mock<IHttpResponseContentFeature>().Object);
context.RequestServices = services.Object;


// Assemble: The HttpResponse and HttpResponseWrapper
HttpResponse response = new HttpResponse(context.Response);
HttpResponseBase responseBase = new HttpResponseWrapper(response);

// Act: On the HttpResponseBase
if (endResponse.HasValue)
{
if (permanent)
{
responseBase.RedirectPermanent(url, endResponse.Value);
}
else
{
responseBase.Redirect(url, endResponse.Value);
}
}
else
{
if (permanent)
{
responseBase.RedirectPermanent(url);
}
else
{
responseBase.Redirect(url);
}
}

// Assert: On the inner HttpResponse
Assert.Equal(resolved, response.RedirectLocation);
Assert.Null(context.Features.GetRequired<IHttpResponseFeature>().ReasonPhrase);
Assert.Equal(2, context.Response.Headers.Count);
Assert.Equal(resolved, context.Response.Headers.Location);
Assert.Equal("text/html", context.Response.Headers.ContentType);
Assert.Equal(permanent ? 301 : 302, context.Response.StatusCode);

endFeature.Verify(b => b.EndAsync(), isEndCalled ? Times.Once : Times.Never);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@

namespace Microsoft.AspNetCore.SystemWebAdapters.Tests
{
public class HttpResponseWrapperTests
public class HttpServerUtilityWrapperTests
{
[Fact]
public void Constructor()
{
Assert.Throws<ArgumentNullException>(() => new HttpResponseWrapper(null!));
Assert.Throws<ArgumentNullException>(() => new HttpServerUtilityWrapper(null!));
}
}
}

0 comments on commit 08d532b

Please sign in to comment.