-
Notifications
You must be signed in to change notification settings - Fork 10k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
HeaderPropagation: propagate incoming request headers to outgoing HTTP requests #7921
Conversation
src/Middleware/HeaderPropagation/src/DependencyInjection/HeaderPropagationExtensions.cs
Outdated
Show resolved
Hide resolved
src/Middleware/HeaderPropagation/src/HeaderPropagationMessageHandler.cs
Outdated
Show resolved
Hide resolved
src/Middleware/HeaderPropagation/src/Microsoft.AspNetCore.Http.HeaderPropagation.csproj
Outdated
Show resolved
Hide resolved
src/Middleware/HeaderPropagation/src/DependencyInjection/HeaderPropagationExtensions.cs
Outdated
Show resolved
Hide resolved
src/Middleware/HeaderPropagation/src/DependencyInjection/HeaderPropagationExtensions.cs
Outdated
Show resolved
Hide resolved
I've introduced the Middleware to solve the concurrency issue. The I'm not convinced about the configuration... the behavior it's probably not really straightforward and can be simplified. |
src/Middleware/HeaderPropagation/src/DependencyInjection/HeaderPropagationExtensions.cs
Outdated
Show resolved
Hide resolved
src/Middleware/HeaderPropagation/src/DependencyInjection/HeaderPropagationExtensions.cs
Outdated
Show resolved
Hide resolved
src/Middleware/HeaderPropagation/src/HeaderPropagationMiddleware.cs
Outdated
Show resolved
Hide resolved
src/Middleware/HeaderPropagation/src/HeaderPropagationMiddleware.cs
Outdated
Show resolved
Hide resolved
src/Middleware/HeaderPropagation/src/HeaderPropagationMessageHandler.cs
Outdated
Show resolved
Hide resolved
src/Middleware/HeaderPropagation/src/DependencyInjection/HeaderPropagationExtensions.cs
Outdated
Show resolved
Hide resolved
src/Middleware/HeaderPropagation/src/DependencyInjection/HeaderPropagationExtensions.cs
Outdated
Show resolved
Hide resolved
src/Middleware/HeaderPropagation/test/HeaderPropagationIntegrationTest.cs
Outdated
Show resolved
Hide resolved
src/Middleware/HeaderPropagation/test/HeaderPropagationMessageHandlerTest.cs
Outdated
Show resolved
Hide resolved
src/Middleware/HeaderPropagation/test/HeaderPropagationMessageHandlerTest.cs
Show resolved
Hide resolved
src/Middleware/HeaderPropagation/src/HeaderPropagationMiddleware.cs
Outdated
Show resolved
Hide resolved
src/Middleware/HeaderPropagation/test/HeaderPropagationMiddlewareTest.cs
Show resolved
Hide resolved
Hi @rynowak , thank you for the review and apologies for the delay on my side :) I'll have a look tomorrow at why it's not passing on the CI |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Didn't look at the C# files at all but the rest looks good
@alefranz - could you rebase? after that I think we're ready to go. |
Thanks everyone! |
ci tests on windows are failing, but it looks unrelated
|
This comment was made automatically. If there is a problem contact ryanbrandenburg. I've triaged the above build. |
Merged ! Thanks @alefranz and everyone else who helped review. |
@rynowak What is the policy about back-porting this kind of packages to 2.2? |
@alefranz - we don't backport features to already shipped releases. If you want a version of this you can use with 2.2, I would suggest grabbing the code and building it from source - it should be straightforward since this package doesn't have tendrils anywhere else.. @Eilon will correct me if I'm wrong but our license allows you to copy as much code as you want (with attribution). |
Yup, what @rynowak said. |
@rynowak I didn't get a chance to review the entire changeset closely, but is it implemented to reduce allocations as much as practical? |
Nice work @alefranz :) |
Our work is never over. If you think it can be improved, collect some data and send a PR 👍 |
👍 Maybe I'll see if I can nerd-snipe @benaadams into taking a peek first :) Cheers all |
_values.Headers.TryGetValue(headerName, out var values) && | ||
!StringValues.IsNullOrEmpty(values)) | ||
{ | ||
request.Headers.TryAddWithoutValidation(outputName, (string[])values); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The cast (string[])values
will cause an array allocation for most headers (which are only one)
Better would be to check the count and then switch on overload e.g.
var count = values.Count;
if (count == 1)
{
request.Headers.TryAddWithoutValidation(outputName, (string)values);
}
else if (count > 1)
{
request.Headers.TryAddWithoutValidation(outputName, (string[])values);
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also HttpClient has an odd behaviour where some headers are rejected from the Headers collection and instead need to be added to the Content.Headers collection (if there is a content); so might need to be more like:
var hasContent = request.Content != null;
// ...
var count = values.Count;
if (count == 1)
{
var value = (string)values;
if (!request.Headers.TryAddWithoutValidation(outputName, value) && hasContent)
{
request.Content.Headers.TryAddWithoutValidation(outputName, value);
}
}
else ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @benaadams !
I'll raise a PR to address this by the end of the week.
This PR introduces a
MessageHandler
for theHttpClientFactory
to forward headers received in the current MVC request.It is a port of dotnet/extensions#1099 which
Addresses dotnet/extensions#526
Main feedback on the original PR
@natemcmaster : it can't be added to https://github.com/aspnet/Extensions as it introduce a circulr dependency
@rynowak has suggested to move this to this repo as middleware.
@Tratcher it is not handling concurrency in accessing the Context if multiple HttpClient requests are sent in parallel
@Tratcher @rynowak it should not need to be based on the HttpClientFactory but it could be a
DelegatingHandler
and aMiddleware
to initialize the state.Current Plan
DelegatingHandler
with a initializer middleware, locking the access to the Context if needed, similar to https://github.com/Microsoft/ApplicationInsights-aspnetcore/issues/373Original description
I believe it is a common use case which deserves to be included in the
Extensions
namespace, so I'd like to help to land this feature. Its main use case is probably to track distributed transaction which requires the ability to pass through a transaction identifier as well as generating a new one when not present.The code is loosely based on this gist from @davidfowl with some extra features and a different behaviour as, by default, this PR doesn't add the header if it's already present in the
HttpRequestMessage
.Features:
HttpClient
requests, allowing to use a different header name. The header is forwarded only if present and all values are used.HttpRequestMessage
(AlwaysAdd=true
) or only when the header is not already present (default).HttpRequestMessage
if the incoming request does not contain the headerHttpRequestMessage
if the incoming request does not contain the header. The generator can rely on theHttpRequestMessage
orHttpContext
to decide the value. (note: in my mind the use case is to generate a new GUID/identifier for a transaction chain if it's not in the incoming request, I'm not sure if having access to the request and context add any value)The tests should clarify the behaviour if needed.
It definitely needs some polishing on the definition of the configuration as well as probably removing some of the different behaviours, however I believe opening a PR is the best way to move forward the discussion and shape the behaviour.
Probably the discussion on the requirements should stay on the issue to keep the focus of the discussion here on the implementation.
Please Note:
up-for-grabs
I really appreciate you taking the time to review this PR.
Thanks,
Alessio