public override void ExceptionCaught(IChannelHandlerContext ctx, Exception cause)
 {
     // IOException is fine as it will also close the channel and may just be a connection reset.
     if (!(cause is SocketException))
     {
         _clientReceived.Value = cause;
         _latch.SafeSignal();
     }
 }
Example #2
0
 public override void UserEventTriggered(IChannelHandlerContext ctx, object evt)
 {
     if (evt == ChannelInputShutdownEvent.Instance && _allowHalfClosed)
     {
         _clientHalfClosedLatch.SafeSignal();
     }
     else if (evt == ChannelInputShutdownReadComplete.Instance)
     {
         ctx.CloseAsync();
     }
 }
Example #3
0
        public Http2MultiplexCodecBuilderTest(EventLoopGroupFixture fixture)
        {
            this.fixture = fixture;

            var          serverChannelLatch = new CountdownEvent(1);
            LocalAddress serverAddress      = new LocalAddress(this.GetType().Name);

            this.serverLastInboundHandler = new SharableLastInboundHandler();
            ServerBootstrap sb = new ServerBootstrap()
                                 .Channel <LocalServerChannel>()
                                 .Group(fixture.Group)
                                 .ChildHandler(new ActionChannelInitializer <IChannel>(ch =>
            {
                this.serverConnectedChannel = ch;
                ch.Pipeline.AddLast(new Http2MultiplexCodecBuilder(true, new ActionChannelInitializer <IChannel>(ch0 =>
                {
                    ch0.Pipeline.AddLast(new TestServerChannelHandler());
                    ch0.Pipeline.AddLast(this.serverLastInboundHandler);
                })).Build());
                serverChannelLatch.SafeSignal();
            }));

            this.serverChannel = sb.BindAsync(serverAddress).GetAwaiter().GetResult();
            Bootstrap cb = new Bootstrap()
                           .Channel <LocalChannel>()
                           .Group(fixture.Group)
                           .Handler(new Http2MultiplexCodecBuilder(false, new ActionChannelInitializer <IChannel>(ch =>
            {
                Assert.False(true, "Should not be called for outbound streams");
            })).Build());

            this.clientChannel = cb.ConnectAsync(serverAddress).GetAwaiter().GetResult();
            Assert.True(serverChannelLatch.Wait(TimeSpan.FromSeconds(5)));
        }
 public override void UserEventTriggered(IChannelHandlerContext ctx, object evt)
 {
     if (ReferenceEquals(evt, Http2ConnectionPrefaceAndSettingsFrameWrittenEvent.Instance))
     {
         _latch.SafeSignal();
     }
 }
Example #5
0
        public void RemoveAllStreamsWhileIteratingActiveStreams()
        {
            var remote = client.Remote;
            var local  = client.Local;

            for (int c = 3, s = 2; c < 5000; c += 2, s += 2)
            {
                local.CreateStream(c, false);
                remote.CreateStream(s, false);
            }
            var promise = this.fixture.Group.GetNext().NewPromise();
            var latch   = new CountdownEvent(client.NumActiveStreams);

            bool localVisit(IHttp2Stream stream)
            {
                var closeFuture = client.CloseAsync(promise);

                closeFuture.ContinueWith(t =>
                {
                    Assert.True(t.IsCompleted);
                    latch.SafeSignal();
                }, TaskContinuationOptions.ExecuteSynchronously);
                return(true);
            }

            client.ForEachActiveStream(localVisit);
            Assert.True(latch.Wait(TimeSpan.FromSeconds(5)));
        }
