internal async Task SendHeadersPartialAsync() { // Send HEADERS frame header without content. var outputWriter = Pair.Application.Output; Http3FrameWriter.WriteHeader(Http3FrameType.Data, frameLength: 10, outputWriter); await SendAsync(Span <byte> .Empty); }
private Http3FrameWriter CreateFrameWriter(Pipe pipe) { var frameWriter = new Http3FrameWriter(null, null, null, _dirtyMemoryPool, null, Mock.Of <IStreamIdFeature>(), new Http3PeerSettings(), null); frameWriter.Reset(pipe.Writer, null); return(frameWriter); }
internal async Task SendDataAsync(Memory <byte> data) { var outputWriter = _pair.Application.Output; var frame = new Http3RawFrame(); frame.PrepareData(); frame.Length = data.Length; Http3FrameWriter.WriteHeader(frame, outputWriter); await SendAsync(data.Span); }
public async Task WriteSettings_NoSettingsWrittenWithProtocolDefault() { var pipe = new Pipe(new PipeOptions(_dirtyMemoryPool, PipeScheduler.Inline, PipeScheduler.Inline)); var frameWriter = new Http3FrameWriter(pipe.Writer, null, null, null, null, _dirtyMemoryPool, null); var settings = new Http3PeerSettings(); await frameWriter.WriteSettingsAsync(settings.GetNonProtocolDefaults()); var payload = await pipe.Reader.ReadForLengthAsync(2); Assert.Equal(new byte[] { 0x04, 0x00 }, payload.ToArray()); }
public void Initialize(Http3StreamContext context) { base.Initialize(context); InputRemaining = null; _context = context; _errorCodeFeature = _context.ConnectionFeatures.GetRequiredFeature <IProtocolErrorCodeFeature>(); _streamIdFeature = _context.ConnectionFeatures.GetRequiredFeature <IStreamIdFeature>(); _streamAbortFeature = _context.ConnectionFeatures.GetRequiredFeature <IStreamAbortFeature>(); _appCompletedTaskSource.Reset(); _isClosed = 0; _requestHeaderParsingState = default; _parsedPseudoHeaderFields = default; _totalParsedHeaderSize = 0; _isMethodConnect = false; _completionState = default; StreamTimeoutTicks = 0; if (_frameWriter == null) { _frameWriter = new Http3FrameWriter( context.StreamContext, context.TimeoutControl, context.ServiceContext.ServerOptions.Limits.MinResponseDataRate, context.MemoryPool, context.ServiceContext.Log, _streamIdFeature, context.ClientPeerSettings, this); _http3Output = new Http3OutputProducer( _frameWriter, context.MemoryPool, this, context.ServiceContext.Log); Output = _http3Output; RequestBodyPipe = CreateRequestBodyPipe(64 * 1024); // windowSize? QPackDecoder = new QPackDecoder(_context.ServiceContext.ServerOptions.Limits.Http3.MaxRequestHeaderFieldSize); } else { _http3Output.StreamReset(); RequestBodyPipe.Reset(); QPackDecoder.Reset(); } _frameWriter.Reset(context.Transport.Output, context.ConnectionId); }
internal async Task SendDataAsync(Memory <byte> data, bool endStream = false) { var outputWriter = _pair.Application.Output; var frame = new Http3RawFrame(); frame.PrepareData(); frame.Length = data.Length; Http3FrameWriter.WriteHeader(frame, outputWriter); await SendAsync(data.Span); if (endStream) { await _pair.Application.Output.CompleteAsync(); } }
public async Task <bool> SendHeadersAsync(IEnumerable <KeyValuePair <string, string> > headers) { var outputWriter = _pair.Application.Output; var frame = new Http3RawFrame(); frame.PrepareHeaders(); var buffer = _headerEncodingBuffer.AsMemory(); var done = _qpackEncoder.BeginEncode(headers, buffer.Span, out var length); frame.Length = length; // TODO may want to modify behavior of input frames to mock different client behavior (client can send anything). Http3FrameWriter.WriteHeader(frame, outputWriter); await SendAsync(buffer.Span.Slice(0, length)); return(done); }
public async Task WriteSettings_TwoSettingsWritten() { var pipe = new Pipe(new PipeOptions(_dirtyMemoryPool, PipeScheduler.Inline, PipeScheduler.Inline)); var frameWriter = new Http3FrameWriter(pipe.Writer, null, null, null, null, _dirtyMemoryPool, null); var settings = new Http3PeerSettings(); settings.HeaderTableSize = 1234; settings.MaxRequestHeaderFieldSize = 567890; await frameWriter.WriteSettingsAsync(settings.GetNonProtocolDefaults()); // variable length ints make it so the results isn't know without knowing the values var payload = await pipe.Reader.ReadForLengthAsync(10); Assert.Equal(new byte[] { 0x04, 0x08, 0x01, 0x44, 0xD2, 0x06, 0x80, 0x08, 0xAA, 0x52 }, payload.ToArray()); }
public async Task WriteSettings_OneSettingsWrittenWithKestrelDefaults() { var pipe = new Pipe(new PipeOptions(_dirtyMemoryPool, PipeScheduler.Inline, PipeScheduler.Inline)); var frameWriter = new Http3FrameWriter(pipe.Writer, null, null, null, null, _dirtyMemoryPool, null); var limits = new Http3Limits(); var settings = new Http3PeerSettings(); settings.HeaderTableSize = (uint)limits.HeaderTableSize; settings.MaxRequestHeaderFieldSize = (uint)limits.MaxRequestHeaderFieldSize; await frameWriter.WriteSettingsAsync(settings.GetNonProtocolDefaults()); // variable length ints make it so the results isn't know without knowing the values var payload = await pipe.Reader.ReadForLengthAsync(5); Assert.Equal(new byte[] { 0x04, 0x03, 0x06, 0x60, 0x00 }, payload.ToArray()); }
public Http3OutputProducer( Http3FrameWriter frameWriter, MemoryPool <byte> pool, Http3Stream stream, KestrelTrace log) { _frameWriter = frameWriter; _memoryPool = pool; _stream = stream; _log = log; _pipe = CreateDataPipe(pool); _pipeWriter = _pipe.Writer; _pipeReader = _pipe.Reader; _flusher = new TimingPipeFlusher(timeoutControl: null, log); _flusher.Initialize(_pipeWriter); _dataWriteProcessingTask = ProcessDataWrites().Preserve(); }
public Http3ControlStream(Http3StreamContext context) { var httpLimits = context.ServiceContext.ServerOptions.Limits; _context = context; _serverPeerSettings = context.ServerPeerSettings; _streamIdFeature = context.ConnectionFeatures.GetRequiredFeature <IStreamIdFeature>(); _errorCodeFeature = context.ConnectionFeatures.GetRequiredFeature <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); }