public void OnNext_RequestObserver_With_Null_Action_Value_And_Null_Controller_Value()
        {
            // Arrange
            var observer = new AspNetCoreDiagnosticListenerObserver();

            var registry = new DefaultCollectorRegistry();
            var factory  = Metrics.WithCustomRegistry(registry);

            var listener = new DiagnosticListener("TestListener2");

            listener.Subscribe(observer);



            var context = new DefaultHttpContext();

            context.Request.Method      = "GET";
            context.Request.Path        = new PathString("/api/test2");
            context.Response.StatusCode = 200;

            var httpConnectionFeature = new HttpConnectionFeature
            {
                ConnectionId = "12345"
            };

            context.Features.Set <IHttpConnectionFeature>(httpConnectionFeature);

            var routeData = new RouteData();

            routeData.Values.Add("controller", null);
            routeData.Values.Add("action", null);

            // Act
            var activity = new Activity("Microsoft.AspNetCore.Hosting.HttpRequestIn");

            listener.StartActivity(activity, new { HttpContext = context });
            listener.Write("Microsoft.AspNetCore.Mvc.AfterAction", new { httpContext = context, routeData });
            listener.StopActivity(activity, new { HttpContext = context });


            // Assert
            var requestCounter = (Counter)observer.GetType().GetField("_requestCounter",
                                                                      BindingFlags.Instance | BindingFlags.NonPublic).GetValue(observer);
            var requestSummary = (Summary)observer.GetType().GetField("_requestSummary",
                                                                      BindingFlags.Instance | BindingFlags.NonPublic).GetValue(observer);

            var counterMetrics = requestCounter.Collect();
            var summaryMetrics = requestSummary.Collect();



            Assert.IsTrue(counterMetrics.First().metric.Any(p => p.label[1].value == "/api/test2"));
            Assert.IsNotNull(summaryMetrics.First().metric[0].summary);
        }
        public void OnNext_RequestObserved_RequestStopEventReceived()
        {
            // Arrange
            var observer = new AspNetCoreDiagnosticListenerObserver();
            var listener = new DiagnosticListener("TestListener");

            listener.Subscribe(observer);

            var context = new DefaultHttpContext();

            context.Request.Method      = "GET";
            context.Request.Path        = new PathString("/api/test");
            context.Response.StatusCode = 200;

            var httpConnectionFeature = new HttpConnectionFeature
            {
                ConnectionId = "1234"
            };

            context.Features.Set <IHttpConnectionFeature>(httpConnectionFeature);

            var routeData = new RouteData();

            routeData.Values.Add("controller", "test");
            routeData.Values.Add("action", "get");
            // Act

            // Create the activity, start it and immediately stop it. This will
            // cause the OnNext method in the observer to be called with the events
            // Microsoft.AspNetCore.Hosting.HttpRequestIn.Start and
            // Microsoft.AspNetCore.Hosting.HttpRequestIn.Stop. In addition,
            // Activity.Current will be managed by the listener.
            var activity = new Activity("Microsoft.AspNetCore.Hosting.HttpRequestIn");

            listener.StartActivity(activity, new { HttpContext = context });
            listener.Write("Microsoft.AspNetCore.Mvc.AfterAction", new { httpContext = context, routeData });
            listener.StopActivity(activity, new { HttpContext = context });


            // Assert
            var requestCounter = (Counter)observer.GetType().GetField("_requestCounter",
                                                                      BindingFlags.Instance | BindingFlags.NonPublic).GetValue(observer);
            var requestSummary = (Summary)observer.GetType().GetField("_requestSummary",
                                                                      BindingFlags.Instance | BindingFlags.NonPublic).GetValue(observer);

            var counterMetrics = requestCounter.Collect();
            var summaryMetrics = requestSummary.Collect();

            Assert.AreEqual(1, counterMetrics.First().metric.Count);
            Assert.AreEqual(1, counterMetrics.First().metric[0].counter.value);
            Assert.AreEqual(1, summaryMetrics.First().metric.Count);
            Assert.IsNotNull(summaryMetrics.First().metric[0].summary);
        }
