public static HttpMultiplexedConnectionContext CreateHttp3ConnectionContext(
        MultiplexedConnectionContext connectionContext = null,
        ServiceContext serviceContext         = null,
        IFeatureCollection connectionFeatures = null,
        MemoryPool <byte> memoryPool          = null,
        IPEndPoint localEndPoint       = null,
        IPEndPoint remoteEndPoint      = null,
        ITimeoutControl timeoutControl = null)
    {
        var http3ConnectionContext = new HttpMultiplexedConnectionContext(
            "TEST",
            HttpProtocols.Http3,
            altSvcHeader: null,
            connectionContext ?? new TestMultiplexedConnectionContext {
            ConnectionId = "TEST"
        },
            serviceContext ?? CreateServiceContext(new KestrelServerOptions()),
            connectionFeatures ?? new FeatureCollection(),
            memoryPool ?? PinnedBlockMemoryPoolFactory.Create(),
            localEndPoint,
            remoteEndPoint)
        {
            TimeoutControl = timeoutControl
        };

        return(http3ConnectionContext);
    }
Beispiel #2
0
        public async Task GracefulServerShutdownSendsGoawayClosesConnection()
        {
            await InitializeConnectionAsync(_echoApplication);

            // Trigger server shutdown.
            MultiplexedConnectionContext.ConnectionClosingCts.Cancel();
            Assert.Null(await MultiplexedConnectionContext.AcceptAsync().DefaultTimeout());
        }
 public Http3Connection(Http3ConnectionContext context)
 {
     _multiplexedContext = context.ConnectionContext;
     _context            = context;
     DynamicTable        = new DynamicTable(0);
     _systemClock        = context.ServiceContext.SystemClock;
     _timeoutControl     = new TimeoutControl(this);
     _context.TimeoutControl ??= _timeoutControl;
 }
Beispiel #4
0
 public HttpMultiplexedConnectionContext(
     string connectionId,
     MultiplexedConnectionContext connectionContext,
     ServiceContext serviceContext,
     IFeatureCollection connectionFeatures,
     MemoryPool <byte> memoryPool,
     IPEndPoint?localEndPoint,
     IPEndPoint?remoteEndPoint) : base(connectionId, HttpProtocols.Http3, connectionContext, serviceContext, connectionFeatures, memoryPool, localEndPoint, remoteEndPoint)
 {
 }
        public Http3Connection(Http3ConnectionContext context)
        {
            _multiplexedContext = context.ConnectionContext;
            _context            = context;
            _systemClock        = context.ServiceContext.SystemClock;
            _timeoutControl     = new TimeoutControl(this);
            _context.TimeoutControl ??= _timeoutControl;

            var httpLimits = context.ServiceContext.ServerOptions.Limits;

            _serverSettings.HeaderTableSize           = (uint)httpLimits.Http3.HeaderTableSize;
            _serverSettings.MaxRequestHeaderFieldSize = (uint)httpLimits.Http3.MaxRequestHeaderFieldSize;
        }
Beispiel #6
0
        public Http3Connection(HttpMultiplexedConnectionContext context)
        {
            _multiplexedContext    = (MultiplexedConnectionContext)context.ConnectionContext;
            _context               = context;
            _streamLifetimeHandler = this;

            _errorCodeFeature = context.ConnectionFeatures.Get <IProtocolErrorCodeFeature>() !;

            var httpLimits = context.ServiceContext.ServerOptions.Limits;

            _serverSettings.HeaderTableSize = (uint)httpLimits.Http3.HeaderTableSize;
            _serverSettings.MaxRequestHeaderFieldSectionSize = (uint)httpLimits.MaxRequestHeadersTotalSize;
        }
