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); }
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); } }
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); }
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); }
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)); }