Example #6
0
        private async Task BootstrapEnv(int serverOutSize)
        {
            var prefaceWrittenLatch = new CountdownEvent(1);

            this.serverOut   = new MemoryStream(serverOutSize);
            this.serverLatch = new CountdownEvent(1);
            this.sb          = new ServerBootstrap();
            this.cb          = new Bootstrap();

            // Streams are created before the normal flow for this test, so these connection must be initialized up front.
            this.serverConnection = new DefaultHttp2Connection(true);
            this.clientConnection = new DefaultHttp2Connection(false);

            this.serverConnection.AddListener(new TestHttp2ConnectionAdapter(this.serverLatch));

            this.serverListener
            .Setup(x => x.OnDataRead(
                       It.IsAny <IChannelHandlerContext>(),
                       It.IsAny <int>(),
                       It.IsAny <IByteBuffer>(),
                       It.IsAny <int>(),
                       It.IsAny <bool>()))
            .Returns <IChannelHandlerContext, int, IByteBuffer, int, bool>((ctx, id, buf, padding, end) =>
            {
                int processedBytes = buf.ReadableBytes + padding;

                buf.ReadBytes(this.serverOut, buf.ReadableBytes);
                if (end)
                {
                    this.serverConnection.Stream(id).Close();
                }
                return(processedBytes);
            });
            var serverChannelLatch = new CountdownEvent(1);

            this.SetupServerBootstrap(this.sb);
            this.sb.ChildHandler(new ActionChannelInitializer <IChannel>(ch =>
            {
                this.SetInitialServerChannelPipeline(ch);
                serverChannelLatch.SafeSignal();
            }));

            this.SetupBootstrap(this.cb);
            this.cb.Handler(new ActionChannelInitializer <IChannel>(ch =>
            {
                this.SetInitialChannelPipeline(ch);
                ch.Pipeline.AddLast(new TestChannelHandlerAdapter(prefaceWrittenLatch));
            }));

            var loopback = IPAddress.IPv6Loopback;

            this.serverChannel = await this.sb.BindAsync(loopback, Port);

            var port = ((IPEndPoint)this.serverChannel.LocalAddress).Port;
            var ccf  = this.cb.ConnectAsync(loopback, port);

            this.clientChannel = await ccf;
            Assert.True(prefaceWrittenLatch.Wait(TimeSpan.FromSeconds(10)));
            Assert.True(serverChannelLatch.Wait(TimeSpan.FromSeconds(10)));
        }
Example #7
0
        private async Task TestNoRstIfSoLingerOnClose0(ServerBootstrap sb, Bootstrap cb)
        {
            AtomicReference <IChannel>  serverChannelRef = new AtomicReference <IChannel>();
            AtomicReference <Exception> throwableRef     = new AtomicReference <Exception>();
            CountdownEvent latch  = new CountdownEvent(1);
            CountdownEvent latch2 = new CountdownEvent(1);

            sb.ChildHandler(new ActionChannelInitializer <IChannel>(ch =>
            {
                serverChannelRef.CompareAndSet(null, ch);
                latch.SafeSignal();
            }));
            cb.Handler(new ActionChannelInitializer <IChannel>(ch =>
            {
                ch.Pipeline.AddLast(new ChannelInboundHandlerAdapter0(throwableRef, latch2));
            }));
            IChannel sc = await sb.BindAsync();

            await cb.ConnectAsync(sc.LocalAddress);

            // Wait for the server to get setup.
            latch.Wait();

            // The server has SO_LINGER=0 and so it must send a RST when close is called.
            serverChannelRef.Value.CloseAsync().Ignore();

            // Wait for the client to get channelInactive.
            latch2.Wait();

            // Verify the client did not received a RST.
            Assert.Null(throwableRef.Value);
        }
