Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
using Datadog.Trace.Configuration;
using Datadog.Trace.HttpOverStreams;
using Datadog.Trace.Logging;
using Datadog.Trace.Vendors.Newtonsoft.Json;
using Datadog.Trace.Vendors.Newtonsoft.Json.Linq;

namespace Datadog.Trace.Agent.DiscoveryService
Expand Down Expand Up @@ -75,8 +74,7 @@ public async Task<bool> DiscoverAsync()
using var response = await api.GetAsync().ConfigureAwait(false);
if (response.StatusCode == 200)
{
var content = await response.ReadAsStringAsync().ConfigureAwait(false);
ProcessDiscoveryResponse(content);
await ProcessDiscoveryResponse(response).ConfigureAwait(false);

_cancellationSource = null;
return true;
Expand Down Expand Up @@ -104,9 +102,9 @@ public async Task<bool> DiscoverAsync()
return false;
}

private void ProcessDiscoveryResponse(string content)
private async Task ProcessDiscoveryResponse(IApiResponse response)
{
var jObject = JsonConvert.DeserializeObject<JObject>(content);
var jObject = await response.ReadAsTypeAsync<JObject>().ConfigureAwait(false);
AgentVersion = jObject["version"]?.Value<string>();

var discoveredEndpoints = (jObject["endpoints"] as JArray)?.Values<string>().ToArray();
Expand Down
29 changes: 28 additions & 1 deletion tracer/src/Datadog.Trace/Agent/IApiResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
// </copyright>

using System;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Datadog.Trace.Vendors.Newtonsoft.Json;

namespace Datadog.Trace.Agent
{
Expand All @@ -14,8 +17,32 @@ internal interface IApiResponse : IDisposable

long ContentLength { get; }

Encoding ContentEncoding { get; }

string GetHeader(string headerName);

Task<string> ReadAsStringAsync();
Task<Stream> GetStreamAsync();
}

internal static class ApiResponseExtensions
{
public static async Task<string> ReadAsStringAsync(this IApiResponse apiResponse)
{
using var reader = await GetStreamReader(apiResponse).ConfigureAwait(false);
return await reader.ReadToEndAsync().ConfigureAwait(false);
}

public static async Task<T> ReadAsTypeAsync<T>(this IApiResponse apiResponse)
{
using var sr = await GetStreamReader(apiResponse).ConfigureAwait(false);
using var jsonTextReader = new JsonTextReader(sr);
return JsonSerializer.Create().Deserialize<T>(jsonTextReader);
}

private static async Task<StreamReader> GetStreamReader(IApiResponse apiResponse)
{
var stream = await apiResponse.GetStreamAsync().ConfigureAwait(false);
return new StreamReader(stream, apiResponse.ContentEncoding, detectEncodingFromByteOrderMarks: false, (int)apiResponse.ContentLength, leaveOpen: true);
}
}
}
12 changes: 6 additions & 6 deletions tracer/src/Datadog.Trace/Agent/Transports/ApiWebResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace Datadog.Trace.Agent.Transports
Expand All @@ -17,21 +18,20 @@ internal class ApiWebResponse : IApiResponse, IDisposable
public ApiWebResponse(HttpWebResponse response)
{
_response = response;
ContentEncoding = !string.IsNullOrEmpty(response.ContentEncoding) ? Encoding.GetEncoding(response.ContentEncoding) : Encoding.UTF8;
}

public int StatusCode => (int)_response.StatusCode;

public long ContentLength => _response.ContentLength;

public Encoding ContentEncoding { get; }

public string GetHeader(string headerName) => _response.Headers[headerName];

public async Task<string> ReadAsStringAsync()
public Task<Stream> GetStreamAsync()
{
using (var responseStream = _response.GetResponseStream())
{
var reader = new StreamReader(responseStream);
return await reader.ReadToEndAsync().ConfigureAwait(false);
}
return Task.FromResult(_response.GetResponseStream());
}

public void Dispose()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
// </copyright>

#if NETCOREAPP
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

namespace Datadog.Trace.Agent.Transports
Expand All @@ -17,12 +19,17 @@ internal class HttpClientResponse : IApiResponse
public HttpClientResponse(HttpResponseMessage response)
{
_response = response;

var encoding = _response.Content?.Headers?.ContentEncoding?.FirstOrDefault();
ContentEncoding = !string.IsNullOrEmpty(encoding) ? Encoding.GetEncoding(encoding) : Encoding.UTF8;
}

public int StatusCode => (int)_response.StatusCode;

public long ContentLength => _response.Content.Headers.ContentLength ?? -1;

public Encoding ContentEncoding { get; }

public void Dispose()
{
_response.Dispose();
Expand All @@ -48,9 +55,9 @@ public string GetHeader(string headerName)
return null;
}

