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);
            }
        }
Exemplo n.º 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();
        }
Exemplo n.º 3
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();
        }
Exemplo n.º 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();
        }
Exemplo n.º 5
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();
        }
Exemplo n.º 6
0
        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();
        }
Exemplo n.º 7
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();
        }
        public async Task ServerShouldCloseTheConnectionIfNoPrefaceIsSent(
            int nrDummyPrefaceData)
        {
            var inPipe   = new BufferedPipe(1024);
            var outPipe  = new BufferedPipe(1024);
            var http2Con = BuildConnection(true, inPipe, outPipe);

            // Write some dummy data
            // All this data is not long enough to be a preface, so the
            // preface reception should time out
            if (nrDummyPrefaceData != 0)
            {
                var b = new byte[nrDummyPrefaceData];
                for (var i = 0; i < b.Length; i++)
                {
                    b[i] = 10;
                }
                await inPipe.WriteAsync(new ArraySegment <byte>(b));
            }

            // Settings will be sent by connection before the preface is
            // checked - so they must be discarded
            await outPipe.ReadAndDiscardSettings();

            // Wait for the stream to end within 400ms.
            // This is longer than the timeout in the connection waiting for the
            // preface

            var buf          = new byte[1];
            var readTask     = outPipe.ReadAsync(new ArraySegment <byte>(buf)).AsTask();
            var timeoutTask  = Task.Delay(400);
            var finishedTask = await Task.WhenAny(
                new Task[] { readTask, timeoutTask });

            if (ReferenceEquals(finishedTask, readTask))
            {
                var res = readTask.Result;
                Assert.Equal(true, res.EndOfStream);
                Assert.Equal(0, res.BytesRead);
                // Received end of stream
                return;
            }
            Assert.True(false,
                        "Expected connection to close outgoing stream. " +
                        "Got timeout");
        }
Exemplo n.º 9
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();
        }
Exemplo n.º 10
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();
        }
Exemplo n.º 11
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();
        }
Exemplo n.º 12
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();
        }
Exemplo n.º 13
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();
        }