Пример #1
0
        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();
        }
Пример #2
0
        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();
        }
Пример #3
0
        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();
        }
Пример #4
0
 public async Task ShouldErrorIfPrefaceWasNotReceivedUntilTimeout()
 {
     var timeout = 50;
     var pipe    = new BufferedPipe(50);
     await Assert.ThrowsAsync <TimeoutException>(
         () => ClientPreface.ReadAsync(pipe, timeout).AsTask());
 }
Пример #5
0
        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();
        }
Пример #6
0
        public async Task ShouldReadThePrefaceFromStream()
        {
            var buffer = new BufferReadStream(50, 50);

            Array.Copy(ClientPreface.Bytes, buffer.Buffer, ClientPreface.Length);
            buffer.Written = ClientPreface.Length;
            await ClientPreface.ReadAsync(buffer);
        }
Пример #7
0
        public async Task ShouldErrorIfStreamEnds()
        {
            var buffer = new BufferReadStream(50, 50);

            Array.Copy(ClientPreface.Bytes, buffer.Buffer, ClientPreface.Length);
            buffer.Written = ClientPreface.Length - 1; // Miss one byte
            await Assert.ThrowsAsync <EndOfStreamException>(
                () => ClientPreface.ReadAsync(buffer).AsTask());
        }
Пример #8
0
 public async Task ShouldNotErrorIfPrefaceWasReceivedWithinTimeout()
 {
     var timeout = 200;
     var pipe    = new BufferedPipe(50);
     var _       = Task.Run(async() =>
     {
         await pipe.WriteAsync(new ArraySegment <byte>(ClientPreface.Bytes));
     });
     await ClientPreface.ReadAsync(pipe, timeout);
 }
Пример #9
0
        public async Task ShouldWriteThePrefaceToStream()
        {
            var buffer = new BufferWriteStream(50);
            await ClientPreface.WriteAsync(buffer);

            Assert.Equal(ClientPreface.Length, buffer.Written);

            var pf = Encoding.ASCII.GetString(buffer.Buffer, 0, ClientPreface.Length);

            Assert.Equal(ClientPreface.String, pf);
        }
Пример #10
0
        public async Task ShouldErrorIfStreamDoesNotContainPreface()
        {
            var buffer = new BufferReadStream(50, 50);

            Array.Copy(ClientPreface.Bytes, buffer.Buffer, ClientPreface.Length);
            buffer.Buffer[22] = (byte)'l';
            buffer.Written    = ClientPreface.Length;
            var ex = await Assert.ThrowsAsync <Exception>(
                () => ClientPreface.ReadAsync(buffer).AsTask());

            Assert.Equal("Invalid prefix received", ex.Message);
        }
Пример #11
0
        public async Task ShouldErrorIfStreamWasClosedWithinTimeout()
        {
            var timeout = 200;
            var pipe    = new BufferedPipe(50);
            var _       = Task.Run(async() =>
            {
                await Task.Delay(10);
                await pipe.CloseAsync();
            });
            var ex = await Assert.ThrowsAsync <AggregateException>(
                () => ClientPreface.ReadAsync(pipe, timeout).AsTask());

            Assert.IsType <EndOfStreamException>(ex.InnerException);
        }
Пример #12
0
        public async Task ConnectionShouldAcknowledgeValidSettings()
        {
            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);

            await outPipe.ReadAndDiscardSettings();

            await outPipe.AssertSettingsAck();
        }
Пример #13
0
        public async Task ConnectionShouldAcceptSettingsAckAndNotGoAway()
        {
            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
            await inPipe.WriteSettingsAck();

            // And expect that no GoAway follows - which means a timeout happens on read
            await outPipe.AssertReadTimeout();
        }
Пример #14
0
        public async Task ServersShouldGoAwayIfFirstFrameIsNotSettings()
        {
            var inPipe   = new BufferedPipe(1024);
            var outPipe  = new BufferedPipe(1024);
            var http2Con = BuildConnection(true, Settings.Default, inPipe, outPipe);
            await ClientPreface.WriteAsync(inPipe);

            var fh = new FrameHeader
            {
                Type     = FrameType.Headers,
                Length   = 0,
                Flags    = 0,
                StreamId = 2,
            };
            await inPipe.WriteFrameHeader(fh);

            await outPipe.ReadAndDiscardSettings();

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

            await outPipe.AssertStreamEnd();
        }
