public async Task DatadogHttpClient_WhenOnlyPartOfResponseIsAvailable_ParsesCorrectly(int bytesToRead) { var client = DatadogHttpClient.CreateTraceAgentClient(); var requestContent = new BufferContent(new ArraySegment <byte>(new byte[0])); var htmlResponse = string.Join("\r\n", HtmlResponseLines()); using var requestStream = new MemoryStream(); var responseBytes = Encoding.UTF8.GetBytes(htmlResponse); using var responseStream = new RegulatedStream(responseBytes, bytesToRead); var request = new HttpRequest("POST", "localhost", string.Empty, new HttpHeaders(), requestContent); var response = await client.SendAsync(request, requestStream, responseStream); Assert.Equal(200, response.StatusCode); Assert.Equal("OK", response.ResponseMessage); Assert.Equal("Test Server", response.Headers.GetValue(("Server"))); Assert.Equal(2, response.ContentLength); Assert.Equal("application/json", response.ContentType); var buffer = new byte[2]; await response.Content.CopyToAsync(buffer); var content = Encoding.UTF8.GetString(buffer); Assert.Equal("{}", content); }
public HttpStreamRequest(DatadogHttpClient client, Uri uri, IStreamFactory streamFactory) { _uri = uri; _client = client; _streamFactory = streamFactory; }
public HttpStreamRequestFactory(IStreamFactory streamFactory, DatadogHttpClient httpClient) { _streamFactory = streamFactory; _httpClient = httpClient; }
public static IApiRequestFactory Get(ImmutableExporterSettings settings) { var strategy = settings.TracesTransport; switch (strategy) { case TracesTransportType.WindowsNamedPipe: Log.Information <string, string, int>("Using {FactoryType} for trace transport, with pipe name {PipeName} and timeout {Timeout}ms.", nameof(NamedPipeClientStreamFactory), settings.TracesPipeName, settings.TracesPipeTimeoutMs); // use http://localhost as base endpoint return(new HttpStreamRequestFactory(new NamedPipeClientStreamFactory(settings.TracesPipeName, settings.TracesPipeTimeoutMs), DatadogHttpClient.CreateTraceAgentClient(), new Uri("http://localhost"))); case TracesTransportType.Default: default: #if NETCOREAPP Log.Information("Using {FactoryType} for trace transport.", nameof(HttpClientRequestFactory)); return(new HttpClientRequestFactory(settings.AgentUri, AgentHttpHeaderNames.DefaultHeaders)); #else Log.Information("Using {FactoryType} for trace transport.", nameof(ApiWebRequestFactory)); return(new ApiWebRequestFactory(settings.AgentUri, AgentHttpHeaderNames.DefaultHeaders)); #endif } }
/// <summary> /// Initializes a new instance of the <see cref="HttpStreamRequestFactory"/> class. /// </summary> /// <param name="streamFactory">The <see cref="IStreamFactory"/> to use when creating <see cref="HttpStreamRequest"/></param> /// <param name="httpClient">The <see cref="DatadogHttpClient"/> to use to associate with the <see cref="HttpStreamRequest"/></param> /// <param name="baseEndpoint"> The base endpoint to use when constructing an <see cref="HttpRequest"/> in <see cref="GetEndpoint"/>.. /// The endpoint returned from <see cref="GetEndpoint"/>, isn't actually used to route the request, /// but it is used to construct the HTTP message, by using the the Host header and the path. /// For non TCP workloads, failure to include a valid Host header (e.g. using a file URI) can cause issues /// e.g. see this issue around nodejs (called from go) https://github.com/grpc/grpc-go/issues/2628 and /// issue/discussion in aspnetcore here https://github.com/dotnet/aspnetcore/issues/18522. /// Typically, you should use <c>http://localhost</c> as the host instead for non-TCP clients (e.g. UDS and named pipes)</param> public HttpStreamRequestFactory(IStreamFactory streamFactory, DatadogHttpClient httpClient, Uri baseEndpoint) { _streamFactory = streamFactory; _httpClient = httpClient; _baseEndpoint = baseEndpoint; }
public static IApiRequestFactory Get(ImmutableExporterSettings settings) { var strategy = settings.TracesTransport; switch (strategy) { case TracesTransportType.CustomTcpProvider: Log.Information("Using {FactoryType} for trace transport.", nameof(TcpStreamFactory)); return(new HttpStreamRequestFactory(new TcpStreamFactory(settings.AgentUri.Host, settings.AgentUri.Port), DatadogHttpClient.CreateTraceAgentClient())); case TracesTransportType.WindowsNamedPipe: Log.Information <string, string, int>("Using {FactoryType} for trace transport, with pipe name {PipeName} and timeout {Timeout}ms.", nameof(NamedPipeClientStreamFactory), settings.TracesPipeName, settings.TracesPipeTimeoutMs); return(new HttpStreamRequestFactory(new NamedPipeClientStreamFactory(settings.TracesPipeName, settings.TracesPipeTimeoutMs), DatadogHttpClient.CreateTraceAgentClient())); case TracesTransportType.UnixDomainSocket: #if NETCOREAPP3_1_OR_GREATER Log.Information <string, string, int>("Using {FactoryType} for trace transport, with Unix Domain Sockets path {Path} and timeout {Timeout}ms.", nameof(UnixDomainSocketStreamFactory), settings.TracesUnixDomainSocketPath, settings.TracesPipeTimeoutMs); return(new HttpStreamRequestFactory(new UnixDomainSocketStreamFactory(settings.TracesUnixDomainSocketPath), DatadogHttpClient.CreateTraceAgentClient())); #else Log.Error("Using Unix Domain Sockets for trace transport is only supported on .NET Core 3.1 and greater. Falling back to default transport."); goto case TracesTransportType.Default; #endif case TracesTransportType.Default: default: #if NETCOREAPP Log.Information("Using {FactoryType} for trace transport.", nameof(HttpClientRequestFactory)); return(new HttpClientRequestFactory(AgentHttpHeaderNames.DefaultHeaders)); #else Log.Information("Using {FactoryType} for trace transport.", nameof(ApiWebRequestFactory)); return(new ApiWebRequestFactory(AgentHttpHeaderNames.DefaultHeaders)); #endif } }
public static IApiRequestFactory GetAgentIntakeFactory(ImmutableExporterSettings settings) { // use the same transport for telemetry as we do for traces var strategy = settings.TracesTransport; switch (strategy) { case TracesTransportType.WindowsNamedPipe: Log.Information <string, string, int>("Using {FactoryType} for telemetry transport, with pipe name {PipeName} and timeout {Timeout}ms.", nameof(NamedPipeClientStreamFactory), settings.TracesPipeName, settings.TracesPipeTimeoutMs); return(new HttpStreamRequestFactory(new NamedPipeClientStreamFactory(settings.TracesPipeName, settings.TracesPipeTimeoutMs), DatadogHttpClient.CreateTelemetryAgentClient(), GetBaseEndpoint())); case TracesTransportType.Default: default: var agentUri = UriHelpers.Combine(settings.AgentUri, TelemetryConstants.AgentTelemetryEndpoint); #if NETCOREAPP Log.Information("Using {FactoryType} for telemetry transport.", nameof(HttpClientRequestFactory)); return(new HttpClientRequestFactory(agentUri, TelemetryHttpHeaderNames.GetDefaultAgentHeaders(), timeout: Timeout)); #else Log.Information("Using {FactoryType} for telemetry transport.", nameof(ApiWebRequestFactory)); return(new ApiWebRequestFactory(agentUri, TelemetryHttpHeaderNames.GetDefaultAgentHeaders(), timeout: Timeout)); #endif }