public async Task CloseShouldUnblockReads() { var p = new BufferedPipe(128); var input = new byte[70]; var output = new byte[50]; for (var i = 0; i < 70; i++) { input[i] = (byte)i; } // Start read first var task = p.ReadAsync(new ArraySegment <byte>(output)).AsTask(); // Schedule close var writeTask = Task.Run(async() => { await Task.Delay(10); await p.CloseAsync(); }); // And wait for read to unblock var res = await task; Assert.Equal(true, res.EndOfStream); Assert.Equal(0, res.BytesRead); // The writeTask should also finish await writeTask; }
public async Task ConnectionShouldIgnoreResetsforUnknownStreams() { var inPipe = new BufferedPipe(1024); var outPipe = new BufferedPipe(1024); Func <IStream, bool> listener = (s) => true; var conn = await ConnectionUtils.BuildEstablishedConnection( true, inPipe, outPipe, loggerProvider, listener); var hEncoder = new Encoder(); var streamId = 7u; await inPipe.WriteHeaders( hEncoder, streamId, false, TestHeaders.DefaultGetHeaders); await inPipe.WriteResetStream(streamId - 2, ErrorCode.RefusedStream); await inPipe.WriteResetStream(streamId - 4, ErrorCode.Cancel); // Send a ping afterwards // If we get a response the reset frame in between was ignored await inPipe.WritePing(new byte[8], false); await outPipe.ReadAndDiscardPong(); }
public async Task ConnectionShouldGoAwayOnInvalidGoAwayFrameLength( bool isServer, int frameLength) { var inPipe = new BufferedPipe(1024); var outPipe = new BufferedPipe(1024); var http2Con = await ConnectionUtils.BuildEstablishedConnection( isServer, inPipe, outPipe, loggerProvider); var fh = new FrameHeader { Type = FrameType.GoAway, Flags = 0, Length = frameLength, StreamId = 0, }; await inPipe.WriteFrameHeader(fh); var expectedErr = frameLength > 65535 ? ErrorCode.FrameSizeError : ErrorCode.ProtocolError; await outPipe.AssertGoAwayReception(expectedErr, 0); await outPipe.AssertStreamEnd(); }
public async Task ConnectionShouldCloseAndStreamsShouldGetResetWhenExternalCloseIsRequested() { // TODO: Add a variant of this test for clients as soon as they are supported var inPipe = new BufferedPipe(1024); var outPipe = new BufferedPipe(1024); var res = await ServerStreamTests.StreamCreator.CreateConnectionAndStream( StreamState.Open, loggerProvider, inPipe, outPipe); // Close the connection var closeTask = res.conn.CloseNow(); // Expect end of stream await outPipe.AssertStreamEnd(); // If the connection was successfully closed close the incoming data // stream, since this is expected from a bidirectional stream implementation await inPipe.CloseAsync(); // Close should now be completed await closeTask; // The stream should be reset Assert.Equal(StreamState.Reset, res.stream.State); // Which also means that further writes/reads should fail await Assert.ThrowsAsync <StreamResetException>(async() => { await res.stream.WriteHeadersAsync( TestHeaders.DefaultStatusHeaders, true); }); await Assert.ThrowsAsync <StreamResetException>(async() => { await res.stream.ReadAllToArray(); }); }
public async Task ReceivingDataDirectlyAfterInformationalHeadersShouldBeAnError() { var inPipe = new BufferedPipe(1024); var outPipe = new BufferedPipe(1024); var res = await StreamCreator.CreateConnectionAndStream( StreamState.Open, loggerProvider, inPipe, outPipe); // Send informational headers to the client var infoHeaders = new HeaderField[] { new HeaderField { Name = ":status", Value = "100" }, new HeaderField { Name = "extension-field", Value = "bar" }, }; await inPipe.WriteHeaders(res.hEncoder, 1u, false, infoHeaders); var recvdHeaders = await res.stream.ReadHeadersAsync(); Assert.True(infoHeaders.SequenceEqual(recvdHeaders)); // Try to send data await inPipe.WriteData(1u, 100, null, true); // Expect to receive an error await outPipe.AssertResetStreamReception(1u, ErrorCode.ProtocolError); Assert.Equal(StreamState.Reset, res.stream.State); await Assert.ThrowsAsync <StreamResetException>( () => res.stream.ReadHeadersAsync()); }
public async Task ADataFrameOnAnUnknownStreamIdShouldTriggerAStreamReset( bool isServer, uint streamId) { // TODO: Add test cases for clients var inPipe = new BufferedPipe(1024); var outPipe = new BufferedPipe(1024); Func <IStream, bool> listener = (s) => true; var http2Con = await ConnectionUtils.BuildEstablishedConnection( isServer, inPipe, outPipe, loggerProvider, listener); // Establish a high stream ID, which means all below are invalid var hEncoder = new Encoder(); var createdStreamId = 111u; if (!isServer) { throw new Exception("For clients the stream must be created from connection"); } await inPipe.WriteHeaders( hEncoder, createdStreamId, false, DefaultGetHeaders); await inPipe.WriteData(streamId, 0); await outPipe.AssertResetStreamReception(streamId, ErrorCode.StreamClosed); }
public async Task ConnectionShouldCloseAndSignalDoneWhenWritingToOutputFails(bool isServer) { var inPipe = new BufferedPipe(1024); var outPipe = new BufferedPipe(1024); var failableOutPipe = new FailingPipe(outPipe); var http2Con = await ConnectionUtils.BuildEstablishedConnection( isServer, inPipe, failableOutPipe, loggerProvider); // Make the next write attempt fail failableOutPipe.FailNextWrite = true; // Send something which triggers a response await inPipe.WritePing(new byte[8], false); // Wait for the connection to close the outgoing part await outPipe.AssertStreamEnd(); Assert.True(failableOutPipe.CloseCalled); // If the connection was successfully closed close the incoming data // stream, since this is expected from a bidirectional stream implementation await inPipe.CloseAsync(); // Expect the connection to close within timeout var closed = http2Con.Done; Assert.True( closed == await Task.WhenAny(closed, Task.Delay(1000)), "Expected connection to close"); }
public async Task ConnectionShouldGoAwayOnUnsolicitedSettingsAck() { var inPipe = new BufferedPipe(1024); var outPipe = new BufferedPipe(1024); var http2Con = BuildConnection(true, Settings.Default, inPipe, outPipe); await ClientPreface.WriteAsync(inPipe); await inPipe.WriteSettings(Settings.Default); // Wait for remote settings await outPipe.ReadAndDiscardSettings(); // Wait for ack to our settings await outPipe.AssertSettingsAck(); // Acknowledge remote settings 2 times await inPipe.WriteSettingsAck(); await inPipe.WriteSettingsAck(); // Wait for GoAway due to multiple ACKs await outPipe.AssertGoAwayReception(ErrorCode.ProtocolError, 0); await outPipe.AssertStreamEnd(); }
public async Task ConnectionShouldGoAwayOnSettingsAckWithNonZeroLength( int frameLength) { var inPipe = new BufferedPipe(1024); var outPipe = new BufferedPipe(1024); var http2Con = BuildConnection(true, Settings.Default, inPipe, outPipe); await ClientPreface.WriteAsync(inPipe); await inPipe.WriteSettings(Settings.Default); // Wait for remote settings await outPipe.ReadAndDiscardSettings(); // Wait for ack to our settings await outPipe.AssertSettingsAck(); var fh = new FrameHeader { Type = FrameType.Settings, Flags = (byte)SettingsFrameFlags.Ack, StreamId = 0, Length = frameLength, }; await inPipe.WriteFrameHeader(fh); // Wait for GoAway due to wrong stream ID await outPipe.AssertGoAwayReception(ErrorCode.ProtocolError, 0); await outPipe.AssertStreamEnd(); }
public async Task ConnectionShouldGoAwayOnInvalidWindowSizeSettingWithFlowControlError() { var inPipe = new BufferedPipe(1024); var outPipe = new BufferedPipe(1024); var http2Con = BuildConnection(true, Settings.Default, inPipe, outPipe); await ClientPreface.WriteAsync(inPipe); var settings = Settings.Default; settings.InitialWindowSize = (uint)int.MaxValue + 1u; // Invalid var settingsData = new byte[settings.RequiredSize]; var fh = new FrameHeader { Type = FrameType.Settings, Length = settingsData.Length, Flags = 0, StreamId = 0, }; settings.EncodeInto(new ArraySegment <byte>(settingsData)); await inPipe.WriteFrameHeader(fh); await inPipe.WriteAsync(new ArraySegment <byte>(settingsData)); await outPipe.ReadAndDiscardSettings(); await outPipe.AssertGoAwayReception(ErrorCode.FlowControlError, 0u); await outPipe.AssertStreamEnd(); }
public async Task ConnectionShouldGoAwayOnInvalidSettingsFrameLength() { var inPipe = new BufferedPipe(1024); var outPipe = new BufferedPipe(1024); var http2Con = BuildConnection(true, Settings.Default, inPipe, outPipe); await ClientPreface.WriteAsync(inPipe); var settings = Settings.Default; var settingsData = new byte[settings.RequiredSize + 1]; // 1 byte extra var fh = new FrameHeader { Type = FrameType.Settings, Length = settingsData.Length, Flags = 0, StreamId = 0, }; settings.EncodeInto(new ArraySegment <byte>( settingsData, 0, settingsData.Length - 1)); await inPipe.WriteFrameHeader(fh); await inPipe.WriteAsync(new ArraySegment <byte>(settingsData)); await outPipe.ReadAndDiscardSettings(); await outPipe.AssertGoAwayReception(ErrorCode.ProtocolError, 0u); await outPipe.AssertStreamEnd(); }
public async Task ClientShouldGoAwayIfFirstFrameIsNotSettings() { var inPipe = new BufferedPipe(1024); var outPipe = new BufferedPipe(1024); var http2Con = BuildConnection(false, Settings.Default, inPipe, outPipe); var fh = new FrameHeader { Type = FrameType.Headers, Length = 0, Flags = 0, StreamId = 2 }; await inPipe.WriteFrameHeader(fh); var expected = Settings.Default; expected.EnablePush = false; await outPipe.ReadAndDiscardPreface(); await outPipe.ReadAndDiscardSettings(); await outPipe.AssertGoAwayReception(ErrorCode.ProtocolError, 0u); await outPipe.AssertStreamEnd(); }
public void CreatingAConnectionWithInvalidUpgradeShouldThrow() { var inPipe = new BufferedPipe(1024); var outPipe = new BufferedPipe(1024); var config = new ConnectionConfigurationBuilder(true) .UseStreamListener(s => false) .Build(); var builder = new ServerUpgradeRequestBuilder(); builder.SetHeaders(DefaultGetHeaders.ToList()); builder.SetHttp2Settings("!"); var upgrade = builder.Build(); Assert.False(upgrade.IsValid); var ex = Assert.Throws <ArgumentException>(() => { var conn = new Connection( config, inPipe, outPipe, new Connection.Options { Logger = loggerProvider.CreateLogger(""), ServerUpgradeRequest = upgrade, }); }); Assert.Equal( "The ServerUpgradeRequest is invalid.\n" + "Invalid upgrade requests must be denied by the HTTP/1 handler", ex.Message); }
public async Task ReadsShouldUnblockWrites() { var p = new BufferedPipe(70); var input = new byte[70]; var input2 = new byte[50]; var output = new byte[60]; for (var i = 0; i < 70; i++) { input[i] = (byte)i; } // Fill the complete buffer await p.WriteAsync(new ArraySegment <byte>(input)); var writeMoreTask = p.WriteAsync(new ArraySegment <byte>(input2)); // Read in the background to unblock var readTask = Task.Run(async() => { await Task.Delay(10); return(await p.ReadAsync(new ArraySegment <byte>(output)).AsTask()); }); // The next line would deadlock without the reader in the background await writeMoreTask; var res = await readTask; Assert.Equal(false, res.EndOfStream); Assert.Equal(60, res.BytesRead); for (var i = 0; i < 60; i++) { Assert.Equal(i, output[i]); } }
public async Task TrailersShouldBeCorrectlySent(bool isServer) { var inPipe = new BufferedPipe(1024); var outPipe = new BufferedPipe(1024); var r = await StreamCreator.CreateConnectionAndStream( isServer, loggerProvider, inPipe, outPipe); await r.stream.WriteAsync(new ArraySegment <byte>(new byte[0])); await outPipe.ReadAndDiscardData(1u, false, 0); // Send trailers await r.stream.WriteTrailersAsync(DefaultTrailingHeaders); // Check the received trailers var fh = await outPipe.ReadFrameHeaderWithTimeout(); Assert.Equal(FrameType.Headers, fh.Type); Assert.Equal(1u, fh.StreamId); var expectedFlags = HeadersFrameFlags.EndOfHeaders | HeadersFrameFlags.EndOfStream; Assert.Equal((byte)expectedFlags, fh.Flags); Assert.InRange(fh.Length, 1, 1024); var headerData = new byte[fh.Length]; await outPipe.ReadAllWithTimeout(new ArraySegment <byte>(headerData)); Assert.Equal(EncodedDefaultTrailingHeaders, headerData); }
public async Task StreamWindowUpdatesShouldRespectBufferState() { var inPipe = new BufferedPipe(1024); var outPipe = new BufferedPipe(1024); // Lower the initial window size so that stream window updates are // sent earlier than connection window updates var settings = Settings.Default; settings.InitialWindowSize = 16000; settings.MaxFrameSize = 1000000; var res = await ServerStreamTests.StreamCreator.CreateConnectionAndStream( StreamState.Open, loggerProvider, inPipe, outPipe, localSettings : settings); // Write 12k of data. Buffer amount: 12k. Remaining window: 4k await inPipe.WriteData(1u, 12000); // Read 5k of data. Buffer amount: 7k await res.stream.ReadAllWithTimeout(new ArraySegment <byte>(new byte[5000])); // This should not trigger a window update await inPipe.WritePing(new byte[8], false); await outPipe.ReadAndDiscardPong(); // Read 5k of data. Buffer amount: 2k await res.stream.ReadAllWithTimeout(new ArraySegment <byte>(new byte[5000])); // Expect a window update of 10k. Remaining window: 14k await outPipe.AssertWindowUpdate(1u, 10000); // Read 2k of data - buffer is now drained await res.stream.ReadAllWithTimeout(new ArraySegment <byte>(new byte[2000])); // This should not trigger a window update await inPipe.WritePing(new byte[8], false); await outPipe.ReadAndDiscardPong(); // Write 4k of data. Buffer amount: 4k. Remaining window: 10k await inPipe.WriteData(1u, 4000); // Read 4k of data. Buffer amount: 0k await res.stream.ReadAllWithTimeout(new ArraySegment <byte>(new byte[4000])); // This should not trigger a window update await inPipe.WritePing(new byte[8], false); await outPipe.ReadAndDiscardPong(); // Write 8k of data. Buffer amount: 8k. Remaining window: 2k await inPipe.WriteData(1u, 8000); // Read 5k of data. Buffer amount: 3k await res.stream.ReadAllWithTimeout(new ArraySegment <byte>(new byte[5000])); // Expect a window update of 11k. Remaining window: 13k await outPipe.AssertWindowUpdate(1u, 11000); }
public async Task OutgoingDataShouldRespectMaxFrameSize( bool isServer) { var inPipe = new BufferedPipe(1024); var outPipe = new BufferedPipe(1024); var r = await StreamCreator.CreateConnectionAndStream( isServer, loggerProvider, inPipe, outPipe); var dataSize = Settings.Default.MaxFrameSize + 10; var writeTask = Task.Run(async() => { var data = new byte[dataSize]; await r.stream.WriteAsync(new ArraySegment <byte>(data), true); }); // Expect to receive the data in fragments await outPipe.ReadAndDiscardData(1u, false, (int)Settings.Default.MaxFrameSize); await outPipe.ReadAndDiscardData(1u, true, 10); var doneTask = await Task.WhenAny(writeTask, Task.Delay(250)); Assert.True(writeTask == doneTask, "Expected write task to finish"); }
public async Task ShouldGoAwayWhenStreamWindowIsOverflowedThroughSettingsUpdate() { var inPipe = new BufferedPipe(1024); var outPipe = new BufferedPipe(1024); var res = await ServerStreamTests.StreamCreator.CreateConnectionAndStream( StreamState.Open, loggerProvider, inPipe, outPipe); // Let the remote increase the flow control window of the stream await inPipe.WriteWindowUpdate( 1u, (int)(int.MaxValue - Settings.Default.InitialWindowSize)); // Should be still alive await inPipe.WritePing(new byte[8], false); await outPipe.ReadAndDiscardPong(); // And now write new settings which overflow the window var newSettings = Settings.Default; newSettings.InitialWindowSize++; await inPipe.WriteSettings(newSettings); // Dead through overflow await outPipe.AssertGoAwayReception(ErrorCode.FlowControlError, 1u); }
public async Task SendingInvalidTrailersShouldTriggerAStreamReset() { var inPipe = new BufferedPipe(1024); var outPipe = new BufferedPipe(1024); var headers = new HeaderField[] { new HeaderField { Name = ":method", Value = "GET" }, new HeaderField { Name = ":scheme", Value = "http" }, new HeaderField { Name = ":path", Value = "/" }, }; var trailers = new HeaderField[] { new HeaderField { Name = ":method", Value = "GET" }, }; Func <IStream, bool> listener = (s) => true; var http2Con = await ConnectionUtils.BuildEstablishedConnection( true, inPipe, outPipe, loggerProvider, listener); var hEncoder = new Encoder(); await inPipe.WriteHeaders(hEncoder, 1, false, headers); await inPipe.WriteHeaders(hEncoder, 1, true, trailers); await outPipe.AssertResetStreamReception(1, ErrorCode.ProtocolError); }
public async Task PingAsyncShouldSendPingAndWaitForAssociatedAck() { var inPipe = new BufferedPipe(1024); var outPipe = new BufferedPipe(1024); var http2Con = await ConnectionUtils.BuildEstablishedConnection( true, inPipe, outPipe, loggerProvider); // Request ping var pingTask = http2Con.PingAsync(); // Expect ping emission var fh = await outPipe.ReadFrameHeaderWithTimeout(); Assert.Equal(FrameType.Ping, fh.Type); Assert.Equal(8, fh.Length); Assert.Equal(0, fh.Flags); Assert.Equal(0u, fh.StreamId); var pingData = new ArraySegment <byte>(new byte[8]); await outPipe.ReadAllWithTimeout(pingData); // Respond with pong fh.Flags = (byte)PingFrameFlags.Ack; await inPipe.WriteFrameHeader(fh); await inPipe.WriteAsync(pingData); // Await ping task to finish Assert.True( pingTask == await Task.WhenAny(pingTask, Task.Delay(200)), "Expected pingTask to finish"); }
public async Task ConnectionShouldCloseAndSignalDoneInCaseOfAProtocolError(bool isServer) { var inPipe = new BufferedPipe(1024); var outPipe = new BufferedPipe(1024); var http2Con = await ConnectionUtils.BuildEstablishedConnection( isServer, inPipe, outPipe, loggerProvider); // Cause a protocol error var fh = new FrameHeader { Type = FrameType.Data, StreamId = 0u, Flags = 0, Length = 0, }; await inPipe.WriteFrameHeader(fh); await outPipe.AssertGoAwayReception(ErrorCode.ProtocolError, 0u); await outPipe.AssertStreamEnd(); await inPipe.CloseAsync(); // Expect the connection to close within timeout var closed = http2Con.Done; Assert.True( closed == await Task.WhenAny(closed, Task.Delay(1000)), "Expected connection to close"); }
public async Task ConnectionShouldRespondToPingWithPong(bool isServer) { var inPipe = new BufferedPipe(1024); var outPipe = new BufferedPipe(1024); var http2Con = await ConnectionUtils.BuildEstablishedConnection( isServer, inPipe, outPipe, loggerProvider); var pingData = new byte[8]; for (var i = 0; i < pingData.Length; i++) { pingData[i] = (byte)i; } await inPipe.WritePing(pingData, false); var res = await outPipe.ReadFrameHeaderWithTimeout(); Assert.Equal(FrameType.Ping, res.Type); Assert.Equal(0u, res.StreamId); Assert.Equal(8, res.Length); Assert.Equal((byte)PingFrameFlags.Ack, res.Flags); var pongData = new byte[8]; await outPipe.ReadAllWithTimeout(new ArraySegment <byte>(pongData)); for (var i = 0; i < pingData.Length; i++) { Assert.Equal((byte)i, pongData[i]); } }
public async Task ConnectionShouldCloseAndSignalDoneWhenReadingFromInputFails(bool isServer) { var inPipe = new BufferedPipe(1024); var outPipe = new BufferedPipe(1024); var failableInPipe = new FailingPipe(inPipe); var http2Con = await ConnectionUtils.BuildEstablishedConnection( isServer, failableInPipe, outPipe, loggerProvider); // Make the next write attempt fail failableInPipe.FailNextRead = true; // Send something which triggers no response but will start a new read call await inPipe.WriteWindowUpdate(0, 128); // Wait for the connection to close the outgoing part await outPipe.AssertStreamEnd(); // If the connection was successfully closed close the incoming data // stream, since this is expected from a bidirectional stream implementation await inPipe.CloseAsync(); // Expect the connection to close within timeout var closed = http2Con.Done; Assert.True( closed == await Task.WhenAny(closed, Task.Delay(1000)), "Expected connection to close"); }
public async Task PingShouldFailWhenConnectionIsClosedAfterPingStart() { var inPipe = new BufferedPipe(1024); var outPipe = new BufferedPipe(1024); var http2Con = await ConnectionUtils.BuildEstablishedConnection( true, inPipe, outPipe, loggerProvider); // Request ping var pingTask = http2Con.PingAsync(); // Expect ping emission var fh = await outPipe.ReadFrameHeaderWithTimeout(); Assert.Equal(FrameType.Ping, fh.Type); Assert.Equal(8, fh.Length); Assert.Equal(0, fh.Flags); Assert.Equal(0u, fh.StreamId); var pingData = new ArraySegment <byte>(new byte[8]); await outPipe.ReadAllWithTimeout(pingData); // Close the connection await inPipe.CloseAsync(); await outPipe.AssertStreamEnd(); // Await ping to finish with exception var timeoutTask = Task.Delay(200); Assert.True( pingTask == await Task.WhenAny(pingTask, timeoutTask), "Expected pingTask to finish"); await Assert.ThrowsAsync <ConnectionClosedException>( async() => await pingTask); }
public async Task ServerShouldCloseTheConnectionIfCorrectPrefaceIsNotReceived() { var inPipe = new BufferedPipe(1024); var outPipe = new BufferedPipe(1024); var http2Con = BuildConnection(true, inPipe, outPipe); var b = new byte[ClientPreface.Length]; // Initialize with non-preface data for (var i = 0; i < b.Length; i++) { b[i] = 10; } await inPipe.WriteAsync(new ArraySegment <byte>(b)); // Wait for the response - a settings frame is expected first // But as there's a race condition the connection could be closed // before or after the settings frame was fully received try { await outPipe.ReadAndDiscardSettings(); var hdrBuf = new byte[FrameHeader.HeaderSize + 50]; var header = await FrameHeader.ReceiveAsync(outPipe, hdrBuf); Assert.Equal(FrameType.GoAway, header.Type); } catch (Exception e) { Assert.IsType <System.IO.EndOfStreamException>(e); } }
public async Task ShouldErrorIfPrefaceWasNotReceivedUntilTimeout() { var timeout = 50; var pipe = new BufferedPipe(50); await Assert.ThrowsAsync <TimeoutException>( () => ClientPreface.ReadAsync(pipe, timeout).AsTask()); }
public async Task RemoteGoAwayReasonShouldBeGettableFromTask( uint lastStreamId, ErrorCode errc, string debugString) { var inPipe = new BufferedPipe(1024); var outPipe = new BufferedPipe(1024); var res = await ServerStreamTests.StreamCreator.CreateConnectionAndStream( StreamState.Open, loggerProvider, inPipe, outPipe); var debugData = Encoding.ASCII.GetBytes(debugString); await inPipe.WriteGoAway(lastStreamId, errc, debugData); var readGoAwayTask = res.conn.RemoteGoAwayReason; Assert.True( readGoAwayTask == await Task.WhenAny(readGoAwayTask, Task.Delay(200)), "Expected to read GoAway data"); var reason = await readGoAwayTask; Assert.Equal(lastStreamId, reason.LastStreamId); Assert.Equal(errc, reason.ErrorCode); Assert.Equal(debugString, Encoding.ASCII.GetString( reason.DebugData.Array, reason.DebugData.Offset, reason.DebugData.Count)); }
public async Task PaddingViolationsOnStreamsShouldLeadToGoAway( bool onKnownStream, int frameLength, byte?padData) { var inPipe = new BufferedPipe(1024); var outPipe = new BufferedPipe(1024); var r = await ServerStreamTests.StreamCreator.CreateConnectionAndStream( StreamState.Open, loggerProvider, inPipe, outPipe); var fh = new FrameHeader { Type = FrameType.Data, StreamId = onKnownStream ? 1u : 2u, Flags = (byte)DataFrameFlags.Padded, Length = frameLength, }; await inPipe.WriteFrameHeader(fh); if (frameLength > 0) { var data = new byte[frameLength]; data[0] = padData.Value; await inPipe.WriteAsync(new ArraySegment <byte>(data)); } await outPipe.AssertGoAwayReception(ErrorCode.ProtocolError, 1u); }
public async Task ConnectionShouldIgnorePriorityData( bool isServer, uint streamId, uint streamDependency, bool isExclusive, byte weight) { var inPipe = new BufferedPipe(1024); var outPipe = new BufferedPipe(1024); var http2Con = await ConnectionUtils.BuildEstablishedConnection( isServer, inPipe, outPipe, loggerProvider); var prioData = new PriorityData { StreamDependency = streamDependency, StreamDependencyIsExclusive = isExclusive, Weight = weight, }; await inPipe.WritePriority(streamId, prioData); // Send a ping afterwards // If we get a response the priority frame in between was ignored var pingData = new byte[8]; for (var i = 0; i < 8; i++) { pingData[i] = (byte)i; } await inPipe.WritePing(pingData, false); await outPipe.ReadAndDiscardPong(); }
public async Task ReceivingHeadersOrDataOnAClosedStreamShouldTriggerAStreamReset( StreamState streamState, bool sendHeaders, bool sendData, bool sendTrailers) { var inPipe = new BufferedPipe(1024); var outPipe = new BufferedPipe(1024); var localCloseDone = new SemaphoreSlim(0); var res = await StreamCreator.CreateConnectionAndStream( streamState, loggerProvider, inPipe, outPipe); if (sendHeaders) { await inPipe.WriteHeaders(res.hEncoder, 1, false, DefaultGetHeaders); } if (sendData) { await inPipe.WriteData(1u, 0); } if (sendTrailers) { await inPipe.WriteHeaders(res.hEncoder, 1, true, DefaultGetHeaders); } await outPipe.AssertResetStreamReception(1u, ErrorCode.StreamClosed); var expectedState = streamState == StreamState.Closed ? StreamState.Closed : StreamState.Reset; Assert.Equal(expectedState, res.stream.State); }