Beispiel #7
0
        public async Task GracefulServerShutdownClosesConnection()
        {
            await InitializeConnectionAsync(_echoApplication);

            var inboundControlStream = await GetInboundControlStream();

            await inboundControlStream.ExpectSettingsAsync();

            // Trigger server shutdown.
            CloseConnectionGracefully();

            Assert.Null(await MultiplexedConnectionContext.AcceptAsync().DefaultTimeout());

            await WaitForConnectionStopAsync(0, false, expectedErrorCode : Http3ErrorCode.NoError);
        }
    public Http3Connection(HttpMultiplexedConnectionContext context)
    {
        _multiplexedContext    = (MultiplexedConnectionContext)context.ConnectionContext;
        _context               = context;
        _streamLifetimeHandler = this;

        _errorCodeFeature = context.ConnectionFeatures.GetRequiredFeature <IProtocolErrorCodeFeature>();

        var httpLimits = context.ServiceContext.ServerOptions.Limits;

        _serverSettings.HeaderTableSize = (uint)httpLimits.Http3.HeaderTableSize;
        _serverSettings.MaxRequestHeaderFieldSectionSize = (uint)httpLimits.MaxRequestHeadersTotalSize;
        _serverSettings.EnableWebTransport = Convert.ToUInt32(context.ServiceContext.ServerOptions.EnableWebTransportAndH3Datagrams);
        // technically these are 2 different settings so they should have separate values but the Chromium implementation requires
        // them to both be 1 to useWebTransport.
        _serverSettings.H3Datagram = Convert.ToUInt32(context.ServiceContext.ServerOptions.EnableWebTransportAndH3Datagrams);
    }
Beispiel #9
0
 public Http3ConnectionContext(
     string connectionId,
     MultiplexedConnectionContext connectionContext,
     ServiceContext serviceContext,
     IFeatureCollection connectionFeatures,
     MemoryPool <byte> memoryPool,
     IPEndPoint?localEndPoint,
     IPEndPoint?remoteEndPoint)
 {
     ConnectionId       = connectionId;
     ConnectionContext  = connectionContext;
     ServiceContext     = serviceContext;
     ConnectionFeatures = connectionFeatures;
     MemoryPool         = memoryPool;
     LocalEndPoint      = localEndPoint;
     RemoteEndPoint     = remoteEndPoint;
 }
Beispiel #10
0
        public Task OnConnectionAsync(MultiplexedConnectionContext connectionContext)
        {
            var memoryPoolFeature = connectionContext.Features.Get <IMemoryPoolFeature>();

            var http3ConnectionContext = new Http3ConnectionContext(
                connectionContext.ConnectionId,
                connectionContext,
                _serviceContext,
                connectionContext.Features,
                memoryPoolFeature?.MemoryPool ?? System.Buffers.MemoryPool <byte> .Shared,
                connectionContext.LocalEndPoint as IPEndPoint,
                connectionContext.RemoteEndPoint as IPEndPoint);

            var connection = new Http3Connection(http3ConnectionContext);

            return(connection.ProcessStreamsAsync(_application));
        }
Beispiel #11
0
        public Task OnConnectionAsync(MultiplexedConnectionContext connectionContext)
        {
            var memoryPoolFeature = connectionContext.Features.Get <IMemoryPoolFeature>();

            var http3ConnectionContext = new Http3ConnectionContext
            {
                ConnectionId       = connectionContext.ConnectionId,
                ConnectionContext  = connectionContext,
                ServiceContext     = _serviceContext,
                ConnectionFeatures = connectionContext.Features,
                MemoryPool         = memoryPoolFeature?.MemoryPool ?? System.Buffers.MemoryPool <byte> .Shared,
                LocalEndPoint      = connectionContext.LocalEndPoint as IPEndPoint,
                RemoteEndPoint     = connectionContext.RemoteEndPoint as IPEndPoint
            };

            var connection = new Http3Connection(http3ConnectionContext);

            return(connection.ProcessRequestsAsync(_application));
        }