コード例 #3
0
        public static (HttpContext context, HttpConnectionFeature feature) CreateHttpContext()
        {
            HttpConnectionFeature feature = new HttpConnectionFeature();

            FeatureCollection features = new FeatureCollection();

            features.Set <IHttpConnectionFeature>(feature);

            Mock <HttpContext> contextMock = new Mock <HttpContext>();

            contextMock.SetupGet(c => c.Features).Returns(features);

            return(contextMock.Object, feature);
        }
コード例 #4
0
        private static HttpClient GetByConfig(Action <WebHostBuilder> configureDelegate)
        {
            var b = new WebHostBuilder();

            configureDelegate(b);
            b.UseStartup <TSetup>();
            var fc = new FeatureCollection();
            var f  = new HttpConnectionFeature();

            f.RemoteIpAddress = new IPAddress(new byte[] { 172, 0, 0, 1 });
            f.RemotePort      = 80;
            fc.Set(f);
            var srv = new Microsoft.AspNetCore.TestHost.TestServer(b, fc);

            return(srv.CreateClient());
        }
コード例 #5
0
        public void InitializeSetsIpFromRemoteIpAddress()
        {
            var requestTelemetry = new RequestTelemetry();
            var contextAccessor  = HttpContextAccessorHelper.CreateHttpContextAccessor(requestTelemetry);

            var httpConnectionFeature = new HttpConnectionFeature
            {
                RemoteIpAddress = new IPAddress(new byte[] { 1, 2, 3, 4 })
            };

            contextAccessor.HttpContext.Features.Set <IHttpConnectionFeature>(httpConnectionFeature);

            var initializer = new ClientIpHeaderTelemetryInitializer(contextAccessor);

            initializer.Initialize(requestTelemetry);

            Assert.Equal("1.2.3.4", requestTelemetry.Context.Location.Ip);
        }
コード例 #6
0
        private static void CloneHttpContext(HttpContext context, HttpConnectionContext connection)
        {
            // The reason we're copying the base features instead of the HttpContext properties is
            // so that we can get all of the logic built into DefaultHttpContext to extract higher level
            // structure from the low level properties
            var existingRequestFeature = context.Features.Get <IHttpRequestFeature>() !;

            var requestFeature = new HttpRequestFeature();

            requestFeature.Protocol    = existingRequestFeature.Protocol;
            requestFeature.Method      = existingRequestFeature.Method;
            requestFeature.Scheme      = existingRequestFeature.Scheme;
            requestFeature.Path        = existingRequestFeature.Path;
            requestFeature.PathBase    = existingRequestFeature.PathBase;
            requestFeature.QueryString = existingRequestFeature.QueryString;
            requestFeature.RawTarget   = existingRequestFeature.RawTarget;
            var requestHeaders = new Dictionary <string, StringValues>(existingRequestFeature.Headers.Count, StringComparer.OrdinalIgnoreCase);

            foreach (var header in existingRequestFeature.Headers)
            {
                requestHeaders[header.Key] = header.Value;
            }
            requestFeature.Headers = new HeaderDictionary(requestHeaders);

            var existingConnectionFeature = context.Features.Get <IHttpConnectionFeature>();
            var connectionFeature         = new HttpConnectionFeature();

            if (existingConnectionFeature != null)
            {
                connectionFeature.ConnectionId    = existingConnectionFeature.ConnectionId;
                connectionFeature.LocalIpAddress  = existingConnectionFeature.LocalIpAddress;
                connectionFeature.LocalPort       = existingConnectionFeature.LocalPort;
                connectionFeature.RemoteIpAddress = existingConnectionFeature.RemoteIpAddress;
                connectionFeature.RemotePort      = existingConnectionFeature.RemotePort;
            }

            // The response is a dud, you can't do anything with it anyways
            var responseFeature = new HttpResponseFeature();

            var features = new FeatureCollection();

            features.Set <IHttpRequestFeature>(requestFeature);
            features.Set <IHttpResponseFeature>(responseFeature);
            features.Set <IHttpResponseBodyFeature>(new StreamResponseBodyFeature(Stream.Null));
            features.Set <IHttpConnectionFeature>(connectionFeature);

            // REVIEW: We could strategically look at adding other features but it might be better
            // if we expose a callback that would allow the user to preserve HttpContext properties.

            var newHttpContext = new DefaultHttpContext(features);

            newHttpContext.TraceIdentifier = context.TraceIdentifier;

            var endpointFeature = context.Features.Get <IEndpointFeature>();

            newHttpContext.SetEndpoint(endpointFeature?.Endpoint);

            CloneUser(newHttpContext, context);

            connection.ServiceScope        = context.RequestServices.CreateAsyncScope();
            newHttpContext.RequestServices = connection.ServiceScope.Value.ServiceProvider;

            // REVIEW: This extends the lifetime of anything that got put into HttpContext.Items
            newHttpContext.Items = new Dictionary <object, object?>(context.Items);

            connection.HttpContext = newHttpContext;
        }
