Example #1
0
        public void FailedWhenUnknownFrameInMiddleOfHeaderBlock()
        {
            int streamId = 1;

            var input = Unpooled.Buffer();

            try
            {
                var headers = new DefaultHttp2Headers
                {
                    Authority = (AsciiString)"foo",
                    Method    = (AsciiString)"get",
                    Path      = (AsciiString)"/",
                    Scheme    = (AsciiString)"https"
                };
                Http2Flags flags = new Http2Flags().EndOfHeaders(false).EndOfStream(true);
                this.WriteHeaderFrame(input, streamId, headers, flags);
                Http2CodecUtil.WriteFrameHeader(input, 0, (Http2FrameTypes)0xff, new Http2Flags(), streamId);
                Assert.Throws <Http2Exception>(() => this.frameReader.ReadFrame(this.ctx.Object, input, this.listener.Object));
            }
            finally
            {
                input.Release();
            }
        }
        public void ClientShouldveSentPrefaceAndSettingsFrameWhenUserEventIsTriggered()
        {
            _connection.Setup(x => x.IsServer).Returns(false);
            _channel.Setup(x => x.IsActive).Returns(false);
            _handler = NewHandler();
            _channel.Setup(x => x.IsActive).Returns(true);

            var evt = Http2ConnectionPrefaceAndSettingsFrameWrittenEvent.Instance;

            AtomicBoolean verified = new AtomicBoolean(false);

            _ctx
            .Setup(x => x.FireUserEventTriggered(It.Is <object>(v => ReferenceEquals(v, evt))))
            .Returns <object>(msg =>
            {
                Assert.Same(msg, evt);
                _ctx.Verify(x => x.WriteAsync(It.Is <object>(d => Http2CodecUtil.ConnectionPrefaceBuf().Equals((IByteBuffer)d))));
                _encoder.Verify(
                    x => x.WriteSettingsAsync(
                        It.Is <IChannelHandlerContext>(v => v == _ctx.Object),
                        It.IsAny <Http2Settings>(),
                        It.IsAny <IPromise>()));
                verified.Value = true;
                return(_ctx.Object);
            });

            _handler.ChannelActive(_ctx.Object);
            Assert.True(verified.Value);
        }
        public void VerifyChannelHandlerCanBeReusedInPipeline()
        {
            _connection.Setup(x => x.IsServer).Returns(true);
            _handler = NewHandler();
            // Only read the connection preface...after preface is read internal state of Http2ConnectionHandler
            // is expected to change relative to the pipeline.
            IByteBuffer preface = Http2CodecUtil.ConnectionPrefaceBuf();

            _handler.ChannelRead(_ctx.Object, preface);
            _decoder.Verify(
                x => x.DecodeFrame(
                    It.IsAny <IChannelHandlerContext>(),
                    It.IsAny <IByteBuffer>(),
                    It.IsAny <List <object> >()),
                Times.Never());

            // Now remove and add the this.handler...this is setting up the test condition.
            _handler.HandlerRemoved(_ctx.Object);
            _handler.HandlerAdded(_ctx.Object);

            // Now verify we can continue as normal, reading connection preface plus more.
            IByteBuffer prefacePlusSome = AddSettingsHeader(Unpooled.Buffer().WriteBytes(Http2CodecUtil.ConnectionPrefaceBuf()));

            _handler.ChannelRead(_ctx.Object, prefacePlusSome);
            _decoder.Verify(
                x => x.DecodeFrame(
                    It.Is <IChannelHandlerContext>(v => v == _ctx.Object),
                    It.IsAny <IByteBuffer>(),
                    It.IsAny <List <object> >()),
                Times.AtLeastOnce);
        }
 public void ServerShouldNotSendClientPrefaceStringWhenActive()
 {
     _connection.Setup(x => x.IsServer).Returns(true);
     _channel.Setup(x => x.IsActive).Returns(false);
     _handler = NewHandler();
     _channel.Setup(x => x.IsActive).Returns(true);
     _handler.ChannelActive(_ctx.Object);
     _ctx.Verify(x => x.WriteAsync(It.Is <object>(d => Http2CodecUtil.ConnectionPrefaceBuf().Equals((IByteBuffer)d))), Times.Never());
 }
