public async Task <int> ReadRequestHeaderAsync() { HeadersFrame frame = await ReadRequestHeaderFrameAsync(); return(frame.StreamId); }
public async Task <Frame> ReadFrameAsync(CancellationToken cancellationToken = default) { // First read the frame headers, which should tell us how long the rest of the frame is. byte[] headerBytes = new byte[Frame.FrameHeaderLength]; try { if (!await FillBufferAsync(headerBytes, cancellationToken).ConfigureAwait(false)) { return(null); } } catch (IOException) { // eat errors when client aborts connection and return null. return(null); } Frame header = Frame.ReadFrom(headerBytes); // Read the data segment of the frame, if it is present. byte[] data = new byte[header.Length]; if (header.Length > 0 && !await FillBufferAsync(data, cancellationToken).ConfigureAwait(false)) { throw new Exception("Connection stream closed while attempting to read frame body."); } if (_ignoredSettingsAckPromise != null && header.Type == FrameType.Settings && header.Flags == FrameFlags.Ack) { _ignoredSettingsAckPromise.TrySetResult(true); _ignoredSettingsAckPromise = null; return(await ReadFrameAsync(cancellationToken).ConfigureAwait(false)); } if (_ignoreWindowUpdates && header.Type == FrameType.WindowUpdate) { return(await ReadFrameAsync(cancellationToken).ConfigureAwait(false)); } if (_expectPingFrame != null && header.Type == FrameType.Ping) { _expectPingFrame.SetResult(PingFrame.ReadFrom(header, data)); _expectPingFrame = null; return(await ReadFrameAsync(cancellationToken).ConfigureAwait(false)); } // Construct the correct frame type and return it. switch (header.Type) { case FrameType.Settings: return(SettingsFrame.ReadFrom(header, data)); case FrameType.Data: return(DataFrame.ReadFrom(header, data)); case FrameType.Headers: return(HeadersFrame.ReadFrom(header, data)); case FrameType.Priority: return(PriorityFrame.ReadFrom(header, data)); case FrameType.RstStream: return(RstStreamFrame.ReadFrom(header, data)); case FrameType.Ping: return(PingFrame.ReadFrom(header, data)); case FrameType.GoAway: return(GoAwayFrame.ReadFrom(header, data)); case FrameType.Continuation: return(ContinuationFrame.ReadFrom(header, data)); default: return(header); } }