Fix #2294: batch processing loses HttpContext for main request.#2385
Fix #2294: batch processing loses HttpContext for main request.#2385NicholasNoise wants to merge 1 commit intoOData:masterfrom
Conversation
de97791 to
27ea2f1
Compare
27ea2f1 to
06a1f05
Compare
test/UnitTest/Microsoft.AspNet.OData.Test.Shared/Batch/DefaultODataBatchHandlerTest.cs
Show resolved
Hide resolved
| } | ||
| // Create a context. | ||
| // IHttpContextFactory should not be used, because it resets IHttpContextAccessor.HttpContext; | ||
| HttpContext context = new DefaultHttpContext(features); |
There was a problem hiding this comment.
HttpContext context = new DefaultHttpContext(features); [](start = 12, length = 55)
What are the ramifications of not using the context factory? Doesn't that mean that, if someone adds their own context factory, we don't use it for batch? Couldn't that be a problem if the developer is expecting their custom httpcontext to be used? Do we instead need a way to create the context from the factory without resetting the IHttpContextAccessor.HttpContext?
There was a problem hiding this comment.
I do not see any other reason to use the factory for creating HttpContext from a set of sub-requests, but dependency injection. And it is unclear why a global factory (that creates context for an actual http request) should be used to instance batch sub-contexts.
If the factory is used we should make a closure of original context after processing batch changesets like this one:
/// <inheritdoc />
public override async Task ProcessBatchAsync(HttpContext context, RequestDelegate nextHandler)
{
// Retrieve current httpcontext.
var httpContextAccessor = context.RequestServices.GetService<IHttpContextAccessor>();
var beforeContext = httpContextAccessor?.HttpContext;
await base.ProcessBatchAsync(context, nextHandler);
if (httpContextAccessor != null)
{
httpContextAccessor.HttpContext = beforeContext;
}
}But still a closure is more like a workaround than THE solution.
Keyword new is kinda bad in common, especially in the name of DI, instead we can introduce an interface IBatchHttpContextFactory to create a context of the changeset (silly refactor)
There was a problem hiding this comment.
Hi @mikepizzo & @NicholasNoise, I tested the pr with the two suggestions. I guess my question would be for Sub requests created during batch processing should we give users more control over the creation of the context? Since we do copy the features, headers, and cookie information. One of the issues with the current approach I do see is if the user used their own IHttpContextAccessor and IHttpContextFactory then this process would need them to do more refactors if they needed to change how batch sub requests are created by extending the BatchMiddleware.
There was a problem hiding this comment.
Hi @marabooy
Yeah, we should give more control of the context creation. But as I've pointed out IHttpContextFactory is not a way to do so. I suggest a new abstraction IBatchHttpContextFactory for this matter.
|
Hi @NicholasNoise -- thanks for the contribution! As per my inline comments, I'm curious what the ramifications are if we don't use the injected HttpContextFactory. Eager to get your (and others') thoughts. |
|
@mikepizzo |
Issues
This pull request fixes issue #2294.
Description
IHttpContextFactory(DefaultHttpContextFactory) service should not be used to create newHttpContext, because it resets current context to new one:https://github.com/dotnet/aspnetcore/blob/master/src/Hosting/Hosting/src/Http/DefaultHttpContextFactory.cs#L73
Checklist (Uncheck if it is not completed)