コード例 #1
0
        public async Task WaitForAvailableUnidirectionStreamsAsyncWorks()
        {
            using QuicListener listener           = CreateQuicListener(maxUnidirectionalStreams: 1);
            using QuicConnection clientConnection = CreateQuicConnection(listener.ListenEndPoint);
            Task <QuicConnection> serverTask = listener.AcceptConnectionAsync().AsTask();
            await TaskTimeoutExtensions.WhenAllOrAnyFailed(clientConnection.ConnectAsync().AsTask(), serverTask, PassingTestTimeoutMilliseconds);

            using QuicConnection serverConnection = serverTask.Result;
            listener.Dispose();

            // No stream opened yet, should return immediately.
            Assert.True(clientConnection.WaitForAvailableUnidirectionalStreamsAsync().IsCompletedSuccessfully);

            // Open one stream, should wait till it closes.
            QuicStream stream   = clientConnection.OpenUnidirectionalStream();
            ValueTask  waitTask = clientConnection.WaitForAvailableUnidirectionalStreamsAsync();

            Assert.False(waitTask.IsCompleted);
            Assert.Throws <QuicException>(() => clientConnection.OpenUnidirectionalStream());
            // Close the streams, the waitTask should finish as a result.
            stream.Dispose();
            QuicStream newStream = await serverConnection.AcceptStreamAsync();

            newStream.Dispose();

            await waitTask.AsTask().WaitAsync(TimeSpan.FromSeconds(10));
        }
コード例 #2
0
        public async Task WaitForAvailableUnidirectionStreamsAsyncWorks()
        {
            using QuicListener listener           = CreateQuicListener(maxUnidirectionalStreams: 1);
            using QuicConnection clientConnection = CreateQuicConnection(listener.ListenEndPoint);

            ValueTask clientTask = clientConnection.ConnectAsync();

            using QuicConnection serverConnection = await listener.AcceptConnectionAsync();

            await clientTask;

            // No stream openned yet, should return immediately.
            Assert.True(clientConnection.WaitForAvailableUnidirectionalStreamsAsync().IsCompletedSuccessfully);

            // Open one stream, should wait till it closes.
            QuicStream stream   = clientConnection.OpenUnidirectionalStream();
            ValueTask  waitTask = clientConnection.WaitForAvailableUnidirectionalStreamsAsync();

            Assert.False(waitTask.IsCompleted);
            Assert.Throws <QuicException>(() => clientConnection.OpenUnidirectionalStream());

            // Close the stream, the waitTask should finish as a result.
            stream.Dispose();
            await waitTask.AsTask().WaitAsync(TimeSpan.FromSeconds(10));
        }
コード例 #3
0
        public ValueTask <ConnectionContext> StartUnidirectionalStreamAsync()
        {
            var stream  = _connection.OpenUnidirectionalStream();
            var context = new QuicStreamContext(stream, this, _context);

            context.Start();
            return(new ValueTask <ConnectionContext>(context));
        }
コード例 #4
0
    public override ValueTask <ConnectionContext> ConnectAsync(IFeatureCollection?features = null, CancellationToken cancellationToken = default)
    {
        QuicStream quicStream;

        var streamDirectionFeature = features?.Get <IStreamDirectionFeature>();

        if (streamDirectionFeature != null)
        {
            if (streamDirectionFeature.CanRead)
            {
                quicStream = _connection.OpenBidirectionalStream();
            }
            else
            {
                quicStream = _connection.OpenUnidirectionalStream();
            }
        }
        else
        {
            quicStream = _connection.OpenBidirectionalStream();
        }

        // Only a handful of control streams are created by the server and they last for the
        // lifetime of the connection. No value in pooling them.
        QuicStreamContext?context = new QuicStreamContext(this, _context);

        context.Initialize(quicStream);
        context.Start();

        QuicLog.ConnectedStream(_log, context);

        return(new ValueTask <ConnectionContext>(context));
    }
