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>
|
/// </summary>
|
||||||
/// <param name="app"></param>
|
/// <param name="app"></param>
|
||||||
/// <param name="pathFormat"></param>
|
/// <param name="pathFormat"></param>
|
||||||
|
/// <param name="queryFormat"></param>
|
||||||
/// <returns></returns>
|
/// <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)
|
if (app == null)
|
||||||
{
|
{
|
||||||
|
|
@ -168,23 +172,31 @@ namespace Microsoft.AspNetCore.Builder
|
||||||
|
|
||||||
return app.UseStatusCodePages(async context =>
|
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 originalPath = context.HttpContext.Request.Path;
|
||||||
|
var originalQueryString = context.HttpContext.Request.QueryString;
|
||||||
// Store the original paths so the app can check it.
|
// Store the original paths so the app can check it.
|
||||||
context.HttpContext.Features.Set<IStatusCodeReExecuteFeature>(new StatusCodeReExecuteFeature()
|
context.HttpContext.Features.Set<IStatusCodeReExecuteFeature>(new StatusCodeReExecuteFeature()
|
||||||
{
|
{
|
||||||
OriginalPathBase = context.HttpContext.Request.PathBase.Value,
|
OriginalPathBase = context.HttpContext.Request.PathBase.Value,
|
||||||
OriginalPath = originalPath.Value,
|
OriginalPath = originalPath.Value,
|
||||||
|
OriginalQueryString = originalQueryString.HasValue ? originalQueryString.Value : null,
|
||||||
});
|
});
|
||||||
|
|
||||||
context.HttpContext.Request.Path = newPath;
|
context.HttpContext.Request.Path = newPath;
|
||||||
|
context.HttpContext.Request.QueryString = newQueryString;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await context.Next(context.HttpContext);
|
await context.Next(context.HttpContext);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
context.HttpContext.Request.QueryString = originalQueryString;
|
||||||
context.HttpContext.Request.Path = originalPath;
|
context.HttpContext.Request.Path = originalPath;
|
||||||
context.HttpContext.Features.Set<IStatusCodeReExecuteFeature>(null);
|
context.HttpContext.Features.Set<IStatusCodeReExecuteFeature>(null);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,5 +8,7 @@ namespace Microsoft.AspNetCore.Diagnostics
|
||||||
public string OriginalPath { get; set; }
|
public string OriginalPath { get; set; }
|
||||||
|
|
||||||
public string OriginalPathBase { 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]
|
[Fact]
|
||||||
public async Task ClearsCacheHeaders_SetByReexecutionPathHandlers()
|
public async Task ClearsCacheHeaders_SetByReexecutionPathHandlers()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue