Example #1
0
        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);
        }
Example #2
0
 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
        }