Example #5
0
        private static void TestUpgrade(Http2ConnectionHandler handler, IChannelHandler multiplexer)
        {
            IFullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.Http11, HttpMethod.Options, "*");

            request.Headers.Set(HttpHeaderNames.Host, "netty.io");
            request.Headers.Set(HttpHeaderNames.Connection, "Upgrade, HTTP2-Settings");
            request.Headers.Set(HttpHeaderNames.Upgrade, "h2c");
            request.Headers.Set((AsciiString)"HTTP2-Settings", "AAMAAABkAAQAAP__");

            var                     parent  = new Mock <IServerChannel>();
            EmbeddedChannel         channel = new EmbeddedChannel(parent.Object, DefaultChannelId.NewInstance(), false, true, new ChannelHandlerAdapter());
            IChannelHandlerContext  ctx     = channel.Pipeline.FirstContext();
            Http2ServerUpgradeCodec codec;

            if (multiplexer == null)
            {
                codec = new Http2ServerUpgradeCodec(handler);
            }
            else
            {
                codec = new Http2ServerUpgradeCodec((Http2FrameCodec)handler, multiplexer);
            }
            Assert.True(codec.PrepareUpgradeResponse(ctx, request, new DefaultHttpHeaders()));
            codec.UpgradeTo(ctx, request);
            // Flush the channel to ensure we write out all buffered data
            channel.Flush();

            channel.WriteInbound(Http2CodecUtil.ConnectionPrefaceBuf());
            Http2FrameInboundWriter writer = new Http2FrameInboundWriter(channel);

            writer.WriteInboundSettings(new Http2Settings());
            writer.WriteInboundRstStream(Http2CodecUtil.HttpUpgradeStreamId, Http2Error.Cancel);

            Assert.Same(handler, channel.Pipeline.Remove <Http2ConnectionHandler>());
            Assert.Null(channel.Pipeline.Get <Http2ConnectionHandler>());
            Assert.True(channel.Finish());

            // Check that the preface was send (a.k.a the settings frame)
            var settingsBuffer = channel.ReadOutbound <IByteBuffer>();

            Assert.NotNull(settingsBuffer);
            settingsBuffer.Release();

            var buf = channel.ReadOutbound <IByteBuffer>();

            Assert.NotNull(buf);
            buf.Release();

            Assert.Null(channel.ReadOutbound());
        }
            public override void ExceptionCaught(IChannelHandlerContext context, Exception cause)
            {
                Http2Exception e = Http2CodecUtil.GetEmbeddedHttp2Exception(cause);

                if (e != null)
                {
                    self.clientException = e;
                    self.clientLatch.SafeSignal();
                }
                else
                {
                    base.ExceptionCaught(context, cause);
                }
            }
Example #7
0
        public void FailedWhenWindowUpdateFrameWithZeroDelta()
        {
            var input = Unpooled.Buffer();

            try
            {
                Http2CodecUtil.WriteFrameHeader(input, 4, Http2FrameTypes.WindowUpdate, new Http2Flags(), 0);
                input.WriteInt(0);
                Assert.Throws <Http2Exception>(() => frameReader.ReadFrame(this.ctx.Object, input, this.listener.Object));
            }
            finally
            {
                input.Release();
            }
        }
Example #8
0
        private void WriteContinuationFrame(IByteBuffer output, int streamId, IHttp2Headers headers, Http2Flags flags)
        {
            IByteBuffer headerBlock = Unpooled.Buffer();

            try
            {
                hpackEncoder.EncodeHeaders(streamId, headerBlock, headers, NeverSensitiveDetector.Instance);
                Http2CodecUtil.WriteFrameHeader(output, headerBlock.ReadableBytes, Http2FrameTypes.Continuation, flags, streamId);
                output.WriteBytes(headerBlock, headerBlock.ReadableBytes);
            }
            finally
            {
                headerBlock.Release();
            }
        }
