public Http3ControlStream(Http3StreamContext context) { var httpLimits = context.ServiceContext.ServerOptions.Limits; _context = context; _serverPeerSettings = context.ServerPeerSettings; _streamIdFeature = context.ConnectionFeatures.Get <IStreamIdFeature>() !; _errorCodeFeature = context.ConnectionFeatures.Get <IProtocolErrorCodeFeature>() !; _headerType = -1; _frameWriter = new Http3FrameWriter( context.StreamContext, context.TimeoutControl, httpLimits.MinResponseDataRate, context.MemoryPool, context.ServiceContext.Log, _streamIdFeature, context.ClientPeerSettings, this); _frameWriter.Reset(context.Transport.Output, context.ConnectionId); }
private Http3StreamContext CreateHttpStreamContext(ConnectionContext streamContext) { var httpConnectionContext = new Http3StreamContext( _multiplexedContext.ConnectionId, HttpProtocols.Http3, _context.AltSvcHeader, _multiplexedContext, _context.ServiceContext, streamContext.Features, _context.MemoryPool, streamContext.LocalEndPoint as IPEndPoint, streamContext.RemoteEndPoint as IPEndPoint, _streamLifetimeHandler, streamContext, _clientSettings, _serverSettings); httpConnectionContext.TimeoutControl = _context.TimeoutControl; httpConnectionContext.Transport = streamContext.Transport; return(httpConnectionContext); }
public Http3Stream(Http3Connection http3Connection, Http3StreamContext context) { Initialize(context); InputRemaining = null; // First, determine how we know if an Http3stream is unidirectional or bidirectional var httpLimits = context.ServiceContext.ServerOptions.Limits; var http3Limits = httpLimits.Http3; _http3Connection = http3Connection; _context = context; _errorCodeFeature = _context.ConnectionFeatures.Get <IProtocolErrorCodeFeature>() !; _streamIdFeature = _context.ConnectionFeatures.Get <IStreamIdFeature>() !; _frameWriter = new Http3FrameWriter( context.Transport.Output, context.StreamContext, context.TimeoutControl, httpLimits.MinResponseDataRate, context.ConnectionId, context.MemoryPool, context.ServiceContext.Log, _streamIdFeature); // ResponseHeaders aren't set, kind of ugly that we need to reset. Reset(); _http3Output = new Http3OutputProducer( _frameWriter, context.MemoryPool, this, context.ServiceContext.Log); RequestBodyPipe = CreateRequestBodyPipe(64 * 1024); // windowSize? Output = _http3Output; QPackDecoder = new QPackDecoder(_context.ServiceContext.ServerOptions.Limits.Http3.MaxRequestHeaderFieldSize); }
private async ValueTask <Http3ControlStream> CreateNewUnidirectionalStreamAsync <TContext>(IHttpApplication <TContext> application) { var features = new FeatureCollection(); features.Set <IStreamDirectionFeature>(new DefaultStreamDirectionFeature(canRead: false, canWrite: true)); var streamContext = await _multiplexedContext.ConnectAsync(features); var httpConnectionContext = new Http3StreamContext { //ConnectionId = "", TODO getting stream ID from stream that isn't started throws an exception. StreamContext = streamContext, Protocols = HttpProtocols.Http3, 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 }; return(new Http3ControlStream <TContext>(application, this, httpConnectionContext)); }
public Http3Stream(IHttpApplication <TContext> application, Http3Connection connection, Http3StreamContext context) : base(connection, context) { _application = application; }
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; } }
public Http3Stream(IHttpApplication <TContext> application, Http3StreamContext context) { Initialize(context); _application = application; }