-
Notifications
You must be signed in to change notification settings - Fork 4
Description
When using the standard resilience handler in Microsoft.Extensions.Http.Resilience, the retry logic reuses the same HttpRequestMessage instance for multiple requests. This causes an issue where the signature header is added twice.
var services = new ServiceCollection();
services.AddHttpClient("client name")
.ConfigurePrimaryHttpMessageHandler(sp =>
{
var signatureAlgorithm = SignatureAlgorithm.Create(rsaOrECDsaAlgorithm);
var config = new HttpMessageSigningConfiguration("key-id", signatureAlgorithm);
return new SigningHttpMessageHandler(config);
})
.AddStandardResilienceHandler();
var serviceProvider => services.BuildServiceProvider();
var client = serviceProvider.GetRequiredService<IHttpClientFactory>().CreateClient("client name");
// Make requests using client.
// If a retry is triggered the "Signature" header will have one additional value for each retry attempt.The cause for this is this line:
HttpMessageSigning/src/IdentityStream.HttpMessageSigning/Extensions/HttpRequestMessageExtensions.cs
Lines 32 to 33 in e375fca
| public void SetHeader(string name, string value) => | |
| Request.Headers.TryAddWithoutValidation(name, value); |
The SetHeader method uses TryAddWithoutValidation(name, value), which adds the new value to the list of header values already present for that header.
It looks like the WcfHttpRequestMessage implementation is not affected, as the WebHeaderCollection.Set(name, value) method used replaces any existing value.
This change would change the behaviour to replace the existing value if there is one:
- public void SetHeader(string name, string value) =>
- Request.Headers.TryAddWithoutValidation(name, value);
+ public void SetHeader(string name, string value)
+ {
+ if (Request.Headers.Contains(name))
+ {
+ Request.Headers.Remove(name);
+ }
+
+ Request.Headers.TryAddWithoutValidation(name, value);
+ }