public static async Task AssertGoAwayReception(
            this IReadableByteStream stream,
            ErrorCode expectedErrorCode,
            uint lastStreamId)
        {
            var hdr = await stream.ReadFrameHeaderWithTimeout();

            Assert.Equal(FrameType.GoAway, hdr.Type);
            Assert.Equal(0u, hdr.StreamId);
            Assert.Equal(0, hdr.Flags);
            Assert.InRange(hdr.Length, 8, 256);
            var goAwayBytes = new byte[hdr.Length];
            await stream.ReadAllWithTimeout(new ArraySegment <byte>(goAwayBytes));

            var goAwayData = GoAwayFrameData.DecodeFrom(new ArraySegment <byte>(goAwayBytes));

            Assert.Equal(lastStreamId, goAwayData.Reason.LastStreamId);
            Assert.Equal(expectedErrorCode, goAwayData.Reason.ErrorCode);
        }
Esempio n. 2
0
        private async ValueTask <Http2Error?> HandleGoAwayFrame(FrameHeader fh)
        {
            if (fh.StreamId != 0 || fh.Length < 8)
            {
                return(new Http2Error
                {
                    StreamId = 0,
                    Code = ErrorCode.ProtocolError,
                    Message = "接收到无效的goaway帧头",
                });
            }
            if (fh.Length > localSettings.MaxFrameSize)
            {
                return(new Http2Error
                {
                    StreamId = 0,
                    Code = ErrorCode.FrameSizeError,
                    Message = "超过最大帧大小",
                });
            }

            EnsureBuffer(fh.Length);
            await inputStream.ReadAll(new ArraySegment <byte>(receiveBuffer, 0, fh.Length));

            var goAwayData = GoAwayFrameData.DecodeFrom(
                new ArraySegment <byte>(receiveBuffer, 0, fh.Length));

            if (!remoteGoAwayTcs.Task.IsCompleted)
            {
                var reason    = goAwayData.Reason;
                var data      = reason.DebugData;
                var debugData = new byte[data.Count];
                Array.Copy(data.Array, data.Offset, debugData, 0, data.Count);
                reason.DebugData = new ArraySegment <byte>(debugData);

                remoteGoAwayTcs.TrySetResult(reason);
            }

            return(null);
        }