diff --git a/CHANGELOG.md b/CHANGELOG.md index 86bb6b7fe..dc96bfd71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - [Added support to collect Perf Counters for .NET Core Apps if running inside Azure WebApps](https://github.com/Microsoft/ApplicationInsights-dotnet-server/issues/889) - [Opt-in legacy correlation headers (x-ms-request-id and x-ms-request-root-id) extraction and injection](https://github.com/Microsoft/ApplicationInsights-dotnet-server/issues/887) - [Fix: Correlation is not working for POST requests](https://github.com/Microsoft/ApplicationInsights-dotnet-server/pull/898) when .NET 4.7.1 runtime is installed. +- [Fix: Tracking mixed HTTP responses with and without content](https://github.com/Microsoft/ApplicationInsights-dotnet-server/pull/919) ## Version 2.6.0-beta4 - [Remove CorrelationIdLookupHelper. Use TelemetryConfiguration.ApplicationIdProvider instead.](https://github.com/Microsoft/ApplicationInsights-dotnet-server/pull/880) With this change you can update URL to query application ID from which enables environments with reverse proxy configuration to access Application Insights ednpoints. diff --git a/Src/DependencyCollector/Net45.Tests/DependencyTrackingTelemetryModuleHttpTest.cs b/Src/DependencyCollector/Net45.Tests/DependencyTrackingTelemetryModuleHttpTest.cs index 6dc0c3af4..5eebcb362 100644 --- a/Src/DependencyCollector/Net45.Tests/DependencyTrackingTelemetryModuleHttpTest.cs +++ b/Src/DependencyCollector/Net45.Tests/DependencyTrackingTelemetryModuleHttpTest.cs @@ -96,7 +96,14 @@ public void TestBasicDependencyCollectionDiagnosticSourceLegacyHeaders() [Timeout(5000)] public async Task TestZeroContentResponseDiagnosticSource() { - await this.TestCollectionHttpClientSucessfulResponse(LocalhostUrlDiagSource, 200, 0); + await this.TestCollectionHttpClientSuccessfulResponse(LocalhostUrlDiagSource, 200, 0); + } + + [TestMethod] + [Timeout(5000)] + public async Task TestZeroAndNonZeroContentResponseDiagnosticSource() + { + await this.TestZeroContentResponseAfterNonZeroResponse(LocalhostUrlDiagSource, 200); } [TestMethod] @@ -379,7 +386,7 @@ private void TestCollectionSuccessfulResponse(bool enableDiagnosticSource, strin } } - private async Task TestCollectionHttpClientSucessfulResponse(string url, int statusCode, int contentLength, bool injectLegacyHeaders = false) + private async Task TestCollectionHttpClientSuccessfulResponse(string url, int statusCode, int contentLength, bool injectLegacyHeaders = false) { using (this.CreateDependencyTrackingModule(true)) { @@ -409,6 +416,62 @@ private async Task TestCollectionHttpClientSucessfulResponse(string url, int sta } } + private async Task TestZeroContentResponseAfterNonZeroResponse(string url, int statusCode) + { + using (this.CreateDependencyTrackingModule(true)) + { + using (HttpClient client = new HttpClient()) + { + using (new LocalServer( + url, + context => + { + context.Response.ContentLength64 = 1; + context.Response.StatusCode = statusCode; + context.Response.OutputStream.WriteByte(0x1); + context.Response.OutputStream.Close(); + })) + { + try + { + using (HttpResponseMessage response = await client.GetAsync(url)) + { + Assert.AreEqual(1, response.Content.Headers.ContentLength); + } + } + catch (WebException) + { + // ignore and let ValidateTelemetry method check status code + } + } + + using (new LocalServer( + url, + context => + { + context.Response.ContentLength64 = 0; + context.Response.StatusCode = statusCode; + })) + { + try + { + using (HttpResponseMessage response = await client.GetAsync(url)) + { + Assert.AreEqual(0, response.Content.Headers.ContentLength); + } + } + catch (WebException) + { + // ignore and let ValidateTelemetry method check status code + } + } + } + + Assert.AreEqual(2, this.sentTelemetry.Count); + this.ValidateTelemetry(true, this.sentTelemetry.Last(), new Uri(url), null, statusCode >= 200 && statusCode < 300, statusCode.ToString(CultureInfo.InvariantCulture)); + } + } + private async Task TestCollectionCanceledRequest(bool enableDiagnosticSource, string url) { using (this.CreateDependencyTrackingModule(enableDiagnosticSource)) diff --git a/Src/DependencyCollector/Shared/Implementation/HttpDesktopDiagnosticSourceListener.cs b/Src/DependencyCollector/Shared/Implementation/HttpDesktopDiagnosticSourceListener.cs index 455781ae7..3ef91aa2e 100644 --- a/Src/DependencyCollector/Shared/Implementation/HttpDesktopDiagnosticSourceListener.cs +++ b/Src/DependencyCollector/Shared/Implementation/HttpDesktopDiagnosticSourceListener.cs @@ -17,8 +17,9 @@ internal class HttpDesktopDiagnosticSourceListener : IObserver @@ -77,10 +80,10 @@ public void OnNext(KeyValuePair value) case "System.Net.Http.Desktop.HttpRequestOut.Ex.Stop": { // request is never null - var request = this.requestFetcherResponseEvent.Fetch(value.Value); + var request = this.requestFetcherResponseExEvent.Fetch(value.Value); DependencyCollectorEventSource.Log.HttpDesktopEndCallbackCalled(ClientServerDependencyTracker.GetIdForRequestObject(request)); - object statusCode = this.responseStatusFetcher.Fetch(value.Value); - object headers = this.responseHeadersFetcher.Fetch(value.Value); + object statusCode = this.responseExStatusFetcher.Fetch(value.Value); + object headers = this.responseExHeadersFetcher.Fetch(value.Value); this.httpDesktopProcessing.OnEndResponse(request, statusCode, headers); break; }