コード例 #5
0
        public async Task ClientToServerUnidirectionalStream_CompleteWrites_PipeProvidesDataAndCompleteTogether()
        {
            // Arrange
            await using var connectionListener = await QuicTestHelpers.CreateConnectionListenerFactory(LoggerFactory);

            var options = QuicTestHelpers.CreateClientConnectionOptions(connectionListener.EndPoint);

            using var quicConnection = new QuicConnection(QuicImplementationProviders.MsQuic, options);
            await quicConnection.ConnectAsync().DefaultTimeout();

            await using var serverConnection = await connectionListener.AcceptAndAddFeatureAsync().DefaultTimeout();

            // Act
            await using var clientStream = quicConnection.OpenUnidirectionalStream();
            await clientStream.WriteAsync(TestData).DefaultTimeout();

            await using var serverStream = await serverConnection.AcceptAsync().DefaultTimeout();

            var readResult = await serverStream.Transport.Input.ReadAtLeastAsync(TestData.Length).DefaultTimeout();

            serverStream.Transport.Input.AdvanceTo(readResult.Buffer.End);

            var readResultTask = serverStream.Transport.Input.ReadAsync();

            await clientStream.WriteAsync(TestData, endStream : true).DefaultTimeout();

            // Assert
            var completeReadResult = await readResultTask.DefaultTimeout();

            Assert.Equal(TestData, completeReadResult.Buffer.ToArray());
            Assert.True(completeReadResult.IsCompleted);
        }
コード例 #6
0
        protected sealed override async Task QuicStreamServer(QuicConnection connection)
        {
            await using var stream = connection.OpenUnidirectionalStream();
            await SendData(stream);

            await stream.ShutdownWriteCompleted();
        }
コード例 #7
0
ファイル: MsQuicTests.cs プロジェクト: jahau/runtime
        public async Task QuicStream_ReadWrite_Random_Success(int readSize, int writeSize)
        {
            byte[] testBuffer = new byte[8192];
            new Random().NextBytes(testBuffer);


            await Task.WhenAll(DoWrite(), DoRead());

            async Task DoWrite()
            {
                using QuicConnection clientConnection = CreateQuicConnection(DefaultListener.ListenEndPoint);
                await clientConnection.ConnectAsync();

                await using QuicStream clientStream = clientConnection.OpenUnidirectionalStream();

                ReadOnlyMemory <byte> sendBuffer = testBuffer;

                while (sendBuffer.Length != 0)
                {
                    ReadOnlyMemory <byte> chunk = sendBuffer.Slice(0, Math.Min(sendBuffer.Length, writeSize));
                    await clientStream.WriteAsync(chunk);

                    sendBuffer = sendBuffer.Slice(chunk.Length);
                }

                clientStream.Shutdown();
                await clientStream.ShutdownWriteCompleted();
            }

            async Task DoRead()
            {
                using QuicConnection serverConnection = await DefaultListener.AcceptConnectionAsync();

                await using QuicStream serverStream = await serverConnection.AcceptStreamAsync();

                byte[] receiveBuffer  = new byte[testBuffer.Length];
                int    totalBytesRead = 0;

                while (totalBytesRead != receiveBuffer.Length)
                {
                    int bytesRead = await serverStream.ReadAsync(receiveBuffer.AsMemory(totalBytesRead, Math.Min(receiveBuffer.Length - totalBytesRead, readSize)));

                    if (bytesRead == 0)
                    {
                        break;
                    }

                    totalBytesRead += bytesRead;
                }

                Assert.True(receiveBuffer.AsSpan().SequenceEqual(testBuffer));
            }
        }
コード例 #8
0
            message);                         // message

        private async ValueTask SendSettingsAsync()
        {
            try
            {
                _clientControl = _connection.OpenUnidirectionalStream();
                await _clientControl.WriteAsync(_pool.Settings.Http3SettingsFrame, CancellationToken.None).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                Abort(ex);
            }
        }
コード例 #9
0
ファイル: QuicStreamTests.cs プロジェクト: newfang/runtime
        private static async Task CreateAndTestUnidirectionalStream(QuicConnection c1, QuicConnection c2)
        {
            using QuicStream s1 = c1.OpenUnidirectionalStream();

            Assert.False(s1.CanRead);
            Assert.True(s1.CanWrite);

            ValueTask writeTask = s1.WriteAsync(s_data);

            using QuicStream s2 = await c2.AcceptStreamAsync();
            await ReceiveDataAsync(s_data, s2);

            await writeTask;

            await TestUnidirectionalStream(s1, s2);
        }