Example #8
0
        private void BootstrapEnv(int requestCountDown, int serverSettingsAckCount, int trailersCount)
        {
            var prefaceWrittenLatch = new CountdownEvent(1);
            var serverChannelLatch  = new CountdownEvent(1);

            this.requestLatch           = new CountdownEvent(requestCountDown);
            this.serverSettingsAckLatch = new CountdownEvent(serverSettingsAckCount);
            this.trailersLatch          = trailersCount == 0 ? null : new CountdownEvent(trailersCount);

            this.sb = new ServerBootstrap();
            this.cb = new Bootstrap();

            this.SetupServerBootstrap(this.sb);
            this.sb.ChildHandler(new ActionChannelInitializer <IChannel>(ch =>
            {
                this.SetInitialServerChannelPipeline(ch);
                serverChannelLatch.SafeSignal();
            }));

            this.SetupBootstrap(this.cb);
            this.cb.Handler(new ActionChannelInitializer <IChannel>(ch =>
            {
                this.SetInitialChannelPipeline(ch);
                ch.Pipeline.AddLast(new TestChannelHandlerAdapter(prefaceWrittenLatch));
            }));

            this.StartBootstrap();

            Assert.True(prefaceWrittenLatch.Wait(TimeSpan.FromSeconds(5)));
            Assert.True(serverChannelLatch.Wait(TimeSpan.FromSeconds(WAIT_TIME_SECONDS)));
        }
 public override void ChannelRead(IChannelHandlerContext context, object message)
 {
     if (message is IHttp2SettingsFrame)
     {
         _clientSettingsLatch.SafeSignal();
     }
     ReferenceCountUtil.Release(message);
 }
 public override void ChannelRead(IChannelHandlerContext ctx, object msg)
 {
     if (msg is IHttp2DataFrame http2DataFrame && http2DataFrame.IsEndStream)
     {
         _latch.SafeSignal();
     }
     ReferenceCountUtil.Release(msg);
 }
Example #11
0
            public override void ChannelActive(IChannelHandlerContext ctx)
            {
                IByteBuffer buf = ctx.Allocator.Buffer(_totalServerBytesWritten);

                buf.SetWriterIndex(buf.Capacity);
                ctx.WriteAndFlushAsync(buf).CloseOnComplete(ctx.Channel);
                _serverInitializedLatch.SafeSignal();
            }
Example #12
0
 private void CheckPrematureClose()
 {
     if (_bytesRead < _expectedBytes)
     {
         _causeRef.Value = new InvalidOperationException("follower premature close");
         _doneLatch.SafeSignal();
     }
 }
 public override void ChannelRead(IChannelHandlerContext context, object message)
 {
     if (message is IHttp2SettingsAckFrame)
     {
         _serverAckOneLatch.SafeSignal();
         _serverAckAllLatch.SafeSignal();
     }
     ReferenceCountUtil.Release(message);
 }
Example #14
0
            public override void ChannelActive(IChannelHandlerContext ctx)
            {
                IByteBuffer buf = ctx.Allocator.Buffer(_totalServerBytesWritten);

                buf.SetWriterIndex(buf.Capacity);
                ctx.WriteAndFlushAsync(buf).ContinueWith(t =>
                {
                    ((IDuplexChannel)ctx.Channel).ShutdownOutputAsync();
                }, TaskContinuationOptions.ExecuteSynchronously);
                _serverInitializedLatch.SafeSignal();
            }
Example #15
0
 public override void ChannelReadComplete(IChannelHandlerContext ctx)
 {
     _clientReadCompletes.Increment();
     if (_bytesRead == _totalServerBytesWritten)
     {
         _clientReadAllDataLatch.SafeSignal();
     }
     if (!_autoRead)
     {
         ctx.Read();
     }
 }
Example #16
0
            public override void ChannelActive(IChannelHandlerContext ctx)
            {
                IByteBuffer buf = ctx.Allocator.Buffer(_expectedBytes);

                buf.SetWriterIndex(buf.WriterIndex + _expectedBytes);
                ctx.WriteAndFlushAsync(buf.RetainedDuplicate());

                // We wait here to ensure that we write before we have a chance to process the outbound
                // shutdown event.
                _followerCloseLatch.Wait();

                // This write should fail, but we should still be allowed to read the peer's data
                ctx.WriteAndFlushAsync(buf).ContinueWith(t =>
                {
                    if (t.IsSuccess())
                    {
                        _causeRef.Value = new InvalidOperationException("second write should have failed!");
                        _doneLatch.SafeSignal();
                    }
                }, TaskContinuationOptions.ExecuteSynchronously);
            }
