diff --git a/docs/docfx/articles/config-files.md b/docs/docfx/articles/config-files.md index debfd51fb..63447ee65 100644 --- a/docs/docfx/articles/config-files.md +++ b/docs/docfx/articles/config-files.md @@ -191,7 +191,6 @@ For additional fields see [ClusterConfig](xref:Yarp.ReverseProxy.Configuration.C "SSLProtocols" : "Tls13", "DangerousAcceptAnyServerCertificate" : false, "MaxConnectionsPerServer" : 1024, - "ActivityContextHeaders" : "None", // Or "Baggage", "CorrelationContext", "BaggageAndCorrelationContext" "EnableMultipleHttp2Connections" : true, "RequestHeaderEncoding" : "Latin1" // How to interpret non ASCII characters in header values }, diff --git a/samples/ReverseProxy.Config.Sample/appsettings.json b/samples/ReverseProxy.Config.Sample/appsettings.json index 4b9ddb635..4afbb1c1f 100644 --- a/samples/ReverseProxy.Config.Sample/appsettings.json +++ b/samples/ReverseProxy.Config.Sample/appsettings.json @@ -122,7 +122,6 @@ }, */ "MaxConnectionsPerServer": 1024, // Destination server can further limit this number - "ActivityContextHeaders": "None", // Or "Baggage", "CorrelationContext", "BaggageAndCorrelationContext" "EnableMultipleHttp2Connections": true, "RequestHeaderEncoding": "Latin1" // How to interpret non ASCII characters in header values }, diff --git a/src/ReverseProxy/Configuration/ActivityContextHeaders.cs b/src/ReverseProxy/Configuration/ActivityContextHeaders.cs deleted file mode 100644 index 9396e6490..000000000 --- a/src/ReverseProxy/Configuration/ActivityContextHeaders.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; - -namespace Yarp.ReverseProxy.Configuration -{ - [Flags] - public enum ActivityContextHeaders - { - None = 0, - Baggage = 1, - CorrelationContext = 2, - BaggageAndCorrelationContext = Baggage | CorrelationContext - } -} diff --git a/src/ReverseProxy/Configuration/ConfigProvider/ConfigurationConfigProvider.cs b/src/ReverseProxy/Configuration/ConfigProvider/ConfigurationConfigProvider.cs index a4bfb7ac0..0d777c957 100644 --- a/src/ReverseProxy/Configuration/ConfigProvider/ConfigurationConfigProvider.cs +++ b/src/ReverseProxy/Configuration/ConfigProvider/ConfigurationConfigProvider.cs @@ -348,7 +348,6 @@ private static RouteQueryParameter CreateRouteQueryParameter(IConfigurationSecti EnableMultipleHttp2Connections = section.ReadBool(nameof(HttpClientConfig.EnableMultipleHttp2Connections)), RequestHeaderEncoding = section[nameof(HttpClientConfig.RequestHeaderEncoding)], #endif - ActivityContextHeaders = section.ReadEnum(nameof(HttpClientConfig.ActivityContextHeaders)), WebProxy = webProxy }; } diff --git a/src/ReverseProxy/Configuration/HttpClientConfig.cs b/src/ReverseProxy/Configuration/HttpClientConfig.cs index ca587b3bb..25d1e84ba 100644 --- a/src/ReverseProxy/Configuration/HttpClientConfig.cs +++ b/src/ReverseProxy/Configuration/HttpClientConfig.cs @@ -32,11 +32,6 @@ public sealed record HttpClientConfig /// public int? MaxConnectionsPerServer { get; init; } - /// - /// Specifies the activity correlation headers for outgoing requests. - /// - public ActivityContextHeaders? ActivityContextHeaders { get; init; } - /// /// Optional web proxy used when communicating with the destination server. /// @@ -71,7 +66,6 @@ public bool Equals(HttpClientConfig? other) // Comparing by reference is fine here since Encoding.GetEncoding returns the same instance for each encoding. && RequestHeaderEncoding == other.RequestHeaderEncoding #endif - && ActivityContextHeaders == other.ActivityContextHeaders && WebProxy == other.WebProxy; } @@ -84,7 +78,6 @@ public override int GetHashCode() EnableMultipleHttp2Connections, RequestHeaderEncoding, #endif - ActivityContextHeaders, WebProxy); } } diff --git a/src/ReverseProxy/Forwarder/ActivityPropagationHandler.cs b/src/ReverseProxy/Forwarder/ActivityPropagationHandler.cs deleted file mode 100644 index e39a2ad48..000000000 --- a/src/ReverseProxy/Forwarder/ActivityPropagationHandler.cs +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Threading; -using System.Threading.Tasks; -using Yarp.ReverseProxy.Configuration; - -namespace Yarp.ReverseProxy.Forwarder -{ - /// - /// ActivityPropagationHandler propagates the current Activity to the downstream service - /// - public sealed class ActivityPropagationHandler : DelegatingHandler - { - private const string RequestIdHeaderName = "Request-Id"; - private const string CorrelationContextHeaderName = "Correlation-Context"; - private const string BaggageHeaderName = "baggage"; - - private const string TraceParentHeaderName = "traceparent"; - private const string TraceStateHeaderName = "tracestate"; - - private readonly ActivityContextHeaders _activityContextHeaders; - - public ActivityPropagationHandler(ActivityContextHeaders activityContextHeaders, HttpMessageHandler innerHandler) : base(innerHandler) - { - _activityContextHeaders = activityContextHeaders; - } - - protected override Task SendAsync(HttpRequestMessage request, - CancellationToken cancellationToken) - { - // This handler is conditionally inserted by the ProxyHttpClientFactory based on the configuration - // If inserted it will insert the necessary headers to propagate the current activity context to - // the downstream service, if there is a current activity - - if (request == null) - { - throw new ArgumentNullException(nameof(request)); - } - - // If we are on at all, we propagate current activity information - var currentActivity = Activity.Current; - if (currentActivity != null) - { - InjectHeaders(currentActivity, request); - } - - return base.SendAsync(request, cancellationToken); - } - - private void InjectHeaders(Activity currentActivity, HttpRequestMessage request) - { - if (currentActivity.IdFormat == ActivityIdFormat.W3C) - { - request.Headers.Remove(TraceParentHeaderName); - request.Headers.Remove(TraceStateHeaderName); - - request.Headers.TryAddWithoutValidation(TraceParentHeaderName, currentActivity.Id); - if (currentActivity.TraceStateString != null) - { - request.Headers.TryAddWithoutValidation(TraceStateHeaderName, currentActivity.TraceStateString); - } - } - else - { - request.Headers.Remove(RequestIdHeaderName); - request.Headers.TryAddWithoutValidation(RequestIdHeaderName, currentActivity.Id); - } - - // we expect baggage to be empty or contain a few items - using (var e = currentActivity.Baggage.GetEnumerator()) - { - if (e.MoveNext()) - { - var baggage = new List(); - do - { - var item = e.Current; - baggage.Add(new NameValueHeaderValue(Uri.EscapeDataString(item.Key), Uri.EscapeDataString(item.Value ?? string.Empty)).ToString()); - } - while (e.MoveNext()); - if (_activityContextHeaders.HasFlag(ActivityContextHeaders.Baggage)) - { - request.Headers.TryAddWithoutValidation(BaggageHeaderName, baggage); - } - if (_activityContextHeaders.HasFlag(ActivityContextHeaders.CorrelationContext)) - { - request.Headers.TryAddWithoutValidation(CorrelationContextHeaderName, baggage); - } - } - } - } - } -} diff --git a/src/ReverseProxy/Forwarder/ForwarderHttpClientFactory.cs b/src/ReverseProxy/Forwarder/ForwarderHttpClientFactory.cs index 320008dce..6ee6d78b4 100644 --- a/src/ReverseProxy/Forwarder/ForwarderHttpClientFactory.cs +++ b/src/ReverseProxy/Forwarder/ForwarderHttpClientFactory.cs @@ -124,16 +124,9 @@ protected virtual void ConfigureHandler(ForwarderHttpClientContext context, Sock /// /// Adds any wrapping middleware around the . - /// The base implementation conditionally includes the . /// protected virtual HttpMessageHandler WrapHandler(ForwarderHttpClientContext context, HttpMessageHandler handler) { - var activityContextHeaders = context.NewConfig.ActivityContextHeaders.GetValueOrDefault(ActivityContextHeaders.CorrelationContext); - if (activityContextHeaders != ActivityContextHeaders.None) - { - handler = new ActivityPropagationHandler(activityContextHeaders, handler); - } - return handler; } diff --git a/src/ReverseProxy/Forwarder/RequestUtilities.cs b/src/ReverseProxy/Forwarder/RequestUtilities.cs index 6563d67dc..82ba5fb2e 100644 --- a/src/ReverseProxy/Forwarder/RequestUtilities.cs +++ b/src/ReverseProxy/Forwarder/RequestUtilities.cs @@ -59,7 +59,7 @@ internal static bool ShouldSkipResponseHeader(string headerName) return _headersToExclude.Contains(headerName); } - private static readonly HashSet _headersToExclude = new(17, StringComparer.OrdinalIgnoreCase) + private static readonly HashSet _headersToExclude = new(22, StringComparer.OrdinalIgnoreCase) { HeaderNames.Connection, HeaderNames.TransferEncoding, @@ -75,7 +75,7 @@ internal static bool ShouldSkipResponseHeader(string headerName) "ALPN", "Close", "HTTP2-Settings", - "Upgrade-Insecure-Requests", + HeaderNames.UpgradeInsecureRequests, HeaderNames.TE, #if NET HeaderNames.AltSvc, @@ -83,6 +83,14 @@ internal static bool ShouldSkipResponseHeader(string headerName) "Alt-Svc", #endif +#if NET6_0_OR_GREATER + // Distributed context headers + HeaderNames.TraceParent, + HeaderNames.RequestId, + HeaderNames.TraceState, + HeaderNames.Baggage, + HeaderNames.CorrelationContext, +#endif }; // Headers marked as HttpHeaderType.Content in diff --git a/src/ServiceFabric/ServiceDiscovery/Util/LabelsParser.cs b/src/ServiceFabric/ServiceDiscovery/Util/LabelsParser.cs index 286a8fc14..7fa65ccf3 100644 --- a/src/ServiceFabric/ServiceDiscovery/Util/LabelsParser.cs +++ b/src/ServiceFabric/ServiceDiscovery/Util/LabelsParser.cs @@ -268,7 +268,6 @@ internal static ClusterConfig BuildCluster(Uri serviceName, Dictionary(labels, "YARP.Backend.HttpRequest.Version", null); - var activityContextHeadersLabel = GetLabel(labels, "YARP.Backend.HttpClient.ActivityContextHeaders", null); var sslProtocolsLabel = GetLabel(labels, "YARP.Backend.HttpClient.SslProtocols", null); #if NET @@ -328,7 +327,6 @@ internal static ClusterConfig BuildCluster(Uri serviceName, Dictionary(labels, "YARP.Backend.HttpClient.DangerousAcceptAnyServerCertificate", null), MaxConnectionsPerServer = GetLabel(labels, "YARP.Backend.HttpClient.MaxConnectionsPerServer", null), - ActivityContextHeaders = !string.IsNullOrEmpty(activityContextHeadersLabel) ? Enum.Parse(activityContextHeadersLabel) : null, SslProtocols = !string.IsNullOrEmpty(sslProtocolsLabel) ? Enum.Parse(sslProtocolsLabel) : null, #if NET EnableMultipleHttp2Connections = GetLabel(labels, "YARP.Backend.HttpClient.EnableMultipleHttp2Connections", null), diff --git a/test/ReverseProxy.FunctionalTests/Common/TestEnvironment.cs b/test/ReverseProxy.FunctionalTests/Common/TestEnvironment.cs index de65bfbdf..2f306bae0 100644 --- a/test/ReverseProxy.FunctionalTests/Common/TestEnvironment.cs +++ b/test/ReverseProxy.FunctionalTests/Common/TestEnvironment.cs @@ -15,6 +15,8 @@ using Microsoft.Extensions.Hosting; using Yarp.Tests.Common; using Yarp.ReverseProxy.Configuration; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Configuration; namespace Yarp.ReverseProxy.Common { @@ -142,6 +144,18 @@ private static IHost CreateHost(HttpProtocols protocols, bool useHttps, Encoding Action configureServices, Action configureApp) { return new HostBuilder() + .ConfigureAppConfiguration(config => + { + config.AddInMemoryCollection(new Dictionary() + { + { "Logging:LogLevel:Microsoft.AspNetCore.Hosting.Diagnostics", "Information" } + }); + }) + .ConfigureLogging((hostingContext, loggingBuilder) => + { + loggingBuilder.AddConfiguration(hostingContext.Configuration.GetSection("Logging")); + loggingBuilder.AddEventSourceLogger(); + }) .ConfigureWebHost(webHostBuilder => { webHostBuilder diff --git a/test/ReverseProxy.FunctionalTests/DistributedTracingTests.cs b/test/ReverseProxy.FunctionalTests/DistributedTracingTests.cs new file mode 100644 index 000000000..4b704e9ea --- /dev/null +++ b/test/ReverseProxy.FunctionalTests/DistributedTracingTests.cs @@ -0,0 +1,127 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System.Diagnostics; +using System.Linq; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Xunit; +using Yarp.ReverseProxy.Common; + +namespace Yarp.ReverseProxy +{ + public class DistributedTracingTests + { + // These constants depend on the default behavior of DiagnosticsHandler in 5.0 + // and the DistributedContextPropagator used in 6.0 + private const string Baggage = "Correlation-Context"; + private const string TraceParent = "traceparent"; + private const string TraceState = "tracestate"; + private const string RequestId = "Request-Id"; + + [Theory] + [InlineData(ActivityIdFormat.W3C)] + [InlineData(ActivityIdFormat.Hierarchical)] + public async Task DistributedTracing_Works(ActivityIdFormat idFormat) + { + var proxyHeaders = new HeaderDictionary(); + var downstreamHeaders = new HeaderDictionary(); + + var test = new TestEnvironment( + async context => + { + foreach (var header in context.Request.Headers) + { + downstreamHeaders.Add(header); + } + await context.Response.Body.WriteAsync(Encoding.UTF8.GetBytes("Hello")); + }, + proxyBuilder => { }, + proxyApp => + { + proxyApp.Use(next => context => + { + foreach (var header in context.Request.Headers) + { + proxyHeaders.Add(header); + } + return next(context); + }); + }); + + var clientActivity = new Activity("Foo"); + clientActivity.SetIdFormat(idFormat); + clientActivity.TraceStateString = "Bar"; + clientActivity.AddBaggage("One", "1"); + clientActivity.AddBaggage("Two", "2"); + clientActivity.Start(); + + await test.Invoke(async uri => + { + using var client = new HttpClient(); + Assert.Equal("Hello", await client.GetStringAsync(uri)); + }); + + Assert.NotEmpty(proxyHeaders); + Assert.NotEmpty(downstreamHeaders); + + ValidateActivities(idFormat, clientActivity, proxyHeaders, downstreamHeaders); + } + + private static void ValidateActivities(ActivityIdFormat idFormat, Activity client, HeaderDictionary proxy, HeaderDictionary downstream) + { + var baggage = string.Join(", ", client.Baggage.Select(pair => $"{pair.Key}={pair.Value}")); + Assert.Equal(baggage, proxy[Baggage]); + Assert.Equal(baggage, downstream[Baggage]); + + if (idFormat == ActivityIdFormat.W3C) + { +#if NET + Assert.True(ActivityContext.TryParse(proxy[TraceParent], proxy[TraceState], out var proxyContext)); + Assert.True(ActivityContext.TryParse(downstream[TraceParent], downstream[TraceState], out var downstreamContext)); + Assert.Equal(client.TraceStateString, proxyContext.TraceState); + Assert.Equal(client.TraceStateString, downstreamContext.TraceState); + var proxyTraceId = proxyContext.TraceId.ToHexString(); + var proxySpanId = proxyContext.SpanId.ToHexString(); + var downstreamTraceId = downstreamContext.TraceId.ToHexString(); + var downstreamSpanId = downstreamContext.SpanId.ToHexString(); +#else + // 3.1 does not have ActivityContext + Assert.Equal(client.TraceStateString, proxy[TraceState]); + Assert.Equal(client.TraceStateString, downstream[TraceState]); + var proxyTraceId = proxy[TraceParent].ToString().Split('-')[1]; + var proxySpanId = proxy[TraceParent].ToString().Split('-')[2]; + var downstreamTraceId = downstream[TraceParent].ToString().Split('-')[1]; + var downstreamSpanId = downstream[TraceParent].ToString().Split('-')[2]; +#endif + + Assert.Equal(client.TraceId.ToHexString(), proxyTraceId); + Assert.Equal(client.TraceId.ToHexString(), downstreamTraceId); + +#if NET6_0_OR_GREATER + Assert.NotEqual(proxySpanId, downstreamSpanId); +#else + // Before 6.0, YARP is just pass-through as far as distributed tracing is concerned + Assert.Equal(proxySpanId, downstreamSpanId); +#endif + } + else + { + var proxyId = proxy[RequestId].ToString(); + var downstreamId = downstream[RequestId].ToString(); + + Assert.StartsWith(client.Id, proxyId); + Assert.StartsWith(proxyId, downstreamId); + +#if NET6_0_OR_GREATER + Assert.NotEqual(proxyId, downstreamId); +#else + // Before 6.0, YARP is just pass-through as far as distributed tracing is concerned + Assert.Equal(proxyId, downstreamId); +#endif + } + } + } +} diff --git a/test/ReverseProxy.Tests/Configuration/ClusterConfigTests.cs b/test/ReverseProxy.Tests/Configuration/ClusterConfigTests.cs index 135563074..af18e2018 100644 --- a/test/ReverseProxy.Tests/Configuration/ClusterConfigTests.cs +++ b/test/ReverseProxy.Tests/Configuration/ClusterConfigTests.cs @@ -85,7 +85,6 @@ public void Equals_Same_Value_Returns_True() SslProtocols = SslProtocols.Tls11 | SslProtocols.Tls12, MaxConnectionsPerServer = 10, DangerousAcceptAnyServerCertificate = true, - ActivityContextHeaders = ActivityContextHeaders.CorrelationContext, #if NET RequestHeaderEncoding = Encoding.UTF8.WebName #endif @@ -166,7 +165,6 @@ public void Equals_Same_Value_Returns_True() SslProtocols = SslProtocols.Tls11 | SslProtocols.Tls12, MaxConnectionsPerServer = 10, DangerousAcceptAnyServerCertificate = true, - ActivityContextHeaders = ActivityContextHeaders.CorrelationContext, #if NET RequestHeaderEncoding = Encoding.UTF8.WebName #endif @@ -258,7 +256,6 @@ public void Equals_Different_Value_Returns_False() SslProtocols = SslProtocols.Tls11 | SslProtocols.Tls12, MaxConnectionsPerServer = 10, DangerousAcceptAnyServerCertificate = true, - ActivityContextHeaders = ActivityContextHeaders.CorrelationContext, }, HttpRequest = new ForwarderRequestConfig { @@ -303,7 +300,6 @@ public void Equals_Different_Value_Returns_False() SslProtocols = SslProtocols.Tls12, MaxConnectionsPerServer = 10, DangerousAcceptAnyServerCertificate = true, - ActivityContextHeaders = ActivityContextHeaders.CorrelationContext, } })); Assert.False(config1.Equals(config1 with { HttpRequest = new ForwarderRequestConfig() { } })); @@ -370,7 +366,6 @@ public void Cluster_CanBeJsonSerialized() SslProtocols = SslProtocols.Tls11 | SslProtocols.Tls12, MaxConnectionsPerServer = 10, DangerousAcceptAnyServerCertificate = true, - ActivityContextHeaders = ActivityContextHeaders.CorrelationContext, WebProxy = new WebProxyConfig { Address = new Uri("http://proxy"), diff --git a/test/ReverseProxy.Tests/Configuration/ConfigProvider/ConfigurationConfigProviderTests.cs b/test/ReverseProxy.Tests/Configuration/ConfigProvider/ConfigurationConfigProviderTests.cs index 7e74f4185..c174c1b38 100644 --- a/test/ReverseProxy.Tests/Configuration/ConfigProvider/ConfigurationConfigProviderTests.cs +++ b/test/ReverseProxy.Tests/Configuration/ConfigProvider/ConfigurationConfigProviderTests.cs @@ -95,7 +95,6 @@ public class ConfigurationConfigProviderTests SslProtocols = SslProtocols.Tls11 | SslProtocols.Tls12, MaxConnectionsPerServer = 10, DangerousAcceptAnyServerCertificate = true, - ActivityContextHeaders = ActivityContextHeaders.Baggage, #if NET EnableMultipleHttp2Connections = true, #endif @@ -245,7 +244,6 @@ public class ConfigurationConfigProviderTests ""DangerousAcceptAnyServerCertificate"": true, ""MaxConnectionsPerServer"": 10, ""EnableMultipleHttp2Connections"": true, - ""ActivityContextHeaders"": ""Baggage"", ""RequestHeaderEncoding"": ""utf-8"", ""WebProxy"": { ""Address"": ""http://localhost:8080"", @@ -538,7 +536,6 @@ private void VerifyValidAbstractConfig(IProxyConfig validConfig, IProxyConfig ab Assert.Equal(cluster1.HttpClient.EnableMultipleHttp2Connections, abstractCluster1.HttpClient.EnableMultipleHttp2Connections); Assert.Equal(Encoding.UTF8.WebName, abstractCluster1.HttpClient.RequestHeaderEncoding); #endif - Assert.Equal(cluster1.HttpClient.ActivityContextHeaders, abstractCluster1.HttpClient.ActivityContextHeaders); Assert.Equal(SslProtocols.Tls11 | SslProtocols.Tls12, abstractCluster1.HttpClient.SslProtocols); Assert.Equal(cluster1.HttpRequest.ActivityTimeout, abstractCluster1.HttpRequest.ActivityTimeout); Assert.Equal(HttpVersion.Version10, abstractCluster1.HttpRequest.Version); diff --git a/test/ReverseProxy.Tests/Forwarder/ActivityPropagationHandlerTests.cs b/test/ReverseProxy.Tests/Forwarder/ActivityPropagationHandlerTests.cs deleted file mode 100644 index 610343afc..000000000 --- a/test/ReverseProxy.Tests/Forwarder/ActivityPropagationHandlerTests.cs +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System.Diagnostics; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; -using Xunit; -using Yarp.Tests.Common; -using Yarp.ReverseProxy.Configuration; - -namespace Yarp.ReverseProxy.Forwarder.Tests -{ - public class ActivityPropagationHandlerTests - { - [Theory] - [InlineData(false, ActivityContextHeaders.BaggageAndCorrelationContext)] - [InlineData(true, ActivityContextHeaders.BaggageAndCorrelationContext)] - [InlineData(true, ActivityContextHeaders.Baggage)] - [InlineData(true, ActivityContextHeaders.CorrelationContext)] - public async Task SendAsync_CurrentActivitySet_RequestHeadersSet(bool useW3CFormat, ActivityContextHeaders activityContextHeaders) - { - const string TraceStateString = "CustomTraceStateString"; - string expectedId = null; - - var invoker = new HttpMessageInvoker(new ActivityPropagationHandler(activityContextHeaders, new MockHttpHandler( - (HttpRequestMessage request, CancellationToken cancellationToken) => - { - var headers = request.Headers; - - Assert.True(headers.TryGetValues(useW3CFormat ? "traceparent" : "Request-Id", out var values)); - Assert.Equal(expectedId, Assert.Single(values)); - - if (useW3CFormat) - { - Assert.True(headers.TryGetValues("tracestate", out values)); - Assert.Equal(TraceStateString, Assert.Single(values)); - } - - if (activityContextHeaders.HasFlag(ActivityContextHeaders.Baggage)) - { - Assert.True(headers.TryGetValues("Baggage", out values)); - Assert.Equal("foo=bar", Assert.Single(values)); - } - - if (activityContextHeaders.HasFlag(ActivityContextHeaders.CorrelationContext)) - { - Assert.True(headers.TryGetValues("Correlation-Context", out values)); - Assert.Equal("foo=bar", Assert.Single(values)); - } - - return Task.FromResult(null); - }))); - - var activity = new Activity("CustomOperation"); - - if (useW3CFormat) - { - activity.SetIdFormat(ActivityIdFormat.W3C); - activity.TraceStateString = TraceStateString; - activity.SetParentId("00-01234567890123456789012345678901-0123456789012345-01"); - } - else - { - activity.SetIdFormat(ActivityIdFormat.Hierarchical); - activity.SetParentId("|root"); - } - - activity.AddBaggage("foo", "bar"); - - activity.Start(); - expectedId = activity.Id; - - await invoker.SendAsync(new HttpRequestMessage(), CancellationToken.None); - - activity.Stop(); - } - } -} diff --git a/test/ReverseProxy.Tests/Forwarder/ForwarderHttpClientFactoryTests.cs b/test/ReverseProxy.Tests/Forwarder/ForwarderHttpClientFactoryTests.cs index 1577097cd..350cc2e25 100644 --- a/test/ReverseProxy.Tests/Forwarder/ForwarderHttpClientFactoryTests.cs +++ b/test/ReverseProxy.Tests/Forwarder/ForwarderHttpClientFactoryTests.cs @@ -90,18 +90,6 @@ public void CreateClient_ApplyMaxConnectionsPerServer_Success() VerifyDefaultValues(handler, "MaxConnectionsPerServer"); } - [Fact] - public void CreateClient_ApplyPropagateActivityContext_Success() - { - var factory = new ForwarderHttpClientFactory(Mock>().Object); - var options = new HttpClientConfig { ActivityContextHeaders = ActivityContextHeaders.None }; - var client = factory.CreateClient(new ForwarderHttpClientContext { NewConfig = options }); - - var handler = GetHandler(client, expectActivityPropagationHandler: false); - - Assert.NotNull(handler); - } - [Fact] public void CreateClient_ApplyWebProxy_Success() { @@ -153,7 +141,6 @@ public void CreateClient_OldClientExistsNoConfigChange_ReturnsOldInstance() SslProtocols = SslProtocols.Tls11 | SslProtocols.Tls12, DangerousAcceptAnyServerCertificate = true, MaxConnectionsPerServer = 10, - ActivityContextHeaders = ActivityContextHeaders.CorrelationContext, #if NET RequestHeaderEncoding = Encoding.Latin1.WebName, #endif @@ -209,14 +196,12 @@ public static IEnumerable GetChangedHttpClientOptions() SslProtocols = SslProtocols.Tls11, DangerousAcceptAnyServerCertificate = true, MaxConnectionsPerServer = null, - ActivityContextHeaders = ActivityContextHeaders.None, }, new HttpClientConfig { SslProtocols = SslProtocols.Tls11 | SslProtocols.Tls12, DangerousAcceptAnyServerCertificate = true, MaxConnectionsPerServer = null, - ActivityContextHeaders = ActivityContextHeaders.None, }, }, new object[] { @@ -225,14 +210,12 @@ public static IEnumerable GetChangedHttpClientOptions() SslProtocols = SslProtocols.Tls11, DangerousAcceptAnyServerCertificate = true, MaxConnectionsPerServer = null, - ActivityContextHeaders = ActivityContextHeaders.None, }, new HttpClientConfig { SslProtocols = SslProtocols.Tls11, DangerousAcceptAnyServerCertificate = false, MaxConnectionsPerServer = null, - ActivityContextHeaders = ActivityContextHeaders.None, }, }, new object[] { @@ -241,14 +224,12 @@ public static IEnumerable GetChangedHttpClientOptions() SslProtocols = SslProtocols.Tls11, DangerousAcceptAnyServerCertificate = true, MaxConnectionsPerServer = null, - ActivityContextHeaders = ActivityContextHeaders.None, }, new HttpClientConfig { SslProtocols = SslProtocols.Tls11, DangerousAcceptAnyServerCertificate = false, MaxConnectionsPerServer = null, - ActivityContextHeaders = ActivityContextHeaders.None, }, }, new object[] { @@ -257,14 +238,12 @@ public static IEnumerable GetChangedHttpClientOptions() SslProtocols = SslProtocols.Tls11, DangerousAcceptAnyServerCertificate = true, MaxConnectionsPerServer = null, - ActivityContextHeaders = ActivityContextHeaders.None, }, new HttpClientConfig { SslProtocols = SslProtocols.Tls11, DangerousAcceptAnyServerCertificate = false, MaxConnectionsPerServer = null, - ActivityContextHeaders = ActivityContextHeaders.None, }, }, new object[] { @@ -273,14 +252,12 @@ public static IEnumerable GetChangedHttpClientOptions() SslProtocols = SslProtocols.Tls11, DangerousAcceptAnyServerCertificate = true, MaxConnectionsPerServer = null, - ActivityContextHeaders = ActivityContextHeaders.None, }, new HttpClientConfig { SslProtocols = SslProtocols.Tls11, DangerousAcceptAnyServerCertificate = true, MaxConnectionsPerServer = 10, - ActivityContextHeaders = ActivityContextHeaders.None, }, }, new object[] { @@ -289,14 +266,12 @@ public static IEnumerable GetChangedHttpClientOptions() SslProtocols = SslProtocols.Tls11, DangerousAcceptAnyServerCertificate = true, MaxConnectionsPerServer = 10, - ActivityContextHeaders = ActivityContextHeaders.None, }, new HttpClientConfig { SslProtocols = SslProtocols.Tls11, DangerousAcceptAnyServerCertificate = true, MaxConnectionsPerServer = null, - ActivityContextHeaders = ActivityContextHeaders.None, }, }, new object[] { @@ -305,62 +280,12 @@ public static IEnumerable GetChangedHttpClientOptions() SslProtocols = SslProtocols.Tls11, DangerousAcceptAnyServerCertificate = true, MaxConnectionsPerServer = 10, - ActivityContextHeaders = ActivityContextHeaders.None, }, new HttpClientConfig { SslProtocols = SslProtocols.Tls11, DangerousAcceptAnyServerCertificate = true, MaxConnectionsPerServer = 20, - ActivityContextHeaders = ActivityContextHeaders.None, - }, - }, - new object[] { - new HttpClientConfig - { - SslProtocols = SslProtocols.Tls11, - DangerousAcceptAnyServerCertificate = true, - MaxConnectionsPerServer = 10, - ActivityContextHeaders = ActivityContextHeaders.CorrelationContext, - }, - new HttpClientConfig - { - SslProtocols = SslProtocols.Tls11, - DangerousAcceptAnyServerCertificate = true, - MaxConnectionsPerServer = 10, - ActivityContextHeaders = ActivityContextHeaders.None, - }, - }, - new object[] { - new HttpClientConfig - { - SslProtocols = SslProtocols.Tls11, - DangerousAcceptAnyServerCertificate = true, - MaxConnectionsPerServer = 10, - ActivityContextHeaders = ActivityContextHeaders.Baggage, - }, - new HttpClientConfig - { - SslProtocols = SslProtocols.Tls11, - DangerousAcceptAnyServerCertificate = true, - MaxConnectionsPerServer = 10, - ActivityContextHeaders = ActivityContextHeaders.CorrelationContext, - }, - }, - new object[] { - new HttpClientConfig - { - SslProtocols = SslProtocols.Tls11, - DangerousAcceptAnyServerCertificate = true, - MaxConnectionsPerServer = 10, - ActivityContextHeaders = ActivityContextHeaders.CorrelationContext, - }, - new HttpClientConfig - { - SslProtocols = SslProtocols.Tls11, - DangerousAcceptAnyServerCertificate = true, - MaxConnectionsPerServer = 10, - ActivityContextHeaders = ActivityContextHeaders.BaggageAndCorrelationContext, }, }, #if NET @@ -370,7 +295,6 @@ public static IEnumerable GetChangedHttpClientOptions() SslProtocols = SslProtocols.Tls11, DangerousAcceptAnyServerCertificate = true, MaxConnectionsPerServer = 10, - ActivityContextHeaders = ActivityContextHeaders.Baggage, EnableMultipleHttp2Connections = true }, new HttpClientConfig @@ -378,7 +302,6 @@ public static IEnumerable GetChangedHttpClientOptions() SslProtocols = SslProtocols.Tls11, DangerousAcceptAnyServerCertificate = true, MaxConnectionsPerServer = 10, - ActivityContextHeaders = ActivityContextHeaders.Baggage, EnableMultipleHttp2Connections = false }, }, @@ -388,14 +311,12 @@ public static IEnumerable GetChangedHttpClientOptions() SslProtocols = SslProtocols.Tls11, DangerousAcceptAnyServerCertificate = true, MaxConnectionsPerServer = 10, - ActivityContextHeaders = ActivityContextHeaders.None, }, new HttpClientConfig { SslProtocols = SslProtocols.Tls11, DangerousAcceptAnyServerCertificate = true, MaxConnectionsPerServer = 10, - ActivityContextHeaders = ActivityContextHeaders.None, RequestHeaderEncoding = Encoding.UTF8.WebName, }, }, @@ -405,7 +326,6 @@ public static IEnumerable GetChangedHttpClientOptions() SslProtocols = SslProtocols.Tls11, DangerousAcceptAnyServerCertificate = true, MaxConnectionsPerServer = 10, - ActivityContextHeaders = ActivityContextHeaders.None, RequestHeaderEncoding = Encoding.UTF8.WebName, }, new HttpClientConfig @@ -413,7 +333,6 @@ public static IEnumerable GetChangedHttpClientOptions() SslProtocols = SslProtocols.Tls11, DangerousAcceptAnyServerCertificate = true, MaxConnectionsPerServer = 10, - ActivityContextHeaders = ActivityContextHeaders.None, RequestHeaderEncoding = Encoding.Latin1.WebName, }, } @@ -421,18 +340,10 @@ public static IEnumerable GetChangedHttpClientOptions() }; } - public static SocketsHttpHandler GetHandler(HttpMessageInvoker client, bool expectActivityPropagationHandler = true) + public static SocketsHttpHandler GetHandler(HttpMessageInvoker client) { var handlerFieldInfo = typeof(HttpMessageInvoker).GetFields(BindingFlags.Instance | BindingFlags.NonPublic).Single(f => f.Name == "_handler"); var handler = handlerFieldInfo.GetValue(client); - - if (handler is ActivityPropagationHandler diagnosticsHandler) - { - Assert.True(expectActivityPropagationHandler); - return (SocketsHttpHandler)diagnosticsHandler.InnerHandler; - } - - Assert.False(expectActivityPropagationHandler); return (SocketsHttpHandler)handler; } diff --git a/test/ReverseProxy.Tests/Forwarder/HttpForwarderTests.cs b/test/ReverseProxy.Tests/Forwarder/HttpForwarderTests.cs index 41de3a7af..8344b05ad 100644 --- a/test/ReverseProxy.Tests/Forwarder/HttpForwarderTests.cs +++ b/test/ReverseProxy.Tests/Forwarder/HttpForwarderTests.cs @@ -2101,8 +2101,13 @@ public static IEnumerable GetProhibitedHeaders() "TE: value", "HTTP2-Settings: value", "Upgrade-Insecure-Requests: value", -#if NET "Alt-Svc: value", +#if NET6_0_OR_GREATER + "traceparent: value", + "Request-Id: value", + "tracestate: value", + "baggage: value", + "Correlation-Context: value", #endif }; diff --git a/test/ReverseProxy.Tests/Forwarder/HttpTransformerTests.cs b/test/ReverseProxy.Tests/Forwarder/HttpTransformerTests.cs index 75bbd99ef..dbf506a20 100644 --- a/test/ReverseProxy.Tests/Forwarder/HttpTransformerTests.cs +++ b/test/ReverseProxy.Tests/Forwarder/HttpTransformerTests.cs @@ -15,6 +15,7 @@ public class HttpTransformerTests { private static readonly string[] RestrictedHeaders = new[] { + HeaderNames.Connection, HeaderNames.TransferEncoding, HeaderNames.KeepAlive, HeaderNames.Upgrade, @@ -28,12 +29,19 @@ public class HttpTransformerTests "ALPN", "Close", "HTTP2-Settings", - "Upgrade-Insecure-Requests", + HeaderNames.UpgradeInsecureRequests, HeaderNames.TE, #if NET HeaderNames.AltSvc, #else "Alt-Svc", +#endif +#if NET6_0_OR_GREATER + HeaderNames.TraceParent, + HeaderNames.RequestId, + HeaderNames.TraceState, + HeaderNames.Baggage, + HeaderNames.CorrelationContext, #endif }; diff --git a/test/ServiceFabric.Tests/ServiceDiscovery/Util/LabelsParserTests.cs b/test/ServiceFabric.Tests/ServiceDiscovery/Util/LabelsParserTests.cs index 9c459fa8c..6e8f6b8f3 100644 --- a/test/ServiceFabric.Tests/ServiceDiscovery/Util/LabelsParserTests.cs +++ b/test/ServiceFabric.Tests/ServiceDiscovery/Util/LabelsParserTests.cs @@ -56,7 +56,6 @@ public void BuildCluster_CompleteLabels_Works() { "YARP.Backend.HttpClient.DangerousAcceptAnyServerCertificate", "true" }, { "YARP.Backend.HttpClient.MaxConnectionsPerServer", "1000" }, { "YARP.Backend.HttpClient.SslProtocols", "Tls12" }, - { "YARP.Backend.HttpClient.ActivityContextHeaders", "BaggageAndCorrelationContext" }, #if NET { "YARP.Backend.HttpClient.EnableMultipleHttp2Connections", "false" }, { "YARP.Backend.HttpClient.RequestHeaderEncoding", "utf-8" }, @@ -122,7 +121,6 @@ public void BuildCluster_CompleteLabels_Works() }, HttpClient = new HttpClientConfig { - ActivityContextHeaders = ActivityContextHeaders.BaggageAndCorrelationContext, DangerousAcceptAnyServerCertificate = true, #if NET EnableMultipleHttp2Connections = false,