Example #9
0
        public void FailedWhenAckSettingsFrameWithPayload()
        {
            var input = Unpooled.Buffer();

            try
            {
                Http2CodecUtil.WriteFrameHeader(input, 1, Http2FrameTypes.Settings, new Http2Flags().Ack(true), 0);
                input.WriteByte(1);
                Assert.Throws <Http2Exception>(() => frameReader.ReadFrame(this.ctx.Object, input, this.listener.Object));
            }
            finally
            {
                input.Release();
            }
        }
Example #10
0
        public void ReadAckSettingsFrame()
        {
            var input = Unpooled.Buffer();

            try
            {
                Http2CodecUtil.WriteFrameHeader(input, 0, Http2FrameTypes.Settings, new Http2Flags().Ack(true), 0);
                frameReader.ReadFrame(this.ctx.Object, input, this.listener.Object);

                this.listener.Object.OnSettingsAckRead(this.ctx.Object);
            }
            finally
            {
                input.Release();
            }
        }
Example #11
0
        public void FailedWhenSettingsFrameWithWrongPayloadLength()
        {
            var input = Unpooled.Buffer();

            try
            {
                Http2CodecUtil.WriteFrameHeader(input, 8, Http2FrameTypes.Settings, new Http2Flags(), 0);
                input.WriteInt(Http2CodecUtil.SettingsMaxHeaderListSize);
                input.WriteInt(1024);
                Assert.Throws <Http2Exception>(() => frameReader.ReadFrame(this.ctx.Object, input, this.listener.Object));
            }
            finally
            {
                input.Release();
            }
        }
Example #12
0
        [Fact]//(timeout = 5000)
        public async Task NewOutboundStream()
        {
            IHttp2FrameStream stream = _frameCodec.NewStream();

            Assert.NotNull(stream);
            Assert.False(Http2CodecUtil.IsStreamIdValid(stream.Id));

            var listenerExecuted = new TaskCompletionSource();

            await _channel.WriteAndFlushAsync(new DefaultHttp2HeadersFrame(new DefaultHttp2Headers(), false) { Stream = stream });

            Assert.True(Http2CodecUtil.IsStreamIdValid(stream.Id));

            var data = Unpooled.Buffer().WriteZero(100);
            await _channel.WriteAndFlushAsync(new DefaultHttp2DataFrame(data) { Stream = stream });
        }
Example #13
0
        private void WriteHeaderFramePriorityPresent(IByteBuffer output, int streamId, IHttp2Headers headers, Http2Flags flags, int streamDependency, int weight)
        {
            IByteBuffer headerBlock = Unpooled.Buffer();

            try
            {
                headerBlock.WriteInt(streamDependency);
                headerBlock.WriteByte(weight - 1);
                hpackEncoder.EncodeHeaders(streamId, headerBlock, headers, NeverSensitiveDetector.Instance);
                Http2CodecUtil.WriteFrameHeader(output, headerBlock.ReadableBytes, Http2FrameTypes.Headers, flags, streamId);
                output.WriteBytes(headerBlock, headerBlock.ReadableBytes);
            }
            finally
            {
                headerBlock.Release();
            }
        }
Example #14
0
        private void SetUp(Http2FrameCodecBuilder frameCodecBuilder, Http2Settings initialRemoteSettings)
        {
            // Some tests call this method twice. Once with JUnit's @Before and once directly to pass special settings.
            // This call ensures that in case of two consecutive calls to setUp(), the previous channel is shutdown and
            // ByteBufs are released correctly.
            Dispose0();

            _frameWriter = Http2TestUtil.MockedFrameWriter();

            var builder = frameCodecBuilder.FrameWriter(_frameWriter.Object);

            builder.FrameLogger     = new Http2FrameLogger(Common.Internal.Logging.InternalLogLevel.TRACE);
            builder.InitialSettings = initialRemoteSettings;
            _frameCodec             = frameCodecBuilder.Build();
            _inboundHandler         = new LastInboundHandler();

            _channel            = new EmbeddedChannel();
            _frameInboundWriter = new Http2FrameInboundWriter(_channel);
            //channel.Connect(new InetSocketAddress(0));
            _channel.Pipeline.AddLast(_frameCodec);
            _channel.Pipeline.AddLast(_inboundHandler);
            _channel.Pipeline.FireChannelActive();

            // Handshake
            _frameWriter.Verify(
                x => x.WriteSettingsAsync(
                    It.Is <IChannelHandlerContext>(v => v == _frameCodec._ctx),
                    It.IsAny <Http2Settings>(),
                    It.IsAny <IPromise>()));
            _frameWriter.VerifyNoOtherCalls();
            _channel.WriteInbound(Http2CodecUtil.ConnectionPrefaceBuf());

            _frameInboundWriter.WriteInboundSettings(initialRemoteSettings);
            _frameWriter.Verify(
                x => x.WriteSettingsAckAsync(
                    It.Is <IChannelHandlerContext>(v => v == _frameCodec._ctx),
                    It.IsAny <IPromise>()));
            _frameInboundWriter.WriteInboundSettingsAck();

            var settingsFrame = _inboundHandler.ReadInbound <IHttp2SettingsFrame>();

            Assert.NotNull(settingsFrame);
            var settingsAckFrame = _inboundHandler.ReadInbound <IHttp2SettingsAckFrame>();

            Assert.NotNull(settingsAckFrame);
        }
Example #15
0
        public void ReadSettingsFrame()
        {
            var input = Unpooled.Buffer();

            try
            {
                Http2CodecUtil.WriteFrameHeader(input, 6, Http2FrameTypes.Settings, new Http2Flags(), 0);
                input.WriteShort(Http2CodecUtil.SettingsMaxHeaderListSize);
                input.WriteInt(1024);
                frameReader.ReadFrame(this.ctx.Object, input, this.listener.Object);

                this.listener.Object.OnSettingsRead(this.ctx.Object, new Http2Settings().MaxHeaderListSize(1024));
            }
            finally
            {
                input.Release();
            }
        }
Example #16
0
        private void WriteHeaderFrameWithData(IByteBuffer output, int streamId, IHttp2Headers headers, IByteBuffer dataPayload)
        {
            IByteBuffer headerBlock = Unpooled.Buffer();

            try
            {
                hpackEncoder.EncodeHeaders(streamId, headerBlock, headers, NeverSensitiveDetector.Instance);
                Http2CodecUtil.WriteFrameHeader(output, headerBlock.ReadableBytes, Http2FrameTypes.Headers,
                                                new Http2Flags().EndOfHeaders(true), streamId);
                output.WriteBytes(headerBlock, headerBlock.ReadableBytes);

                Http2CodecUtil.WriteFrameHeader(output, dataPayload.ReadableBytes, Http2FrameTypes.Data, new Http2Flags().EndOfStream(true), streamId);
                output.WriteBytes(dataPayload);
            }
            finally
            {
                headerBlock.Release();
            }
        }
Example #17
0
        public void FailedWhenDataFrameNotAssociateWithStream()
        {
            var input   = Unpooled.Buffer();
            var payload = Unpooled.Buffer();

            try
            {
                payload.WriteByte(1);

                Http2CodecUtil.WriteFrameHeader(input, payload.ReadableBytes, Http2FrameTypes.Data, new Http2Flags().EndOfStream(true), 0);
                input.WriteBytes(payload);
                Assert.Throws <Http2Exception>(() => frameReader.ReadFrame(this.ctx.Object, input, this.listener.Object));
            }
            finally
            {
                payload.Release();
                input.Release();
            }
        }
