Пример #1
0
        public async Task UnacceptedConnectionsAreAborted()
        {
            var transportContext = new TestLibuvTransportContext();
            var transport = new LibuvConnectionListener(transportContext, new IPEndPoint(IPAddress.Loopback, 0));

            await transport.BindAsync();
            var endpoint = (IPEndPoint)transport.EndPoint;

            async Task ConnectAsync()
            {
                using (var socket = TestConnection.CreateConnectedLoopbackSocket(endpoint.Port))
                {
                    try
                    {
                        var read = await socket.ReceiveAsync(new byte[10], SocketFlags.None);
                        Assert.Equal(0, read);
                    }
                    catch (SocketException)
                    {
                        // The connection can be reset sometimes
                    }
                }
            }

            var connectTask = ConnectAsync();

            await transport.UnbindAsync();
            await transport.DisposeAsync();

            // The connection was accepted because libuv eagerly accepts connections
            // they sit in a queue in each listener, we want to make sure that resources
            // are cleaned up if they are never accepted by the caller

            await connectTask.DefaultTimeout();
        }
Пример #2
0
        public async Task ConnectionCanReadAndWrite()
        {
            var transportContext = new TestLibuvTransportContext();

            await using var transport = new LibuvConnectionListener(transportContext, new IPEndPoint(IPAddress.Loopback, 0));

            await transport.BindAsync();

            var endpoint = (IPEndPoint)transport.EndPoint;

            async Task EchoServerAsync()
            {
                while (true)
                {
                    await using var connection = await transport.AcceptAsync();

                    if (connection == null)
                    {
                        break;
                    }

                    while (true)
                    {
                        var result = await connection.Transport.Input.ReadAsync();

                        if (result.IsCompleted)
                        {
                            break;
                        }
                        await connection.Transport.Output.WriteAsync(result.Buffer.ToArray());

                        connection.Transport.Input.AdvanceTo(result.Buffer.End);
                    }
                }
            }

            var serverTask = EchoServerAsync();

            using (var socket = TestConnection.CreateConnectedLoopbackSocket(endpoint.Port))
            {
                var data = Encoding.ASCII.GetBytes("Hello World");
                await socket.SendAsync(data, SocketFlags.None);

                var buffer = new byte[data.Length];
                var read   = 0;
                while (read < data.Length)
                {
                    read += await socket.ReceiveAsync(buffer.AsMemory(read, buffer.Length - read), SocketFlags.None);
                }

                Assert.Equal(data, buffer);
            }

            await transport.UnbindAsync();

            await serverTask.DefaultTimeout();
        }
Пример #3
0
        public async Task TransportCanBindUnbindAndStop()
        {
            var transportContext = new TestLibuvTransportContext();
            var transport = new LibuvConnectionListener(transportContext, new IPEndPoint(IPAddress.Loopback, 0));

            await transport.BindAsync();
            await transport.UnbindAsync();
            await transport.DisposeAsync();
        }
Пример #4
0
        public async Task CallingAcceptAfterDisposeAsyncThrows()
        {
            var transportContext = new TestLibuvTransportContext();
            var transport = new LibuvConnectionListener(transportContext, new IPEndPoint(IPAddress.Loopback, 0));

            await transport.BindAsync();
            var endpoint = (IPEndPoint)transport.EndPoint;

            await transport.UnbindAsync();
            await transport.DisposeAsync();

            await Assert.ThrowsAsync<ObjectDisposedException>(() => transport.AcceptAsync().AsTask());
        }
Пример #5
0
        public async Task OneToTenThreads(int threadCount)
        {
            var listenOptions   = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0));
            var serviceContext  = new TestServiceContext();
            var testApplication = new DummyApplication(context =>
            {
                return(context.Response.WriteAsync("Hello World"));
            });

            listenOptions.UseHttpServer(serviceContext, testApplication, Core.HttpProtocols.Http1, addAltSvcHeader: false);

            var transportContext = new TestLibuvTransportContext
            {
#pragma warning disable CS0618
                Options = new LibuvTransportOptions {
                    ThreadCount = threadCount
                }
#pragma warning restore CS0618
            };

            await using var transport = new LibuvConnectionListener(transportContext, listenOptions.EndPoint);
            await transport.BindAsync();

            listenOptions.EndPoint = transport.EndPoint;

            var transportConnectionManager = new TransportConnectionManager(serviceContext.ConnectionManager);
            var dispatcher = new ConnectionDispatcher <ConnectionContext>(serviceContext, c => listenOptions.Build()(c), transportConnectionManager);
            var acceptTask = dispatcher.StartAcceptingConnections(new GenericConnectionListener(transport));

            using (var client = new HttpClient())
            {
                // Send 20 requests just to make sure we don't get any failures
                var requestTasks = new List <Task <string> >();
                for (int i = 0; i < 20; i++)
                {
                    var requestTask = client.GetStringAsync($"http://127.0.0.1:{listenOptions.IPEndPoint.Port}/");
                    requestTasks.Add(requestTask);
                }

                foreach (var result in await Task.WhenAll(requestTasks))
                {
                    Assert.Equal("Hello World", result);
                }
            }

            await transport.UnbindAsync();

            await acceptTask;

            if (!await transportConnectionManager.CloseAllConnectionsAsync(default))
Пример #6
0
        public async Task CallingDisposeAsyncWillYieldPendingAccepts()
        {
            var transportContext = new TestLibuvTransportContext();
            await using var transport = new LibuvConnectionListener(transportContext, new IPEndPoint(IPAddress.Loopback, 0));

            await transport.BindAsync();

            var acceptTask = transport.AcceptAsync();

            await transport.UnbindAsync();

            var connection = await acceptTask.DefaultTimeout();

            Assert.Null(connection);
        }
Пример #7
0
        public async Task Dispose()
        {
            LibuvConnectionListener listener = Interlocked.Exchange(ref m_Listener, null);

            if (listener != null)
            {
                try
                {
                    await listener.UnbindAsync();

                    await listener.DisposeAsync();
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Listener: Failed to dispose.");
                    Console.WriteLine(ex);
                }
            }

            GC.SuppressFinalize(this);
        }