示例#1
0
 public ValueTask <WriteResult> WriteGoAway(
     FrameHeader header, GoAwayFrameData data, bool closeAfterwards)
 {
     return(PerformWriteRequestAsync(
                0,
                wr => {
         wr.Header = header;
         wr.GoAwayData = data;
     },
                closeAfterwards));
 }
        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);
        }
示例#3
0
        private async Task InitiateGoAway(ErrorCode errorCode, bool closeWriter)
        {
            uint lastProcessedStreamId = 0u;
            bool goAwaySent            = false;

            lock (shared.Mutex)
            {
                lastProcessedStreamId = shared.LastIncomingStreamId;
                goAwaySent            = shared.GoAwaySent;
                shared.GoAwaySent     = true;
            }

            if (goAwaySent)
            {
                if (closeWriter)
                {
                    await writer.CloseNow();
                }
            }
            else
            {
                var fh = new FrameHeader
                {
                    Type     = FrameType.GoAway,
                    StreamId = 0,
                    Flags    = 0,
                };

                var goAwayData = new GoAwayFrameData
                {
                    Reason = new GoAwayReason
                    {
                        LastStreamId = lastProcessedStreamId,
                        ErrorCode    = errorCode,
                        DebugData    = Constants.EmptyByteArray,
                    },
                };

                await writer.WriteGoAway(fh, goAwayData, closeWriter);
            }
        }
示例#4
0
        public async void End()
        {
            var fh = new FrameHeader
            {
                Type     = FrameType.GoAway,
                StreamId = 0,
                Flags    = 0,
            };

            var goAwayData = new GoAwayFrameData
            {
                Reason = new GoAwayReason
                {
                    LastStreamId = _stream.Id,
                    ErrorCode    = ErrorCode.StreamClosed,
                    DebugData    = Constants.EmptyByteArray,
                }
            };

            await writer.WriteGoAway(fh, goAwayData, true);
        }
示例#5
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);
        }
示例#6
0
        public async Task ConnectionShouldGoAwayOnInvalidGoAwayStreamId(
            bool isServer)
        {
            var inPipe   = new BufferedPipe(1024);
            var outPipe  = new BufferedPipe(1024);
            var http2Con = await ConnectionUtils.BuildEstablishedConnection(
                isServer, inPipe, outPipe, loggerProvider);

            var goAwayData = new GoAwayFrameData
            {
                Reason = new GoAwayReason
                {
                    LastStreamId = 0u,
                    ErrorCode    = ErrorCode.NoError,
                    DebugData    = new ArraySegment <byte>(new byte[0]),
                },
            };

            var fh = new FrameHeader
            {
                Type     = FrameType.GoAway,
                Flags    = 0,
                StreamId = 1,
                Length   = goAwayData.RequiredSize,
            };

            var dataBytes = new byte[goAwayData.RequiredSize];

            goAwayData.EncodeInto(new ArraySegment <byte>(dataBytes));
            await inPipe.WriteFrameHeader(fh);

            await inPipe.WriteAsync(new ArraySegment <byte>(dataBytes));

            await outPipe.AssertGoAwayReception(ErrorCode.ProtocolError, 0);

            await outPipe.AssertStreamEnd();
        }
        public static async Task WriteGoAway(
            this IWriteAndCloseableByteStream stream,
            uint lastStreamId,
            ErrorCode errc,
            byte[] debugData = null)
        {
            if (debugData == null)
            {
                debugData = new byte[0];
            }

            var goAwayData = new GoAwayFrameData
            {
                Reason = new GoAwayReason
                {
                    LastStreamId = lastStreamId,
                    ErrorCode    = errc,
                    DebugData    = new ArraySegment <byte>(debugData),
                },
            };

            var fh = new FrameHeader
            {
                Type     = FrameType.GoAway,
                Flags    = 0,
                StreamId = 0,
                Length   = goAwayData.RequiredSize,
            };

            var dataBytes = new byte[goAwayData.RequiredSize];

            goAwayData.EncodeInto(new ArraySegment <byte>(dataBytes));
            await stream.WriteFrameHeader(fh);

            await stream.WriteAsync(new ArraySegment <byte>(dataBytes));
        }