Example #17
0
 public override void ChannelRead(IChannelHandlerContext ctx, object msg)
 {
     if (msg is IByteBuffer buf)
     {
         _totalRead += buf.ReadableBytes;
         if (_totalRead == _expectedBytes)
         {
             _latch.SafeSignal();
         }
     }
     ReferenceCountUtil.Release(msg);
 }
Example #18
0
        void TestRemoveAllStreams()
        {
            var latch       = new CountdownEvent(1);
            var promise     = this.fixture.Group.GetNext().NewPromise();
            var closeFuture = this.client.CloseAsync(promise);

            closeFuture.ContinueWith(t =>
            {
                Assert.True(t.IsCompleted);
                latch.SafeSignal();
            }, TaskContinuationOptions.ExecuteSynchronously);
            Assert.True(latch.Wait(TimeSpan.FromSeconds(5)));
        }
Example #19
0
            public override void ChannelActive(IChannelHandlerContext ctx)
            {
                byte[] data = new byte[1024];
                _random.NextBytes(data);

                _buf = ctx.Allocator.Buffer();
                // call retain on it so it can't be put back on the pool
                _buf.WriteBytes(data).Retain();
                ctx.Channel.WriteAndFlushAsync(_buf).ContinueWith(t =>
                {
                    _latch.SafeSignal();
                });
            }
Example #20
0
 public override void ExceptionCaught(IChannelHandlerContext context, Exception exception)
 {
     if (_count.Increment() <= 2)
     {
         _latch1.SafeSignal();
     }
     else
     {
         _latch2.SafeSignal();
     }
     // This should not throw any exception.
     context.CloseAsync();
 }
Example #21
0
        private async Task TestSoLingerZeroCausesOnlyRstOnClose0(ServerBootstrap sb, Bootstrap cb)
        {
            AtomicReference <IChannel>  serverChannelRef = new AtomicReference <IChannel>();
            AtomicReference <Exception> throwableRef     = new AtomicReference <Exception>();
            CountdownEvent latch  = new CountdownEvent(1);
            CountdownEvent latch2 = new CountdownEvent(1);

            // SO_LINGER=0 means that we must send ONLY a RST when closing (not a FIN + RST).
            sb.ChildOption(ChannelOption.SoLinger, 0);
            sb.ChildHandler(new ActionChannelInitializer <IChannel>(ch =>
            {
                serverChannelRef.CompareAndSet(null, ch);
                latch.SafeSignal();
            }));
            cb.Handler(new ActionChannelInitializer <IChannel>(ch =>
            {
                ch.Pipeline.AddLast(new ChannelInboundHandlerAdapter0(throwableRef, latch2));
            }));
            IChannel sc = await sb.BindAsync();

            IChannel cc = await cb.ConnectAsync(sc.LocalAddress);

            // Wait for the server to get setup.
            latch.Wait();

            // The server has SO_LINGER=0 and so it must send a RST when close is called.
            serverChannelRef.Value.CloseAsync().Ignore();

            // Wait for the client to get channelInactive.
            latch2.Wait();

            // Verify the client received a RST.
            var cause = throwableRef.Value;

            if (cause is object)
            {
                Assert.True(cause is SocketException, "actual [type, message]: [" + cause.GetType() + ", " + cause.Message + "]");

                //AssertRstOnCloseException((SocketException)cause, cc);
                Assert.True(cause.Message.Contains("reset") || cause.Message.Contains("closed"), "actual message: " + cause.Message);
            }
        }
        private void BootstrapEnv(int clientLatchCount, int clientLatchCount2, int serverLatchCount,
                                  int serverLatchCount2, int settingsLatchCount)
        {
            var prefaceWrittenLatch = new CountdownEvent(1);

            this.clientDelegator        = null;
            this.serverDelegator        = null;
            this.serverConnectedChannel = null;
            this.maxContentLength       = 1024;
            var serverChannelLatch = new CountdownEvent(1);

            this.serverLatch   = new CountdownEvent(serverLatchCount);
            this.clientLatch   = new CountdownEvent(clientLatchCount);
            this.serverLatch2  = new CountdownEvent(serverLatchCount2);
            this.clientLatch2  = new CountdownEvent(clientLatchCount2);
            this.settingsLatch = new CountdownEvent(settingsLatchCount);

            this.sb = new ServerBootstrap();
            this.cb = new Bootstrap();

            this.SetupServerBootstrap(this.sb);
            this.sb.ChildHandler(new ActionChannelInitializer <IChannel>(ch =>
            {
                this.SetInitialServerChannelPipeline(ch);
                serverChannelLatch.SafeSignal();
            }));

            this.SetupBootstrap(this.cb);
            this.cb.Handler(new ActionChannelInitializer <IChannel>(ch =>
            {
                this.SetInitialChannelPipeline(ch);

                ch.Pipeline.AddLast(new TestChannelHandlerAdapterEC(this));

                ch.Pipeline.AddLast(new TestChannelHandlerAdapter(prefaceWrittenLatch));
            }));

            this.StartBootstrap();

            Assert.True(prefaceWrittenLatch.Wait(TimeSpan.FromSeconds(5)));
            Assert.True(serverChannelLatch.Wait(TimeSpan.FromSeconds(5)));
        }