コード例 #10
0
        public async Task AcceptAsync_ClientStartsAndStopsUnidirectionStream_ServerAccepts()
        {
            // Arrange
            await using var connectionListener = await QuicTestHelpers.CreateConnectionListenerFactory(LoggerFactory);

            var options = QuicTestHelpers.CreateClientConnectionOptions(connectionListener.EndPoint);

            using var quicConnection = new QuicConnection(QuicImplementationProviders.MsQuic, options);
            await quicConnection.ConnectAsync().DefaultTimeout();

            await using var serverConnection = await connectionListener.AcceptAndAddFeatureAsync().DefaultTimeout();

            // Act
            var acceptTask = serverConnection.AcceptAsync();

            await using var clientStream = quicConnection.OpenUnidirectionalStream();
            await clientStream.WriteAsync(TestData);

            await using var serverStream = await acceptTask.DefaultTimeout();

            // Assert
            Assert.NotNull(serverStream);
            Assert.False(serverStream.ConnectionClosed.IsCancellationRequested);

            var closedTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);

            serverStream.ConnectionClosed.Register(() => closedTcs.SetResult());

            // Read data from client.
            var read = await serverStream.Transport.Input.ReadAtLeastAsync(TestData.Length).DefaultTimeout();

            Assert.Equal(TestData, read.Buffer.ToArray());
            serverStream.Transport.Input.AdvanceTo(read.Buffer.End);

            // Shutdown client.
            clientStream.Shutdown();

            // Receive shutdown on server.
            read = await serverStream.Transport.Input.ReadAsync().DefaultTimeout();

            Assert.True(read.IsCompleted);

            await closedTcs.Task.DefaultTimeout();
        }
コード例 #11
0
        public async Task ClientToServerUnidirectionalStream_ClientAbort_ServerReceivesAbort()
        {
            // Arrange
            await using var connectionListener = await QuicTestHelpers.CreateConnectionListenerFactory(LoggerFactory);

            var options = QuicTestHelpers.CreateClientConnectionOptions(connectionListener.EndPoint);

            using var quicConnection = new QuicConnection(QuicImplementationProviders.MsQuic, options);
            await quicConnection.ConnectAsync().DefaultTimeout();

            await using var serverConnection = await connectionListener.AcceptAsync().DefaultTimeout();

            // Act
            await using var clientStream = quicConnection.OpenUnidirectionalStream();
            await clientStream.WriteAsync(TestData).DefaultTimeout();

            await using var serverStream = await serverConnection.AcceptAsync().DefaultTimeout();

            var readResult = await serverStream.Transport.Input.ReadAtLeastAsync(TestData.Length).DefaultTimeout();

            serverStream.Transport.Input.AdvanceTo(readResult.Buffer.End);

            var closedTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);

            serverStream.ConnectionClosed.Register(() => closedTcs.SetResult());

            clientStream.AbortWrite((long)Http3ErrorCode.InternalError);

            // Receive abort from client.
            var ex = await Assert.ThrowsAsync <ConnectionResetException>(() => serverStream.Transport.Input.ReadAsync().AsTask()).DefaultTimeout();

            // Assert
            Assert.Equal((long)Http3ErrorCode.InternalError, ((QuicStreamAbortedException)ex.InnerException).ErrorCode);

            var quicStreamContext = Assert.IsType <QuicStreamContext>(serverStream);

            // Both send and receive loops have exited.
            await quicStreamContext._processingTask.DefaultTimeout();

            await closedTcs.Task.DefaultTimeout();
        }
コード例 #12
0
        public async Task ClientToServerUnidirectionalStream_ServerReadsData_GracefullyClosed()
        {
            // Arrange
            await using var connectionListener = await QuicTestHelpers.CreateConnectionListenerFactory(LoggerFactory);

            var options = QuicTestHelpers.CreateClientConnectionOptions(connectionListener.EndPoint);

            using var quicConnection = new QuicConnection(QuicImplementationProviders.MsQuic, options);
            await quicConnection.ConnectAsync().DefaultTimeout();

            await using var serverConnection = await connectionListener.AcceptAsync().DefaultTimeout();

            // Act
            await using var clientStream = quicConnection.OpenUnidirectionalStream();
            await clientStream.WriteAsync(TestData, endStream : true).DefaultTimeout();

            await using var serverStream = await serverConnection.AcceptAsync().DefaultTimeout();

            var readResult = await serverStream.Transport.Input.ReadAtLeastAsync(TestData.Length).DefaultTimeout();

            serverStream.Transport.Input.AdvanceTo(readResult.Buffer.End);

            // Input should be completed.
            readResult = await serverStream.Transport.Input.ReadAsync();

            // Assert
            Assert.True(readResult.IsCompleted);

            var quicStreamContext = Assert.IsType <QuicStreamContext>(serverStream);

            Assert.False(quicStreamContext.CanWrite);
            Assert.True(quicStreamContext.CanRead);

            // Both send and receive loops have exited.
            await quicStreamContext._processingTask.DefaultTimeout();
        }
コード例 #13
0
 public Http3LoopbackStream OpenUnidirectionalStream()
 {
     return(new Http3LoopbackStream(_connection.OpenUnidirectionalStream()));
 }