Beispiel #12
0
    public Task OnConnectionAsync(MultiplexedConnectionContext connectionContext)
    {
        var memoryPoolFeature = connectionContext.Features.Get <IMemoryPoolFeature>();
        var localEndPoint     = connectionContext.LocalEndPoint as IPEndPoint;
        var altSvcHeader      = _addAltSvcHeader && localEndPoint != null?HttpUtilities.GetEndpointAltSvc(localEndPoint, _protocols) : null;

        var httpConnectionContext = new HttpMultiplexedConnectionContext(
            connectionContext.ConnectionId,
            _protocols,
            altSvcHeader,
            connectionContext,
            _serviceContext,
            connectionContext.Features,
            memoryPoolFeature?.MemoryPool ?? System.Buffers.MemoryPool <byte> .Shared,
            localEndPoint,
            connectionContext.RemoteEndPoint as IPEndPoint);

        var connection = new HttpConnection(httpConnectionContext);

        return(connection.ProcessRequestsAsync(_application));
    }
Beispiel #13
0
        public static HttpMultiplexedConnectionContext CreateHttp3ConnectionContext(
            MultiplexedConnectionContext connectionContext = null,
            ServiceContext serviceContext         = null,
            IFeatureCollection connectionFeatures = null,
            MemoryPool <byte> memoryPool          = null,
            IPEndPoint localEndPoint       = null,
            IPEndPoint remoteEndPoint      = null,
            ITimeoutControl timeoutControl = null)
        {
            var http3ConnectionContext = new HttpMultiplexedConnectionContext(
                "TestConnectionId",
                connectionContext ?? new TestMultiplexedConnectionContext(),
                serviceContext ?? CreateServiceContext(new KestrelServerOptions()),
                connectionFeatures ?? new FeatureCollection(),
                memoryPool ?? PinnedBlockMemoryPoolFactory.Create(),
                localEndPoint,
                remoteEndPoint);

            http3ConnectionContext.TimeoutControl = timeoutControl;

            return(http3ConnectionContext);
        }
Beispiel #14
0
    public static async Task <QuicStreamContext> CreateAndCompleteBidirectionalStreamGracefully(QuicConnection clientConnection, MultiplexedConnectionContext serverConnection, ILogger logger)
    {
        logger.LogInformation("Client starting stream.");
        var clientStream = await clientConnection.OpenOutboundStreamAsync(QuicStreamType.Bidirectional);

        logger.LogInformation("Client sending data.");
        await clientStream.WriteAsync(TestData, completeWrites : true).DefaultTimeout();

        logger.LogInformation("Server accepting stream.");
        var serverStream = await serverConnection.AcceptAsync().DefaultTimeout();

        logger.LogInformation("Server reading data.");
        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.True(readResult.IsCompleted);

        // Complete reading and writing.
        logger.LogInformation("Server completing input and output.");
        await serverStream.Transport.Input.CompleteAsync();

        await serverStream.Transport.Output.CompleteAsync();

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

        // Both send and receive loops have exited.
        logger.LogInformation("Server verifying stream is finished.");
        await quicStreamContext._processingTask.DefaultTimeout();

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

        logger.LogInformation("Server disposing stream.");
        await quicStreamContext.DisposeAsync();

        quicStreamContext.Dispose();

        return(quicStreamContext);
    }
    public static async Task <QuicStreamContext> CreateAndCompleteBidirectionalStreamGracefully(QuicConnection clientConnection, MultiplexedConnectionContext serverConnection)
    {
        var clientStream = await clientConnection.OpenBidirectionalStreamAsync();

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

        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.True(readResult.IsCompleted);

        // Complete reading and writing.
        await serverStream.Transport.Input.CompleteAsync();

        await serverStream.Transport.Output.CompleteAsync();

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

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

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

        await quicStreamContext.DisposeAsync();

        quicStreamContext.Dispose();

        return(quicStreamContext);
    }
Beispiel #16
0
 public LoggingMultiplexedConnectionContext(MultiplexedConnectionContext inner, ILogger logger)
 {
     _inner  = inner;
     _logger = logger;
 }
Beispiel #17
0
 public Task OnConnectionAsync(MultiplexedConnectionContext context)
 {
     return(_multiplexedNext(new LoggingMultiplexedConnectionContext(context, _logger)));
 }