Skip to content
This repository has been archived by the owner on Nov 20, 2018. It is now read-only.

Attempt to make it easier to detect when the request is done #1021

Merged
merged 4 commits into from
Jun 26, 2018

Conversation

davidfowl
Copy link
Member

@davidfowl davidfowl commented Jun 26, 2018

  • Today the async local reference to the HttpContext flows when the execution context is captured. When the http request has ended, the HttpContext property will return the reference to an invalid HttpContext instead of returning null. This change stores both the request id and the HttpContext and makes sure both match before returning anything valid.
  • This is still racy but should catch more cases of people doing bad things.
  • There will still be issue if people store the context in a local and use that reference instead of accessing it through the property getter but we can live with that.
  • Added tests

Mitigates aspnet/KestrelHttpServer#2591

cc @benaadams

- Today the async local reference to the HttpContext flows when the execution context is captured. When the http request has ended, the HttpContext property will return the reference to an invalid HttpContext instead of returning null. This change stores both the request id and the HttpContext and makes sure both match before returning anything valid.
- This is still racy but should catch more cases of people doing bad things.
- There will still be issue if people store the context in a local and use that reference instead of accessing it through the property getter but we can live with that.
- Added tests
@davidfowl davidfowl requested a review from Tratcher June 26, 2018 08:22
else
{
// Setting the context to null means the request is over
existing.context.TraceIdentifier = null;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't modify the actual context, let kestrel clean that up.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is set to null in HttpProtocol.Reset()?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WebListener doesn't do this today so I'm not sure I want to remove it yet. It means all server implementations need to mutate the HttpContext on Dispose.

Copy link
Member

@Tratcher Tratcher Jun 26, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's better than having an arbitrary field mutated by the accessor. Any way to give it its own field? A feature?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I originally had that but it will make the performance worse (as it modifies the feature. We already have a feature that I'm piggy backing on. I would need to make a new feature and implement it in all the server feature collections then clear it here. It's exactly the same as this.

So the question is, what's the downside?

- Set the TraceIdentifier to null in the default HttpContextFactory
- Added more tests
}

[Fact]
public async Task HttpContextAccessor_GettingHttpContextReturnsNullHttpContextIsDifferentTraceIdentifier()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IfDifferent?


public HttpContext HttpContext
{
get
{
return _httpContextCurrent.Value;
var value = _httpContextCurrent.Value;
// Only return the context if the stored request id matches the stored trace identifier
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// TraceIdentifier is cleared by HttpContextFactory.Dispose.

}
set
{
_httpContextCurrent.Value = value;
_httpContextCurrent.Value = (value?.TraceIdentifier, value);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there ever a situation where a non-null HttpContext is set with a null TraceIdentifier? If not, this could be simplified quite a bit.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nvm. I don't think it can be easily simplified.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants