Exemple #1
0
        public async Task SetsInherentKeepAliveFeatureOnFirstLongPollingRequest()
        {
            var manager    = CreateConnectionManager();
            var connection = manager.CreateConnection();

            var dispatcher = new HttpConnectionDispatcher(manager, new LoggerFactory());

            var context = MakeRequest("/foo", connection);

            var services = new ServiceCollection();

            services.AddEndPoint <TestEndPoint>();
            var builder = new SocketBuilder(services.BuildServiceProvider());

            builder.UseEndPoint <TestEndPoint>();
            var app     = builder.Build();
            var options = new HttpSocketOptions();

            options.LongPolling.PollTimeout = TimeSpan.FromMilliseconds(1); // We don't care about the poll itself

            Assert.Null(connection.Features.Get <IConnectionInherentKeepAliveFeature>());

            await dispatcher.ExecuteAsync(context, options, app).OrTimeout();

            Assert.NotNull(connection.Features.Get <IConnectionInherentKeepAliveFeature>());
            Assert.Equal(options.LongPolling.PollTimeout, connection.Features.Get <IConnectionInherentKeepAliveFeature>().KeepAliveInterval);
        }
        public async Task WebSocketTransportTimesOutWhenCloseFrameNotReceived()
        {
            var manager    = CreateConnectionManager();
            var connection = manager.CreateConnection();

            var dispatcher = new HttpConnectionDispatcher(manager, new LoggerFactory());

            var context = MakeRequest("/foo", connection);

            SetTransport(context, TransportType.WebSockets);

            var services = new ServiceCollection();

            services.AddEndPoint <ImmediatelyCompleteEndPoint>();
            var builder = new SocketBuilder(services.BuildServiceProvider());

            builder.UseEndPoint <ImmediatelyCompleteEndPoint>();
            var app     = builder.Build();
            var options = new HttpSocketOptions();

            options.WebSockets.CloseTimeout = TimeSpan.FromSeconds(1);

            var task = dispatcher.ExecuteAsync(context, options, app);

            await task.OrTimeout();
        }
Exemple #3
0
        public async Task NegotiateReservesConnectionIdAndReturnsIt()
        {
            var manager    = CreateConnectionManager();
            var dispatcher = new HttpConnectionDispatcher(manager, new LoggerFactory());
            var context    = new DefaultHttpContext();
            var services   = new ServiceCollection();

            services.AddEndPoint <TestEndPoint>();
            services.AddOptions();
            var ms = new MemoryStream();

            context.Request.Path   = "/foo";
            context.Request.Method = "OPTIONS";
            context.Response.Body  = ms;
            var builder = new SocketBuilder(services.BuildServiceProvider());

            builder.UseEndPoint <TestEndPoint>();
            var app = builder.Build();
            await dispatcher.ExecuteAsync(context, new HttpSocketOptions(), app);

            var negotiateResponse = JsonConvert.DeserializeObject <JObject>(Encoding.UTF8.GetString(ms.ToArray()));
            var connectionId      = negotiateResponse.Value <string>("connectionId");

            Assert.True(manager.TryGetConnection(connectionId, out var connectionContext));
            Assert.Equal(connectionId, connectionContext.ConnectionId);
        }
        public async Task BlockingConnectionWorksWithLongPollingConnection()
        {
            var manager    = CreateConnectionManager();
            var connection = manager.CreateConnection();

            var dispatcher = new HttpConnectionDispatcher(manager, new LoggerFactory());

            var context = MakeRequest("/foo", connection);

            var services = new ServiceCollection();

            services.AddEndPoint <BlockingEndPoint>();
            var builder = new SocketBuilder(services.BuildServiceProvider());

            builder.UseEndPoint <BlockingEndPoint>();
            var app     = builder.Build();
            var options = new HttpSocketOptions();
            var task    = dispatcher.ExecuteAsync(context, options, app);

            var buffer = Encoding.UTF8.GetBytes("Hello World");

            // Write to the application
            await connection.Application.Writer.WriteAsync(buffer);

            await task;

            Assert.Equal(StatusCodes.Status204NoContent, context.Response.StatusCode);
            bool exists = manager.TryGetConnection(connection.ConnectionId, out _);

            Assert.False(exists);
        }
        public async Task RequestToDisposedConnectionIdReturns404(TransportType transportType)
        {
            var manager    = CreateConnectionManager();
            var connection = manager.CreateConnection();

            connection.Status = DefaultConnectionContext.ConnectionStatus.Disposed;

            var dispatcher = new HttpConnectionDispatcher(manager, new LoggerFactory());

            var context = MakeRequest("/foo", connection);

            SetTransport(context, transportType);

            var services = new ServiceCollection();

            services.AddEndPoint <TestEndPoint>();
            var builder = new SocketBuilder(services.BuildServiceProvider());

            builder.UseEndPoint <TestEndPoint>();
            var app     = builder.Build();
            var options = new HttpSocketOptions();
            await dispatcher.ExecuteAsync(context, options, app);


            Assert.Equal(StatusCodes.Status404NotFound, context.Response.StatusCode);
        }
Exemple #6
0
        public async Task NegotiateReturnsAvailableTransports(TransportType transports)
        {
            var manager    = CreateConnectionManager();
            var dispatcher = new HttpConnectionDispatcher(manager, new LoggerFactory());
            var context    = new DefaultHttpContext();

            context.Features.Set <IHttpResponseFeature>(new ResponseFeature());
            var services = new ServiceCollection();

            services.AddEndPoint <TestEndPoint>();
            services.AddOptions();
            var ms = new MemoryStream();

            context.Request.Path   = "/foo";
            context.Request.Method = "OPTIONS";
            context.Response.Body  = ms;
            var builder = new SocketBuilder(services.BuildServiceProvider());

            builder.UseEndPoint <TestEndPoint>();
            var app = builder.Build();
            await dispatcher.ExecuteAsync(context, new HttpSocketOptions { Transports = transports }, app);

            var negotiateResponse   = JsonConvert.DeserializeObject <JObject>(Encoding.UTF8.GetString(ms.ToArray()));
            var availableTransports = (TransportType)0;

            foreach (var transport in negotiateResponse["availableTransports"])
            {
                availableTransports |= (TransportType)Enum.Parse(typeof(TransportType), transport.Value <string>());
            }

            Assert.Equal(transports, availableTransports);
        }
        public async Task AttemptingToPollWhileAlreadyPollingReplacesTheCurrentPoll()
        {
            var manager    = CreateConnectionManager();
            var connection = manager.CreateConnection();

            var dispatcher = new HttpConnectionDispatcher(manager, new LoggerFactory());

            var services = new ServiceCollection();

            services.AddEndPoint <TestEndPoint>();
            var builder = new SocketBuilder(services.BuildServiceProvider());

            builder.UseEndPoint <TestEndPoint>();
            var app     = builder.Build();
            var options = new HttpSocketOptions();

            var context1 = MakeRequest("/foo", connection);
            var task1    = dispatcher.ExecuteAsync(context1, options, app);
            var context2 = MakeRequest("/foo", connection);
            var task2    = dispatcher.ExecuteAsync(context2, options, app);

            // Task 1 should finish when request 2 arrives
            await task1.OrTimeout();

            // Send a message from the app to complete Task 2
            await connection.Transport.Writer.WriteAsync(Encoding.UTF8.GetBytes("Hello, World"));

            await task2.OrTimeout();

            // Verify the results
            Assert.Equal(StatusCodes.Status204NoContent, context1.Response.StatusCode);
            Assert.Equal(string.Empty, GetContentAsString(context1.Response.Body));
            Assert.Equal(StatusCodes.Status200OK, context2.Response.StatusCode);
            Assert.Equal("Hello, World", GetContentAsString(context2.Response.Body));
        }
        public async Task EndpointsThatAcceptConnectionId404WhenUnknownConnectionIdProvided(TransportType transportType)
        {
            var manager    = CreateConnectionManager();
            var dispatcher = new HttpConnectionDispatcher(manager, new LoggerFactory());

            using (var strm = new MemoryStream())
            {
                var context = new DefaultHttpContext();
                context.Features.Set <IHttpResponseFeature>(new ResponseFeature());
                context.Response.Body = strm;

                var services = new ServiceCollection();
                services.AddEndPoint <TestEndPoint>();
                services.AddOptions();
                context.Request.Path   = "/foo";
                context.Request.Method = "GET";
                var values = new Dictionary <string, StringValues>();
                values["id"] = "unknown";
                var qs = new QueryCollection(values);
                context.Request.Query = qs;
                SetTransport(context, transportType);

                var builder = new SocketBuilder(services.BuildServiceProvider());
                builder.UseEndPoint <TestEndPoint>();
                var app = builder.Build();
                await dispatcher.ExecuteAsync(context, new HttpSocketOptions(), app);

                Assert.Equal(StatusCodes.Status404NotFound, context.Response.StatusCode);
                await strm.FlushAsync();

                Assert.Equal("No Connection with that ID", Encoding.UTF8.GetString(strm.ToArray()));
            }
        }
        public async Task TransportCapabilitiesSet(TransportType transportType, TransferMode expectedTransportCapabilities)
        {
            var manager    = CreateConnectionManager();
            var connection = manager.CreateConnection();

            var dispatcher = new HttpConnectionDispatcher(manager, new LoggerFactory());

            var context = MakeRequest("/foo", connection);

            SetTransport(context, transportType);

            var services = new ServiceCollection();

            services.AddEndPoint <ImmediatelyCompleteEndPoint>();
            var builder = new SocketBuilder(services.BuildServiceProvider());

            builder.UseEndPoint <ImmediatelyCompleteEndPoint>();
            var app = builder.Build();

            var options = new HttpSocketOptions();

            options.WebSockets.CloseTimeout = TimeSpan.FromSeconds(0);
            await dispatcher.ExecuteAsync(context, options, app);

            Assert.Equal(expectedTransportCapabilities, connection.TransportCapabilities);
        }
        public async Task SynchronusExceptionEndsConnection()
        {
            var manager    = CreateConnectionManager();
            var connection = manager.CreateConnection();

            var dispatcher = new HttpConnectionDispatcher(manager, new LoggerFactory());
            var context    = MakeRequest("/foo", connection);

            SetTransport(context, TransportType.ServerSentEvents);

            var services = new ServiceCollection();

            services.AddEndPoint <SynchronusExceptionEndPoint>();
            var builder = new SocketBuilder(services.BuildServiceProvider());

            builder.UseEndPoint <SynchronusExceptionEndPoint>();
            var app = builder.Build();
            await dispatcher.ExecuteAsync(context, new HttpSocketOptions(), app);

            Assert.Equal(StatusCodes.Status200OK, context.Response.StatusCode);

            bool exists = manager.TryGetConnection(connection.ConnectionId, out _);

            Assert.False(exists);
        }
        public async Task EndpointsThatRequireConnectionId400WhenNoConnectionIdProvidedForPost()
        {
            var manager    = CreateConnectionManager();
            var dispatcher = new HttpConnectionDispatcher(manager, new LoggerFactory());

            using (var strm = new MemoryStream())
            {
                var context = new DefaultHttpContext();
                context.Response.Body = strm;
                var services = new ServiceCollection();
                services.AddOptions();
                services.AddEndPoint <TestEndPoint>();
                context.Request.Path   = "/foo";
                context.Request.Method = "POST";

                var builder = new SocketBuilder(services.BuildServiceProvider());
                builder.UseEndPoint <TestEndPoint>();
                var app = builder.Build();
                await dispatcher.ExecuteAsync(context, new HttpSocketOptions(), app);

                Assert.Equal(StatusCodes.Status400BadRequest, context.Response.StatusCode);
                await strm.FlushAsync();

                Assert.Equal("Connection ID required", Encoding.UTF8.GetString(strm.ToArray()));
            }
        }
        public async Task PostNotAllowedForWebSocketConnections()
        {
            var manager    = CreateConnectionManager();
            var dispatcher = new HttpConnectionDispatcher(manager, new LoggerFactory());
            var connection = manager.CreateConnection();

            connection.Metadata[ConnectionMetadataNames.Transport] = TransportType.WebSockets;

            using (var strm = new MemoryStream())
            {
                var context = new DefaultHttpContext();
                context.Response.Body = strm;

                var services = new ServiceCollection();
                services.AddEndPoint <TestEndPoint>();
                services.AddOptions();
                context.Request.Path   = "/foo";
                context.Request.Method = "POST";
                var values = new Dictionary <string, StringValues>();
                values["id"] = connection.ConnectionId;
                var qs = new QueryCollection(values);
                context.Request.Query = qs;

                var builder = new SocketBuilder(services.BuildServiceProvider());
                builder.UseEndPoint <TestEndPoint>();
                var app = builder.Build();
                await dispatcher.ExecuteAsync(context, new HttpSocketOptions(), app);

                Assert.Equal(StatusCodes.Status405MethodNotAllowed, context.Response.StatusCode);
                await strm.FlushAsync();

                Assert.Equal("POST requests are not allowed for WebSocket connections.", Encoding.UTF8.GetString(strm.ToArray()));
            }
        }
        public async Task ConnectionStateSetToInactiveAfterPoll()
        {
            var manager    = CreateConnectionManager();
            var connection = manager.CreateConnection();

            var dispatcher = new HttpConnectionDispatcher(manager, new LoggerFactory());

            var context = MakeRequest("/foo", connection);

            var services = new ServiceCollection();

            services.AddEndPoint <TestEndPoint>();
            var builder = new SocketBuilder(services.BuildServiceProvider());

            builder.UseEndPoint <TestEndPoint>();
            var app     = builder.Build();
            var options = new HttpSocketOptions();
            var task    = dispatcher.ExecuteAsync(context, options, app);

            var buffer = Encoding.UTF8.GetBytes("Hello World");

            // Write to the transport so the poll yields
            await connection.Transport.Writer.WriteAsync(buffer);

            await task;

            Assert.Equal(DefaultConnectionContext.ConnectionStatus.Inactive, connection.Status);
            Assert.Null(connection.GetHttpContext());

            Assert.Equal(StatusCodes.Status200OK, context.Response.StatusCode);
        }
        public async Task RequestToActiveConnectionIdKillsPreviousConnectionLongPolling()
        {
            var manager    = CreateConnectionManager();
            var connection = manager.CreateConnection();

            var dispatcher = new HttpConnectionDispatcher(manager, new LoggerFactory());

            var context1 = MakeRequest("/foo", connection);
            var context2 = MakeRequest("/foo", connection);

            var services = new ServiceCollection();

            services.AddEndPoint <TestEndPoint>();
            var builder = new SocketBuilder(services.BuildServiceProvider());

            builder.UseEndPoint <TestEndPoint>();
            var app      = builder.Build();
            var options  = new HttpSocketOptions();
            var request1 = dispatcher.ExecuteAsync(context1, options, app);
            var request2 = dispatcher.ExecuteAsync(context2, options, app);

            await request1;

            Assert.Equal(StatusCodes.Status204NoContent, context1.Response.StatusCode);
            Assert.Equal(DefaultConnectionContext.ConnectionStatus.Active, connection.Status);

            Assert.False(request2.IsCompleted);

            manager.CloseConnections();

            await request2;
        }
        public async Task AuthorizedConnectionWithAcceptedSchemesCanConnectToEndPoint()
        {
            var manager    = CreateConnectionManager();
            var connection = manager.CreateConnection();
            var dispatcher = new HttpConnectionDispatcher(manager, new LoggerFactory());
            var context    = new DefaultHttpContext();

            context.Features.Set <IHttpResponseFeature>(new ResponseFeature());
            var services = new ServiceCollection();

            services.AddOptions();
            services.AddEndPoint <TestEndPoint>();
            services.AddAuthorization(o =>
            {
                o.AddPolicy("test", policy =>
                {
                    policy.RequireClaim(ClaimTypes.NameIdentifier);
                    policy.AddAuthenticationSchemes("Default");
                });
            });
            services.AddAuthorizationPolicyEvaluator();
            services.AddLogging();
            services.AddAuthenticationCore(o =>
            {
                o.DefaultScheme = "Default";
                o.AddScheme("Default", a => a.HandlerType = typeof(TestAuthenticationHandler));
            });
            var sp = services.BuildServiceProvider();

            context.Request.Path    = "/foo";
            context.Request.Method  = "GET";
            context.RequestServices = sp;
            var values = new Dictionary <string, StringValues>();

            values["id"] = connection.ConnectionId;
            var qs = new QueryCollection(values);

            context.Request.Query = qs;
            context.Response.Body = new MemoryStream();

            var builder = new SocketBuilder(sp);

            builder.UseEndPoint <TestEndPoint>();
            var app     = builder.Build();
            var options = new HttpSocketOptions();

            options.AuthorizationData.Add(new AuthorizeAttribute("test"));

            // "authorize" user
            context.User = new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim(ClaimTypes.NameIdentifier, "name") }));

            var endPointTask = dispatcher.ExecuteAsync(context, options, app);
            await connection.Transport.Writer.WriteAsync(Encoding.UTF8.GetBytes("Hello, World")).OrTimeout();

            await endPointTask.OrTimeout();

            Assert.Equal(StatusCodes.Status200OK, context.Response.StatusCode);
            Assert.Equal("Hello, World", GetContentAsString(context.Response.Body));
        }
        public async Task AuthorizedConnectionWithRejectedSchemesFailsToConnectToEndPoint()
        {
            var manager    = CreateConnectionManager();
            var connection = manager.CreateConnection();
            var dispatcher = new HttpConnectionDispatcher(manager, new LoggerFactory());
            var context    = new DefaultHttpContext();
            var services   = new ServiceCollection();

            services.AddOptions();
            services.AddEndPoint <TestEndPoint>();
            services.AddAuthorization(o =>
            {
                o.AddPolicy("test", policy =>
                {
                    policy.RequireClaim(ClaimTypes.NameIdentifier);
                    policy.AddAuthenticationSchemes("Default");
                });
            });
            services.AddAuthorizationPolicyEvaluator();
            services.AddLogging();
            services.AddAuthenticationCore(o =>
            {
                o.DefaultScheme = "Default";
                o.AddScheme("Default", a => a.HandlerType = typeof(RejectHandler));
            });
            var sp = services.BuildServiceProvider();

            context.Request.Path    = "/foo";
            context.Request.Method  = "GET";
            context.RequestServices = sp;
            var values = new Dictionary <string, StringValues>();

            values["id"] = connection.ConnectionId;
            var qs = new QueryCollection(values);

            context.Request.Query = qs;
            context.Response.Body = new MemoryStream();

            var builder = new SocketBuilder(sp);

            builder.UseEndPoint <TestEndPoint>();
            var app     = builder.Build();
            var options = new HttpSocketOptions();

            options.AuthorizationData.Add(new AuthorizeAttribute("test"));

            // "authorize" user
            context.User = new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim(ClaimTypes.NameIdentifier, "name") }));

            // would block if EndPoint was executed
            await dispatcher.ExecuteAsync(context, options, app).OrTimeout();

            Assert.Equal(StatusCodes.Status401Unauthorized, context.Response.StatusCode);
        }
        public async Task AuthenticatedUserWithoutPermissionCausesForbidden()
        {
            var manager    = CreateConnectionManager();
            var connection = manager.CreateConnection();
            var dispatcher = new HttpConnectionDispatcher(manager, new LoggerFactory());
            var context    = new DefaultHttpContext();
            var services   = new ServiceCollection();

            services.AddOptions();
            services.AddEndPoint <TestEndPoint>();
            services.AddAuthorizationPolicyEvaluator();
            services.AddAuthorization(o =>
            {
                o.AddPolicy("test", policy => policy.RequireClaim(ClaimTypes.NameIdentifier));
            });
            services.AddAuthenticationCore(o =>
            {
                o.DefaultScheme = "Default";
                o.AddScheme("Default", a => a.HandlerType = typeof(TestAuthenticationHandler));
            });
            services.AddLogging();
            var sp = services.BuildServiceProvider();

            context.Request.Path    = "/foo";
            context.Request.Method  = "GET";
            context.RequestServices = sp;
            var values = new Dictionary <string, StringValues>();

            values["id"] = connection.ConnectionId;
            var qs = new QueryCollection(values);

            context.Request.Query = qs;

            var builder = new SocketBuilder(sp);

            builder.UseEndPoint <TestEndPoint>();
            var app     = builder.Build();
            var options = new HttpSocketOptions();

            options.AuthorizationData.Add(new AuthorizeAttribute("test"));

            context.User = new ClaimsPrincipal(new ClaimsIdentity("authenticated"));

            // would hang if EndPoint was running
            await dispatcher.ExecuteAsync(context, options, app).OrTimeout();

            Assert.Equal(StatusCodes.Status403Forbidden, context.Response.StatusCode);
        }
        public async Task RequestToActiveConnectionId409ForStreamingTransports(TransportType transportType)
        {
            var manager    = CreateConnectionManager();
            var connection = manager.CreateConnection();

            var dispatcher = new HttpConnectionDispatcher(manager, new LoggerFactory());

            var context1 = MakeRequest("/foo", connection);
            var context2 = MakeRequest("/foo", connection);

            SetTransport(context1, transportType);
            SetTransport(context2, transportType);

            var services = new ServiceCollection();

            services.AddEndPoint <TestEndPoint>();
            var builder = new SocketBuilder(services.BuildServiceProvider());

            builder.UseEndPoint <TestEndPoint>();
            var app      = builder.Build();
            var options  = new HttpSocketOptions();
            var request1 = dispatcher.ExecuteAsync(context1, options, app);

            await dispatcher.ExecuteAsync(context2, options, app);

            Assert.Equal(StatusCodes.Status409Conflict, context2.Response.StatusCode);

            var webSocketTask = Task.CompletedTask;

            var ws = (TestWebSocketConnectionFeature)context1.Features.Get <IHttpWebSocketFeature>();

            if (ws != null)
            {
                await ws.Client.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None);
            }

            manager.CloseConnections();

            await request1.OrTimeout();
        }
        private static async Task CheckTransportSupported(TransportType supportedTransports, TransportType transportType, int status)
        {
            var manager    = CreateConnectionManager();
            var connection = manager.CreateConnection();
            var dispatcher = new HttpConnectionDispatcher(manager, new LoggerFactory());

            using (var strm = new MemoryStream())
            {
                var context = new DefaultHttpContext();
                context.Features.Set <IHttpResponseFeature>(new ResponseFeature());
                context.Response.Body = strm;
                var services = new ServiceCollection();
                services.AddOptions();
                services.AddEndPoint <ImmediatelyCompleteEndPoint>();
                SetTransport(context, transportType);
                context.Request.Path   = "/foo";
                context.Request.Method = "GET";
                var values = new Dictionary <string, StringValues>();
                values["id"] = connection.ConnectionId;
                var qs = new QueryCollection(values);
                context.Request.Query = qs;

                var builder = new SocketBuilder(services.BuildServiceProvider());
                builder.UseEndPoint <ImmediatelyCompleteEndPoint>();
                var app     = builder.Build();
                var options = new HttpSocketOptions();
                options.Transports = supportedTransports;

                await dispatcher.ExecuteAsync(context, options, app);

                Assert.Equal(status, context.Response.StatusCode);
                await strm.FlushAsync();

                // Check the message for 404
                if (status == 404)
                {
                    Assert.Equal($"{transportType} transport not supported by this end point type", Encoding.UTF8.GetString(strm.ToArray()));
                }
            }
        }
        public async Task LongPollingTimeoutSets200StatusCode()
        {
            var manager    = CreateConnectionManager();
            var connection = manager.CreateConnection();

            var dispatcher = new HttpConnectionDispatcher(manager, new LoggerFactory());

            var context = MakeRequest("/foo", connection);

            var services = new ServiceCollection();

            services.AddEndPoint <TestEndPoint>();
            var builder = new SocketBuilder(services.BuildServiceProvider());

            builder.UseEndPoint <TestEndPoint>();
            var app     = builder.Build();
            var options = new HttpSocketOptions();

            options.LongPolling.PollTimeout = TimeSpan.FromSeconds(2);
            await dispatcher.ExecuteAsync(context, options, app).OrTimeout();

            Assert.Equal(StatusCodes.Status200OK, context.Response.StatusCode);
        }
        public async Task CompletedEndPointEndsLongPollingConnection()
        {
            var manager    = CreateConnectionManager();
            var connection = manager.CreateConnection();

            var dispatcher = new HttpConnectionDispatcher(manager, new LoggerFactory());

            var context = MakeRequest("/foo", connection);

            var services = new ServiceCollection();

            services.AddEndPoint <ImmediatelyCompleteEndPoint>();
            var builder = new SocketBuilder(services.BuildServiceProvider());

            builder.UseEndPoint <ImmediatelyCompleteEndPoint>();
            var app = builder.Build();
            await dispatcher.ExecuteAsync(context, new HttpSocketOptions(), app);

            Assert.Equal(StatusCodes.Status204NoContent, context.Response.StatusCode);

            bool exists = manager.TryGetConnection(connection.ConnectionId, out _);

            Assert.False(exists);
        }