Пример #15
0
        public async Task ConnectionShouldGoAwayOnSettingsStreamIdNonZero()
        {
            var inPipe   = new BufferedPipe(1024);
            var outPipe  = new BufferedPipe(1024);
            var http2Con = BuildConnection(true, Settings.Default, inPipe, outPipe);
            await ClientPreface.WriteAsync(inPipe);

            var fh = new FrameHeader
            {
                Type     = FrameType.Settings,
                Length   = Settings.Default.RequiredSize,
                Flags    = 0,
                StreamId = 1,
            };
            await inPipe.WriteFrameHeader(fh);

            await outPipe.ReadAndDiscardSettings();

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

            await outPipe.AssertStreamEnd();
        }
Пример #16
0
        public async Task ConnectionShouldGoAwayOnInvalidSettingsMaxLengthExceeded()
        {
            var inPipe   = new BufferedPipe(1024);
            var outPipe  = new BufferedPipe(1024);
            var http2Con = BuildConnection(true, Settings.Default, inPipe, outPipe);
            await ClientPreface.WriteAsync(inPipe);

            var fh = new FrameHeader
            {
                Type     = FrameType.Settings,
                Length   = (int)Settings.Default.MaxFrameSize + 1,
                Flags    = 0,
                StreamId = 0,
            };
            await inPipe.WriteFrameHeader(fh);

            await outPipe.ReadAndDiscardSettings();

            await outPipe.AssertGoAwayReception(ErrorCode.FrameSizeError, 0u);

            await outPipe.AssertStreamEnd();
        }
Пример #17
0
        public static async Task PerformHandshakes(
            this Connection connection,
            IBufferedPipe inputStream,
            IBufferedPipe outputStream,
            Settings?remoteSettings = null)
        {
            if (connection.IsServer)
            {
                await ClientPreface.WriteAsync(inputStream);
            }
            var rsettings = remoteSettings ?? Settings.Default;
            await inputStream.WriteSettings(rsettings);

            if (!connection.IsServer)
            {
                await outputStream.ReadAndDiscardPreface();
            }
            await outputStream.ReadAndDiscardSettings();

            await outputStream.AssertSettingsAck();

            await inputStream.WriteSettingsAck();
        }
Пример #18
0
        public async Task ConnectionShouldIgnoreAndAcknowledgeUnknownSettings()
        {
            var inPipe   = new BufferedPipe(1024);
            var outPipe  = new BufferedPipe(1024);
            var http2Con = BuildConnection(true, Settings.Default, inPipe, outPipe);

            await ClientPreface.WriteAsync(inPipe);

            await outPipe.ReadAndDiscardSettings();

            var settings = Settings.Default;
            // Create a buffer for normal settings plus 3 unknown ones
            var settingsBuffer = new byte[settings.RequiredSize + 18];

            settings.EncodeInto(new ArraySegment <byte>(
                                    settingsBuffer, 0, settings.RequiredSize));
            // Use some unknown settings IDs
            settingsBuffer[settings.RequiredSize]      = 0;
            settingsBuffer[settings.RequiredSize + 1]  = 10;
            settingsBuffer[settings.RequiredSize + 6]  = 10;
            settingsBuffer[settings.RequiredSize + 7]  = 20;
            settingsBuffer[settings.RequiredSize + 12] = 0xFF;
            settingsBuffer[settings.RequiredSize + 13] = 0xFF;
            var settingsHeader = new FrameHeader
            {
                Type     = FrameType.Settings,
                StreamId = 0,
                Flags    = 0,
                Length   = settingsBuffer.Length,
            };
            await inPipe.WriteFrameHeader(settingsHeader);

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

            // Check if the connection ACKs these settings
            await outPipe.AssertSettingsAck();
        }