Example #23
0
 protected override void ChannelRead0(IChannelHandlerContext ctx, IByteBuffer msg)
 {
     _bytesRead += msg.ReadableBytes;
     if (_bytesRead >= _expectedBytes)
     {
         // We write a reply and immediately close our end of the socket.
         IByteBuffer buf = ctx.Allocator.Buffer(_expectedBytes);
         buf.SetWriterIndex(buf.WriterIndex + _expectedBytes);
         ctx.WriteAndFlushAsync(buf).ContinueWith(t =>
         {
             ctx.Channel.CloseAsync().ContinueWith(task =>
             {
                 // This is a bit racy but there is no better way how to handle this in Java11.
                 // The problem is that on close() the underlying FD will not actually be closed directly
                 // but the close will be done after the Selector did process all events. Because of
                 // this we will need to give it a bit time to ensure the FD is actual closed before we
                 // count down the latch and try to write.
                 _followerCloseLatch.SafeSignal();
                 //ctx.Channel.EventLoop.Schedule(() => _followerCloseLatch.SafeSignal(), TimeSpan.FromMilliseconds(200));
             }, TaskContinuationOptions.ExecuteSynchronously);
         }, TaskContinuationOptions.ExecuteSynchronously);
     }
 }
Example #24
0
        public void RemoveAllStreamsWhileIteratingActiveStreamsAndExceptionOccurs()
        {
            var remote = client.Remote;
            var local  = client.Local;

            for (int c = 3, s = 2; c < 5000; c += 2, s += 2)
            {
                local.CreateStream(c, false);
                remote.CreateStream(s, false);
            }
            var promise = this.fixture.Group.GetNext().NewPromise();
            var latch   = new CountdownEvent(1);

            try
            {
                bool localVisit(IHttp2Stream stream)
                {
                    // This close call is basically a noop, because the following statement will throw an exception.
                    client.CloseAsync(promise);
                    // Do an invalid operation while iterating.
                    remote.CreateStream(3, false);
                    return(true);
                }
                client.ForEachActiveStream(localVisit);
            }
            catch (Http2Exception)
            {
                var closeFuture = client.CloseAsync(promise);
                closeFuture.ContinueWith(t =>
                {
                    Assert.True(t.IsCompleted);
                    latch.SafeSignal();
                }, TaskContinuationOptions.ExecuteSynchronously);
            }
            Assert.True(latch.Wait(TimeSpan.FromSeconds(5)));
        }
 protected override void ChannelRead0(IChannelHandlerContext ctx, object msg)
 {
     _clientReadLatch.SafeSignal();
 }
 public override void ChannelActive(IChannelHandlerContext context)
 {
     _serverConnectedChannelRef.Value = context.Channel;
     _serverConnectedChannelLatch.SafeSignal();
 }
