Add support for Redirect preserving method/body (HTTP 307 and 308) (#9968)

This commit is contained in:
huysentruitw 2019-05-07 00:07:07 +02:00 committed by Chris Ross
parent 0dfe695468
commit e436fd9d08
3 changed files with 43 additions and 0 deletions

View File

@ -12,6 +12,7 @@ namespace Microsoft.AspNetCore.Http
public static partial class ResponseExtensions
{
public static void Clear(this Microsoft.AspNetCore.Http.HttpResponse response) { }
public static void Redirect(this Microsoft.AspNetCore.Http.HttpResponse response, string location, bool permanent, bool preserveMethod) { }
}
public static partial class SendFileResponseExtensions
{

View File

@ -3,6 +3,7 @@
using System;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.Net.Http.Headers;
namespace Microsoft.AspNetCore.Http
{
@ -22,5 +23,26 @@ namespace Microsoft.AspNetCore.Http
response.Body.SetLength(0);
}
}
/// <summary>
/// Returns a redirect response (HTTP 301, HTTP 302, HTTP 307 or HTTP 308) to the client.
/// </summary>
/// <param name="response">The <see cref="HttpResponse"/> to redirect.</param>
/// <param name="location">The URL to redirect the client to. This must be properly encoded for use in http headers where only ASCII characters are allowed.</param>
/// <param name="permanent"><c>True</c> if the redirect is permanent (301 or 308), otherwise <c>false</c> (302 or 307).</param>
/// <param name="preserveMethod"><c>True</c> if the redirect needs to reuse the method and body (308 or 307), otherwise <c>false</c> (301 or 302).</param>
public static void Redirect(this HttpResponse response, string location, bool permanent, bool preserveMethod)
{
if (preserveMethod)
{
response.StatusCode = permanent ? StatusCodes.Status308PermanentRedirect : StatusCodes.Status307TemporaryRedirect;
}
else
{
response.StatusCode = permanent ? StatusCodes.Status301MovedPermanently : StatusCodes.Status302Found;
}
response.Headers[HeaderNames.Location] = location;
}
}
}

View File

@ -3,8 +3,11 @@
using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.Net.Http.Headers;
using Xunit;
namespace Microsoft.AspNetCore.Http.Extensions
@ -35,6 +38,23 @@ namespace Microsoft.AspNetCore.Http.Extensions
Assert.Throws<InvalidOperationException>(() => context.Response.Clear());
}
[Theory]
[InlineData(true, false, 301)]
[InlineData(false, false, 302)]
[InlineData(true, true, 308)]
[InlineData(false, true, 307)]
public void Redirect_SetsResponseCorrectly(bool permanent, bool preserveMethod, int expectedStatusCode)
{
var location = "http://localhost/redirect";
var context = new DefaultHttpContext();
context.Response.StatusCode = StatusCodes.Status200OK;
context.Response.Redirect(location, permanent, preserveMethod);
Assert.Equal(location, context.Response.Headers[HeaderNames.Location].First());
Assert.Equal(expectedStatusCode, context.Response.StatusCode);
}
private class StartedResponseFeature : IHttpResponseFeature
{
public Stream Body { get; set; }