コード例 #7
0
        private static HttpContext CloneHttpContext(HttpContext context)
        {
            // The reason we're copying the base features instead of the HttpContext properties is
            // so that we can get all of the logic built into DefaultHttpContext to extract higher level
            // structure from the low level properties
            var existingRequestFeature = context.Features.Get <IHttpRequestFeature>();

            var requestFeature = new HttpRequestFeature();

            requestFeature.Protocol    = existingRequestFeature.Protocol;
            requestFeature.Method      = existingRequestFeature.Method;
            requestFeature.Scheme      = existingRequestFeature.Scheme;
            requestFeature.Path        = existingRequestFeature.Path;
            requestFeature.PathBase    = existingRequestFeature.PathBase;
            requestFeature.QueryString = existingRequestFeature.QueryString;
            requestFeature.RawTarget   = existingRequestFeature.RawTarget;
            var requestHeaders = new Dictionary <string, StringValues>(existingRequestFeature.Headers.Count, StringComparer.Ordinal);

            foreach (var header in existingRequestFeature.Headers)
            {
                requestHeaders[header.Key] = header.Value;
            }
            requestFeature.Headers = new HeaderDictionary(requestHeaders);

            var existingConnectionFeature = context.Features.Get <IHttpConnectionFeature>();
            var connectionFeature         = new HttpConnectionFeature();

            if (existingConnectionFeature != null)
            {
                connectionFeature.ConnectionId    = existingConnectionFeature.ConnectionId;
                connectionFeature.LocalIpAddress  = existingConnectionFeature.LocalIpAddress;
                connectionFeature.LocalPort       = existingConnectionFeature.LocalPort;
                connectionFeature.RemoteIpAddress = existingConnectionFeature.RemoteIpAddress;
                connectionFeature.RemotePort      = existingConnectionFeature.RemotePort;
            }

            // The response is a dud, you can't do anything with it anyways
            var responseFeature = new HttpResponseFeature();

            var features = new FeatureCollection();

            features.Set <IHttpRequestFeature>(requestFeature);
            features.Set <IHttpResponseFeature>(responseFeature);
            features.Set <IHttpConnectionFeature>(connectionFeature);

            // REVIEW: We could strategically look at adding other features but it might be better
            // if we expose a callback that would allow the user to preserve HttpContext properties.

            var newHttpContext = new DefaultHttpContext(features);

            newHttpContext.TraceIdentifier = context.TraceIdentifier;

            CloneUser(newHttpContext, context);

            // Making request services function property could be tricky and expensive as it would require
            // DI scope per connection. It would also mean that services resolved in middleware leading up to here
            // wouldn't be the same instance (but maybe that's fine). For now, we just return an empty service provider
            newHttpContext.RequestServices = EmptyServiceProvider.Instance;

            // REVIEW: This extends the lifetime of anything that got put into HttpContext.Items
            newHttpContext.Items = new Dictionary <object, object>(context.Items);
            return(newHttpContext);
        }