Example #18
0
        public void ReadUnknownFrame()
        {
            var input   = Unpooled.Buffer();
            var payload = Unpooled.Buffer();

            try
            {
                payload.WriteByte(1);

                Http2CodecUtil.WriteFrameHeader(input, payload.ReadableBytes, (Http2FrameTypes)0xff, new Http2Flags(), 0);
                input.WriteBytes(payload);
                this.frameReader.ReadFrame(this.ctx.Object, input, this.listener.Object);

                this.listener.Verify(x => x.OnUnknownFrame(this.ctx.Object, (Http2FrameTypes)0xff, 0, new Http2Flags(), payload.Slice(0, 1)));
            }
            finally
            {
                payload.Release();
                input.Release();
            }
        }
        public void ServerReceivingClientPrefaceStringFollowedByNonSettingsShouldHandleException()
        {
            _connection.Setup(x => x.IsServer).Returns(true);
            _handler = NewHandler();

            // Create a connection preface followed by a bunch of zeros (i.e. not a settings frame).
            IByteBuffer buf = Unpooled.Buffer().WriteBytes(Http2CodecUtil.ConnectionPrefaceBuf()).WriteZero(10);

            _handler.ChannelRead(_ctx.Object, buf);
            var captor = new ArgumentCaptor <IByteBuffer>();

            _frameWriter.Verify(
                x => x.WriteGoAwayAsync(
                    It.Is <IChannelHandlerContext>(v => v == _ctx.Object),
                    It.Is <int>(v => v == 0),
                    It.Is <Http2Error>(v => v == Http2Error.ProtocolError),
                    It.Is <IByteBuffer>(v => captor.Capture(v)),
                    It.Is <IPromise>(v => v == _promise)),
                Times.AtLeastOnce);
            Assert.Equal(0, captor.GetValue().ReferenceCount);
        }
Example #20
0
        public void MultipleOutboundStreams()
        {
            IHttp2StreamChannel childChannel1 = this.NewOutboundStream(new TestChannelInitializer());

            Assert.True(childChannel1.Active);
            Assert.False(Http2CodecUtil.IsStreamIdValid(childChannel1.Stream.Id));
            IHttp2StreamChannel childChannel2 = this.NewOutboundStream(new TestChannelInitializer());

            Assert.True(childChannel2.Active);
            Assert.False(Http2CodecUtil.IsStreamIdValid(childChannel2.Stream.Id));

            IHttp2Headers headers1 = new DefaultHttp2Headers();
            IHttp2Headers headers2 = new DefaultHttp2Headers();

            // Test that streams can be made active (headers sent) in different order than the corresponding channels
            // have been created.
            childChannel2.WriteAndFlushAsync(new DefaultHttp2HeadersFrame(headers2));
            childChannel1.WriteAndFlushAsync(new DefaultHttp2HeadersFrame(headers1));

            IHttp2HeadersFrame headersFrame2 = serverLastInboundHandler.BlockingReadInbound <IHttp2HeadersFrame>();

            Assert.NotNull(headersFrame2);
            Assert.Equal(3, headersFrame2.Stream.Id);

            IHttp2HeadersFrame headersFrame1 = serverLastInboundHandler.BlockingReadInbound <IHttp2HeadersFrame>();

            Assert.NotNull(headersFrame1);
            Assert.Equal(5, headersFrame1.Stream.Id);

            Assert.Equal(3, childChannel2.Stream.Id);
            Assert.Equal(5, childChannel1.Stream.Id);

            childChannel1.CloseAsync();
            childChannel2.CloseAsync();

            serverLastInboundHandler.CheckException();
        }
Example #21
0
        public void NewOutboundStreamsShouldBeBuffered()
        {
            var builder = Http2FrameCodecBuilder.ForServer();

            builder.EncoderEnforceMaxConcurrentStreams = true;
            SetUp(builder, new Http2Settings().MaxConcurrentStreams(1));

            var stream1 = _frameCodec.NewStream();
            var stream2 = _frameCodec.NewStream();

            var promise1 = _channel.NewPromise();
            var promise2 = _channel.NewPromise();

            _channel.WriteAndFlushAsync(new DefaultHttp2HeadersFrame(new DefaultHttp2Headers())
            {
                Stream = stream1
            }, promise1);
            _channel.WriteAndFlushAsync(new DefaultHttp2HeadersFrame(new DefaultHttp2Headers())
            {
                Stream = stream2
            }, promise2);

            Assert.True(Http2CodecUtil.IsStreamIdValid(stream1.Id));
            _channel.RunPendingTasks();
            Assert.True(Http2CodecUtil.IsStreamIdValid(stream2.Id));

            Assert.True(promise1.IsSuccess);
            Assert.False(promise2.IsCompleted);

            // Increase concurrent streams limit to 2
            _frameInboundWriter.WriteInboundSettings(new Http2Settings().MaxConcurrentStreams(2));

            _channel.Flush();

            Assert.True(promise2.IsSuccess);
        }
