Allow query string on ReExecuting status code page
This commit is contained in:
parent
0ed54e9165
commit
48b436ec8a
|
|
@ -158,8 +158,12 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// </summary>
|
||||
/// <param name="app"></param>
|
||||
/// <param name="pathFormat"></param>
|
||||
/// <param name="queryFormat"></param>
|
||||
/// <returns></returns>
|
||||
public static IApplicationBuilder UseStatusCodePagesWithReExecute(this IApplicationBuilder app, string pathFormat)
|
||||
public static IApplicationBuilder UseStatusCodePagesWithReExecute(
|
||||
this IApplicationBuilder app,
|
||||
string pathFormat,
|
||||
string queryFormat = null)
|
||||
{
|
||||
if (app == null)
|
||||
{
|
||||
|
|
@ -168,23 +172,31 @@ namespace Microsoft.AspNetCore.Builder
|
|||
|
||||
return app.UseStatusCodePages(async context =>
|
||||
{
|
||||
var newPath = new PathString(string.Format(CultureInfo.InvariantCulture, pathFormat, context.HttpContext.Response.StatusCode));
|
||||
var newPath = new PathString(
|
||||
string.Format(CultureInfo.InvariantCulture, pathFormat, context.HttpContext.Response.StatusCode));
|
||||
var formatedQueryString = queryFormat == null ? null :
|
||||
string.Format(CultureInfo.InvariantCulture, queryFormat, context.HttpContext.Response.StatusCode);
|
||||
var newQueryString = queryFormat == null ? QueryString.Empty : new QueryString(formatedQueryString);
|
||||
|
||||
var originalPath = context.HttpContext.Request.Path;
|
||||
var originalQueryString = context.HttpContext.Request.QueryString;
|
||||
// Store the original paths so the app can check it.
|
||||
context.HttpContext.Features.Set<IStatusCodeReExecuteFeature>(new StatusCodeReExecuteFeature()
|
||||
{
|
||||
OriginalPathBase = context.HttpContext.Request.PathBase.Value,
|
||||
OriginalPath = originalPath.Value,
|
||||
OriginalQueryString = originalQueryString.HasValue ? originalQueryString.Value : null,
|
||||
});
|
||||
|
||||
context.HttpContext.Request.Path = newPath;
|
||||
context.HttpContext.Request.QueryString = newQueryString;
|
||||
try
|
||||
{
|
||||
await context.Next(context.HttpContext);
|
||||
}
|
||||
finally
|
||||
{
|
||||
context.HttpContext.Request.QueryString = originalQueryString;
|
||||
context.HttpContext.Request.Path = originalPath;
|
||||
context.HttpContext.Features.Set<IStatusCodeReExecuteFeature>(null);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,5 +8,7 @@ namespace Microsoft.AspNetCore.Diagnostics
|
|||
public string OriginalPath { get; set; }
|
||||
|
||||
public string OriginalPathBase { get; set; }
|
||||
|
||||
public string OriginalQueryString { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -175,6 +175,106 @@ namespace Microsoft.AspNetCore.Diagnostics
|
|||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Redirect_StatusPage()
|
||||
{
|
||||
var expectedStatusCode = 432;
|
||||
var destination = "/location";
|
||||
var builder = new WebHostBuilder()
|
||||
.Configure(app =>
|
||||
{
|
||||
app.UseStatusCodePagesWithRedirects("/errorPage?id={0}");
|
||||
|
||||
app.Map(destination, (innerAppBuilder) =>
|
||||
{
|
||||
innerAppBuilder.Run((httpContext) =>
|
||||
{
|
||||
httpContext.Response.StatusCode = expectedStatusCode;
|
||||
return Task.FromResult(1);
|
||||
});
|
||||
});
|
||||
|
||||
app.Map("/errorPage", (innerAppBuilder) =>
|
||||
{
|
||||
innerAppBuilder.Run(async (httpContext) =>
|
||||
{
|
||||
await httpContext.Response.WriteAsync(httpContext.Request.QueryString.Value);
|
||||
});
|
||||
});
|
||||
|
||||
app.Run((context) =>
|
||||
{
|
||||
|
||||
throw new InvalidOperationException($"Invalid input provided. {context.Request.Path}");
|
||||
});
|
||||
});
|
||||
var expectedQueryString = $"?id={expectedStatusCode}";
|
||||
var expectedUri = $"/errorPage{expectedQueryString}";
|
||||
using (var server = new TestServer(builder))
|
||||
{
|
||||
|
||||
var client = server.CreateClient();
|
||||
var response = await client.GetAsync(destination);
|
||||
Assert.Equal(HttpStatusCode.Found, response.StatusCode);
|
||||
Assert.Equal(expectedUri, response.Headers.First(s => s.Key == "Location").Value.First());
|
||||
|
||||
response = await client.GetAsync(expectedUri);
|
||||
var content = await response.Content.ReadAsStringAsync();
|
||||
Assert.Equal(expectedQueryString, content);
|
||||
Assert.Equal(expectedQueryString, response.RequestMessage.RequestUri.Query);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Reexecute_RequestWithQueryString()
|
||||
{
|
||||
var expectedStatusCode = 432;
|
||||
var destination = "/location";
|
||||
var builder = new WebHostBuilder()
|
||||
.Configure(app =>
|
||||
{
|
||||
app.Use(async (context, next) =>
|
||||
{
|
||||
var beforeNext = context.Request.QueryString;
|
||||
await next();
|
||||
var afterNext = context.Request.QueryString;
|
||||
|
||||
Assert.Equal(beforeNext, afterNext);
|
||||
});
|
||||
app.UseStatusCodePagesWithReExecute("/errorPage", "?id={0}");
|
||||
|
||||
app.Map(destination, (innerAppBuilder) =>
|
||||
{
|
||||
innerAppBuilder.Run((httpContext) =>
|
||||
{
|
||||
httpContext.Response.StatusCode = expectedStatusCode;
|
||||
return Task.FromResult(1);
|
||||
});
|
||||
});
|
||||
|
||||
app.Map("/errorPage", (innerAppBuilder) =>
|
||||
{
|
||||
innerAppBuilder.Run(async (httpContext) =>
|
||||
{
|
||||
await httpContext.Response.WriteAsync(httpContext.Request.QueryString.Value);
|
||||
});
|
||||
});
|
||||
|
||||
app.Run((context) =>
|
||||
{
|
||||
throw new InvalidOperationException("Invalid input provided.");
|
||||
});
|
||||
});
|
||||
|
||||
using (var server = new TestServer(builder))
|
||||
{
|
||||
var client = server.CreateClient();
|
||||
var response = await client.GetAsync(destination);
|
||||
var content = await response.Content.ReadAsStringAsync();
|
||||
Assert.Equal($"?id={expectedStatusCode}", content);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ClearsCacheHeaders_SetByReexecutionPathHandlers()
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue