コード例 #1
0
        internal async Task InnerProcessRequestsAsync <TContext>(IHttpApplication <TContext> application)
        {
            // Start other three unidirectional streams here.
            var controlTask = CreateControlStream(application);
            var encoderTask = CreateEncoderStream(application);
            var decoderTask = CreateDecoderStream(application);

            try
            {
                while (true)
                {
                    var streamContext = await _multiplexedContext.AcceptAsync();

                    if (streamContext == null || _haveSentGoAway)
                    {
                        break;
                    }

                    var quicStreamFeature = streamContext.Features.Get <IStreamDirectionFeature>();
                    var streamIdFeature   = streamContext.Features.Get <IStreamIdFeature>();

                    Debug.Assert(quicStreamFeature != null);

                    var httpConnectionContext = new Http3StreamContext
                    {
                        ConnectionId  = streamContext.ConnectionId,
                        StreamContext = streamContext,
                        // TODO connection context is null here. Should we set it to anything?
                        ServiceContext     = _context.ServiceContext,
                        ConnectionFeatures = streamContext.Features,
                        MemoryPool         = _context.MemoryPool,
                        Transport          = streamContext.Transport,
                        TimeoutControl     = _context.TimeoutControl,
                        LocalEndPoint      = streamContext.LocalEndPoint as IPEndPoint,
                        RemoteEndPoint     = streamContext.RemoteEndPoint as IPEndPoint
                    };

                    if (!quicStreamFeature.CanWrite)
                    {
                        // Unidirectional stream
                        var stream = new Http3ControlStream <TContext>(application, this, httpConnectionContext);
                        ThreadPool.UnsafeQueueUserWorkItem(stream, preferLocal: false);
                    }
                    else
                    {
                        // Keep track of highest stream id seen for GOAWAY
                        var streamId = streamIdFeature.StreamId;
                        HighestStreamId = streamId;

                        var http3Stream = new Http3Stream <TContext>(application, this, httpConnectionContext);
                        var stream      = http3Stream;
                        lock (_streams)
                        {
                            _streams[streamId] = http3Stream;
                        }
                        KestrelEventSource.Log.RequestQueuedStart(stream, AspNetCore.Http.HttpProtocol.Http3);
                        ThreadPool.UnsafeQueueUserWorkItem(stream, preferLocal: false);
                    }
                }
            }
            finally
            {
                // Abort all streams as connection has shutdown.
                lock (_streams)
                {
                    foreach (var stream in _streams.Values)
                    {
                        stream.Abort(new ConnectionAbortedException("Connection is shutting down."));
                    }
                }

                ControlStream?.Abort(new ConnectionAbortedException("Connection is shutting down."));
                EncoderStream?.Abort(new ConnectionAbortedException("Connection is shutting down."));
                DecoderStream?.Abort(new ConnectionAbortedException("Connection is shutting down."));

                await controlTask;
                await encoderTask;
                await decoderTask;
            }
        }
コード例 #2
0
        public async Task ProcessRequestsAsync <TContext>(IHttpApplication <TContext> application)
        {
            var streamListenerFeature = Context.ConnectionFeatures.Get <IQuicStreamListenerFeature>();

            // Start other three unidirectional streams here.
            var controlTask = CreateControlStream(application);
            var encoderTask = CreateEncoderStream(application);
            var decoderTask = CreateDecoderStream(application);

            try
            {
                while (true)
                {
                    var connectionContext = await streamListenerFeature.AcceptAsync();

                    if (connectionContext == null || _haveSentGoAway)
                    {
                        break;
                    }

                    var httpConnectionContext = new HttpConnectionContext
                    {
                        ConnectionId       = connectionContext.ConnectionId,
                        ConnectionContext  = connectionContext,
                        Protocols          = Context.Protocols,
                        ServiceContext     = Context.ServiceContext,
                        ConnectionFeatures = connectionContext.Features,
                        MemoryPool         = Context.MemoryPool,
                        Transport          = connectionContext.Transport,
                        TimeoutControl     = Context.TimeoutControl,
                        LocalEndPoint      = connectionContext.LocalEndPoint as IPEndPoint,
                        RemoteEndPoint     = connectionContext.RemoteEndPoint as IPEndPoint
                    };

                    var streamFeature = httpConnectionContext.ConnectionFeatures.Get <IQuicStreamFeature>();

                    if (!streamFeature.CanWrite)
                    {
                        // Unidirectional stream
                        var stream = new Http3ControlStream <TContext>(application, this, httpConnectionContext);
                        ThreadPool.UnsafeQueueUserWorkItem(stream, preferLocal: false);
                    }
                    else
                    {
                        // Keep track of highest stream id seen for GOAWAY
                        var streamId = streamFeature.StreamId;

                        HighestStreamId = streamId;

                        var http3Stream = new Http3Stream <TContext>(application, this, httpConnectionContext);
                        var stream      = http3Stream;
                        _streams[streamId] = http3Stream;
                        ThreadPool.UnsafeQueueUserWorkItem(stream, preferLocal: false);
                    }
                }
            }
            finally
            {
                // Abort all streams as connection has shutdown.
                foreach (var stream in _streams.Values)
                {
                    stream.Abort(new ConnectionAbortedException("Connection is shutting down."));
                }

                ControlStream.Abort(new ConnectionAbortedException("Connection is shutting down."));
                EncoderStream.Abort(new ConnectionAbortedException("Connection is shutting down."));
                DecoderStream.Abort(new ConnectionAbortedException("Connection is shutting down."));

                await controlTask;
                await encoderTask;
                await decoderTask;
            }
        }