Пример #1
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();
        }
Пример #2
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();
        }
Пример #3
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();
        }
Пример #4
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();
        }
Пример #5
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);
        }
Пример #6
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();
        }
Пример #7
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();
        }
Пример #8
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();
        }
Пример #9
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();
        }
Пример #10
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();
        }
Пример #11
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();
        }
Пример #12
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();
        }