Skip to content
This repository has been archived by the owner on Jul 5, 2020. It is now read-only.

Fix dependency tracking if non-zero length response was cached by PropertyFetcher before #919

Merged
merged 3 commits into from
May 29, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down Expand Up @@ -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))
{
Expand Down Expand Up @@ -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))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ internal class HttpDesktopDiagnosticSourceListener : IObserver<KeyValuePair<stri
private readonly PropertyFetcher requestFetcherRequestEvent;
private readonly PropertyFetcher requestFetcherResponseEvent;
private readonly PropertyFetcher responseFetcher;
private readonly PropertyFetcher responseStatusFetcher;
private readonly PropertyFetcher responseHeadersFetcher;
private readonly PropertyFetcher requestFetcherResponseExEvent;
private readonly PropertyFetcher responseExStatusFetcher;
private readonly PropertyFetcher responseExHeadersFetcher;

private bool disposed = false;

Expand All @@ -29,8 +30,10 @@ internal HttpDesktopDiagnosticSourceListener(DesktopDiagnosticSourceHttpProcessi
this.requestFetcherRequestEvent = new PropertyFetcher("Request");
this.requestFetcherResponseEvent = new PropertyFetcher("Request");
this.responseFetcher = new PropertyFetcher("Response");
this.responseStatusFetcher = new PropertyFetcher("StatusCode");
this.responseHeadersFetcher = new PropertyFetcher("Headers");

this.requestFetcherResponseExEvent = new PropertyFetcher("Request");
this.responseExStatusFetcher = new PropertyFetcher("StatusCode");
this.responseExHeadersFetcher = new PropertyFetcher("Headers");
}

/// <summary>
Expand Down Expand Up @@ -77,10 +80,10 @@ public void OnNext(KeyValuePair<string, object> 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;
}
Expand Down