Exemple #1
0
        private async Task HandleFrameProcessingError(
            Http2Error err)
        {
            if (err.StreamId == 0)
            {
                await InitiateGoAway(err.Code, true);
            }
            else
            {
                StreamImpl stream = null;
                lock (shared.Mutex)
                {
                    shared.streamMap.TryGetValue(err.StreamId, out stream);
                }

                if (stream != null)
                {
                    await stream.Reset(err.Code, false);
                }
                else
                {
                    var fh = new FrameHeader
                    {
                        StreamId = err.StreamId,
                        Type     = FrameType.ResetStream,
                        Flags    = 0,
                    };
                    var resetData = new ResetFrameData
                    {
                        ErrorCode = err.Code,
                    };
                    await writer.WriteResetStream(fh, resetData);
                }
            }
        }
Exemple #2
0
        private async ValueTask <Http2Error?> HandleResetFrame(FrameHeader fh)
        {
            if (fh.StreamId == 0 || fh.Length != ResetFrameData.Size)
            {
                var errc = ErrorCode.ProtocolError;
                if (fh.Length != ResetFrameData.Size)
                {
                    errc = ErrorCode.FrameSizeError;
                }
                return(new Http2Error
                {
                    StreamId = 0,
                    Code = errc,
                    Message = "接收到无效的RST_STREAM帧头",
                });
            }

            await inputStream.ReadAll(
                new ArraySegment <byte>(receiveBuffer, 0, ResetFrameData.Size));

            var resetData = ResetFrameData.DecodeFrom(
                new ArraySegment <byte>(receiveBuffer, 0, ResetFrameData.Size));

            StreamImpl stream             = null;
            uint       lastOutgoingStream = 0u;
            uint       lastIncomingStream = 0u;

            lock (shared.Mutex)
            {
                lastIncomingStream = shared.LastIncomingStreamId;
                lastOutgoingStream = shared.LastOutgoingStreamId;
                shared.streamMap.TryGetValue(fh.StreamId, out stream);
                if (stream != null)
                {
                    shared.streamMap.Remove(fh.StreamId);
                }
            }

            if (stream != null)
            {
                await stream.Reset(resetData.ErrorCode, true);
            }
            else
            {
                if (IsIdleStreamId(fh.StreamId, lastOutgoingStream, lastIncomingStream))
                {
                    return(new Http2Error
                    {
                        StreamId = 0u,
                        Code = ErrorCode.ProtocolError,
                        Message = "接收到空闲流的RST_STREAM",
                    });
                }
            }

            return(null);
        }
Exemple #3
0
 public ValueTask <WriteResult> WriteResetStream(
     FrameHeader header, ResetFrameData data)
 {
     return(PerformWriteRequestAsync(
                header.StreamId,
                wr => {
         wr.Header = header;
         wr.ResetFrameData = data;
     },
                false));
 }
Exemple #4
0
        internal ValueTask <ConnectionWriter.WriteResult> Reset(
            ErrorCode errorCode, bool fromRemote)
        {
            ValueTask <ConnectionWriter.WriteResult> writeResetTask =
                new ValueTask <ConnectionWriter.WriteResult>(
                    ConnectionWriter.WriteResult.Success);

            lock (stateMutex)
            {
                if (state == StreamState.Reset || state == StreamState.Closed)
                {
                    return(writeResetTask);
                }
                state = StreamState.Reset;
                var head = receiveQueueHead;
                receiveQueueHead = null;
                FreeReceiveQueue(head);
            }

            if (!fromRemote)
            {
                var fh = new FrameHeader
                {
                    StreamId = this.Id,
                    Type     = FrameType.ResetStream,
                    Flags    = 0,
                };
                var resetData = new ResetFrameData
                {
                    ErrorCode = errorCode
                };
                writeResetTask = connection.writer.WriteResetStream(fh, resetData);
            }
            else
            {
                connection.writer.RemoveStream(this.Id);
            }

            if (!fromRemote)
            {
                this.connection.UnregisterStream(this);
            }

            readDataPossible.Set();
            readTrailersPossible.Set();
            readHeadersPossible.Set();

            return(writeResetTask);
        }
        public static async Task AssertResetStreamReception(
            this IReadableByteStream stream,
            uint expectedStreamId,
            ErrorCode expectedErrorCode)
        {
            var hdr = await stream.ReadFrameHeaderWithTimeout();

            Assert.Equal(FrameType.ResetStream, hdr.Type);
            Assert.Equal(expectedStreamId, hdr.StreamId);
            Assert.Equal(0, hdr.Flags);
            Assert.Equal(ResetFrameData.Size, hdr.Length);
            var resetBytes = new byte[hdr.Length];
            await stream.ReadAllWithTimeout(new ArraySegment <byte>(resetBytes));

            var resetData = ResetFrameData.DecodeFrom(new ArraySegment <byte>(resetBytes));

            Assert.Equal(expectedErrorCode, resetData.ErrorCode);
        }
        public static async Task WriteResetStream(
            this IWriteAndCloseableByteStream stream, uint streamId, ErrorCode errc)
        {
            var fh = new FrameHeader
            {
                Type     = FrameType.ResetStream,
                Flags    = 0,
                Length   = ResetFrameData.Size,
                StreamId = streamId,
            };
            var data = new ResetFrameData
            {
                ErrorCode = errc,
            };
            var dataBytes = new byte[ResetFrameData.Size];

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

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