示例#1
0
        public async Task <int> ReadRequestHeaderAsync()
        {
            HeadersFrame frame = await ReadRequestHeaderFrameAsync();

            return(frame.StreamId);
        }
示例#2
0
        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);
            }
        }