public Task<string> ReadAsStringAsync()
public Task<Stream> GetStreamAsync()
{
return _response.Content.ReadAsStringAsync();
return _response.Content.ReadAsStreamAsync();
}
}
}
Expand Down
17 changes: 4 additions & 13 deletions tracer/src/Datadog.Trace/Agent/Transports/HttpStreamResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,12 @@ namespace Datadog.Trace.Agent.Transports
internal class HttpStreamResponse : IApiResponse
{
private readonly HttpHeaders _headers;
private string _responseCache;

public HttpStreamResponse(int statusCode, long contentLength, Encoding encoding, Stream responseStream, HttpHeaders headers)
{
StatusCode = statusCode;
ContentLength = contentLength;
Encoding = encoding;
ContentEncoding = encoding;
ResponseStream = responseStream;
_headers = headers;
}
Expand All @@ -28,7 +27,7 @@ public HttpStreamResponse(int statusCode, long contentLength, Encoding encoding,

public long ContentLength { get; }

public Encoding Encoding { get; }
public Encoding ContentEncoding { get; }

public Stream ResponseStream { get; }

Expand All @@ -38,17 +37,9 @@ public void Dispose()

public string GetHeader(string headerName) => _headers.GetValue(headerName);

public async Task<string> ReadAsStringAsync()
public Task<Stream> GetStreamAsync()
{
if (_responseCache == null)
{
using (var reader = new StreamReader(ResponseStream, Encoding, detectEncodingFromByteOrderMarks: false, (int)ContentLength, leaveOpen: true))
{
_responseCache = await reader.ReadToEndAsync().ConfigureAwait(false);
}
}

return _responseCache;
return Task.FromResult(ResponseStream);
}
}
}
7 changes: 4 additions & 3 deletions tracer/src/Datadog.Trace/Ci/IntelligentTestRunnerClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,10 @@ async Task<string[]> InternalSearchCommitAsync(byte[] state, bool finalTry)
request.AddHeader(ApiKeyHeader, _settings.ApiKey);
Log.Debug("ITR: Searching commits from: {url}", _searchCommitsUrl.ToString());
using var response = await request.PostAsync(new ArraySegment<byte>(state), MimeTypes.Json).ConfigureAwait(false);
var responseContent = await response.ReadAsStringAsync().ConfigureAwait(false);
if (response.StatusCode is < 200 or >= 300)
{
var responseContent = await response.ReadAsStringAsync().ConfigureAwait(false);

if (finalTry)
{
try
Expand All @@ -145,8 +146,8 @@ async Task<string[]> InternalSearchCommitAsync(byte[] state, bool finalTry)
throw new WebException($"Status: {response.StatusCode}, Content: {responseContent}");
}

var deserializedResult = JsonConvert.DeserializeObject<DataArrayEnvelope<CommitResponse>>(responseContent);
if (deserializedResult.Data is null)
var deserializedResult = await response.ReadAsTypeAsync<DataArrayEnvelope<CommitResponse>>().ConfigureAwait(false);
if (deserializedResult.Data.Length == 0)
{
return Array.Empty<string>();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,15 @@ public async Task<GetRcmResponse> GetConfigs(GetRcmRequest request)
return null;
}

var content = await apiResponse.ReadAsStringAsync().ConfigureAwait(false);
if (apiResponse.StatusCode is not (>= 200 and <= 299))
{
var content = await apiResponse.ReadAsStringAsync().ConfigureAwait(false);
Log.Warning<int, string>("Failed to receive remote configurations {StatusCode} and message: {ResponseContent}", apiResponse.StatusCode, content);

return null;
}

var response = JsonConvert.DeserializeObject<GetRcmResponse>(content);

return response;
return await apiResponse.ReadAsTypeAsync<GetRcmResponse>().ConfigureAwait(false);
}
}
}
5 changes: 4 additions & 1 deletion tracer/test/Datadog.Trace.Tests/ApiTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@

using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Datadog.Trace.Agent;
using Datadog.Trace.Agent.Transports;
Expand Down Expand Up @@ -179,7 +181,8 @@ public async Task SetsDefaultSamplingRates()

var responseMock = new Mock<IApiResponse>();
responseMock.Setup(x => x.StatusCode).Returns(200);
responseMock.Setup(x => x.ReadAsStringAsync()).Returns(Task.FromResult(serializedResponse));
responseMock.Setup(x => x.GetStreamAsync()).Returns(() => Task.FromResult<Stream>(new MemoryStream(Encoding.UTF8.GetBytes(serializedResponse))));
responseMock.Setup(x => x.ContentEncoding).Returns(() => Encoding.UTF8);
responseMock.Setup(x => x.ContentLength).Returns(serializedResponse.Length);

var requestMock = new Mock<IApiRequest>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
Expand Down Expand Up @@ -214,12 +215,19 @@ public TestApiResponse(int statusCode, string body, string contentType)

public long ContentLength => _body?.Length ?? 0;

public Encoding ContentEncoding => Encoding.UTF8;

public void Dispose()
{
}

public string GetHeader(string headerName) => throw new NotImplementedException();

public Task<Stream> GetStreamAsync()
{
return Task.FromResult(new StreamReader(_body).BaseStream);
}

public Task<string> ReadAsStringAsync() => Task.FromResult(_body);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes;
using Datadog.Trace;
Expand Down Expand Up @@ -126,8 +127,15 @@ private class FakeApiResponse : IApiResponse

public long ContentLength => 0;

public Encoding ContentEncoding => Encoding.UTF8;

public string GetHeader(string headerName) => string.Empty;

public Task<Stream> GetStreamAsync()
{
throw new NotImplementedException();
}

public Task<string> ReadAsStringAsync()
{
throw new NotImplementedException();
Expand Down