Example #22
0
 private static void WritePriorityFrame(IByteBuffer output, int streamId, int streamDependency, int weight)
 {
     Http2CodecUtil.WriteFrameHeader(output, 5, Http2FrameTypes.Priority, new Http2Flags(), streamId);
     output.WriteInt(streamDependency);
     output.WriteByte(weight - 1);
 }
Example #23
0
        public void MultipleNewOutboundStreamsShouldBeBuffered()
        {
            var builder = Http2FrameCodecBuilder.ForServer();

            builder.EncoderEnforceMaxConcurrentStreams = true;
            // We use a limit of 1 and then increase it step by step.
            SetUp(builder, new Http2Settings().MaxConcurrentStreams(1));

            IHttp2FrameStream stream1 = _frameCodec.NewStream();
            IHttp2FrameStream stream2 = _frameCodec.NewStream();
            IHttp2FrameStream stream3 = _frameCodec.NewStream();

            IPromise promise1 = _channel.NewPromise();
            IPromise promise2 = _channel.NewPromise();
            IPromise promise3 = _channel.NewPromise();

            _channel.WriteAndFlushAsync(new DefaultHttp2HeadersFrame(new DefaultHttp2Headers())
            {
                Stream = stream1
            }, promise1);
            _channel.WriteAndFlushAsync(new DefaultHttp2HeadersFrame(new DefaultHttp2Headers())
            {
                Stream = stream2
            }, promise2);
            _channel.WriteAndFlushAsync(new DefaultHttp2HeadersFrame(new DefaultHttp2Headers())
            {
                Stream = stream3
            }, promise3);

            Assert.True(Http2CodecUtil.IsStreamIdValid(stream1.Id));
            _channel.RunPendingTasks();
            Assert.True(Http2CodecUtil.IsStreamIdValid(stream2.Id));

            if (promise1.IsCompleted)
            {
                Assert.True(promise1.Task.IsSuccess());
            }
            else
            {
                try
                {
                    promise1.Task.GetAwaiter().GetResult();
                }
                catch (Exception)
                {
                    Assert.False(true);
                }
            }
            Assert.False(promise2.IsCompleted);
            Assert.False(promise3.IsCompleted);

            // Increase concurrent streams limit to 2
            _frameInboundWriter.WriteInboundSettings(new Http2Settings().MaxConcurrentStreams(2));
            _channel.Flush();

            // As we increased the limit to 2 we should have also succeed the second frame.
            if (promise2.IsCompleted)
            {
                Assert.True(promise2.Task.IsSuccess());
            }
            else
            {
                try
                {
                    promise2.Task.GetAwaiter().GetResult();
                }
                catch (Exception)
                {
                    Assert.False(true);
                }
            }
            Assert.False(promise3.IsCompleted);

            _frameInboundWriter.WriteInboundSettings(new Http2Settings().MaxConcurrentStreams(3));
            _channel.Flush();

            // With the max streams of 3 all streams should be succeed now.
            if (promise3.IsCompleted)
            {
                Assert.True(promise3.Task.IsSuccess());
            }
            else
            {
                try
                {
                    promise3.Task.GetAwaiter().GetResult();
                }
                catch (Exception)
                {
                    Assert.False(true);
                }
            }

            Assert.False(_channel.FinishAndReleaseAll());
        }
        public void ServerReceivingValidClientPrefaceStringShouldContinueReadingFrames()
        {
            _connection.Setup(x => x.IsServer).Returns(true);
            _handler = NewHandler();
            IByteBuffer prefacePlusSome = AddSettingsHeader(Unpooled.Buffer().WriteBytes(Http2CodecUtil.ConnectionPrefaceBuf()));

            _handler.ChannelRead(_ctx.Object, prefacePlusSome);
            _decoder.Verify(
                x => x.DecodeFrame(
                    It.Is <IChannelHandlerContext>(v => v == _ctx.Object),
                    It.IsAny <IByteBuffer>(),
                    It.IsAny <List <object> >()),
                Times.AtLeastOnce);
        }