Example #27
0
 public override void ChannelInactive(IChannelHandlerContext ctx)
 {
     _latch2.SafeSignal();
 }
 public override void ChannelRead(IChannelHandlerContext ctx, object msg)
 {
     _acceptorReadLatch.SafeSignal();
     ctx.FireChannelRead(msg);
 }
        private async Task TestAutoReadOffNoDataReadUntilReadCalled0(ServerBootstrap sb, Bootstrap cb, bool isLibuvServer)
        {
            IChannel  serverChannel = null;
            IChannel  clientChannel = null;
            const int sleepMs       = 100;

            try
            {
                sb.Option(ChannelOption.AutoRead, isLibuvServer); // LibuvServer 不支持 No-AutoRead
                sb.ChildOption(ChannelOption.AutoRead, false);
                cb.Option(ChannelOption.AutoRead, false);
                CountdownEvent             serverReadyLatch          = new CountdownEvent(1);
                CountdownEvent             acceptorReadLatch         = new CountdownEvent(1);
                CountdownEvent             serverReadLatch           = new CountdownEvent(1);
                CountdownEvent             clientReadLatch           = new CountdownEvent(1);
                AtomicReference <IChannel> serverConnectedChannelRef = new AtomicReference <IChannel>();

                sb.Handler(new ActionChannelInitializer <IChannel>(ch =>
                {
                    ch.Pipeline.AddLast(new ChannelInboundHandlerAdapter0(acceptorReadLatch));
                }));

                sb.ChildHandler(new ActionChannelInitializer <IChannel>(ch =>
                {
                    serverConnectedChannelRef.Value = ch;
                    ch.Pipeline.AddLast(new SimpleChannelInboundHandler0(serverReadLatch));
                    serverReadyLatch.SafeSignal();
                }));

                cb.Handler(new ActionChannelInitializer <IChannel>(ch =>
                {
                    ch.Pipeline.AddLast(new SimpleChannelInboundHandler1(clientReadLatch));
                }));

                serverChannel = await sb.BindAsync();

                clientChannel = await cb.ConnectAsync(serverChannel.LocalAddress);

                await clientChannel.WriteAndFlushAsync(clientChannel.Allocator.Buffer().WriteZero(1));

                // The acceptor shouldn't read any data until we call read() below, but give it some time to see if it will.
                if (!isLibuvServer)
                {
                    Thread.Sleep(sleepMs);
                    Assert.Equal(1, acceptorReadLatch.CurrentCount);
                    serverChannel.Read();
                    serverReadyLatch.Wait();
                }

                IChannel serverConnectedChannel = serverConnectedChannelRef.Value;
                Assert.NotNull(serverConnectedChannel);

                // Allow some amount of time for the server peer to receive the message (which isn't expected to happen
                // until we call read() below).
                Thread.Sleep(sleepMs);
                Assert.Equal(1, serverReadLatch.CurrentCount);
                serverConnectedChannel.Read();
                serverReadLatch.Wait();

                // Allow some amount of time for the client to read the echo.
                Thread.Sleep(sleepMs);
                Assert.Equal(1, clientReadLatch.CurrentCount);
                clientChannel.Read();
                clientReadLatch.Wait();
            }
            finally
            {
                if (serverChannel != null)
                {
                    await serverChannel.CloseAsync();
                }
                if (clientChannel != null)
                {
                    await clientChannel.CloseAsync();
                }
                Task.WaitAll(
                    sb.Group().ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(5)),
                    sb.ChildGroup().ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(5)),
                    cb.Group().ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(5)));
            }
        }
 protected override void ChannelRead0(IChannelHandlerContext ctx, IByteBuffer msg)
 {
     ctx.WriteAndFlushAsync(msg.RetainedDuplicate());
     _serverReadLatch.SafeSignal();
 }