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(); } }
public override void UserEventTriggered(IChannelHandlerContext ctx, object evt) { if (evt == ChannelInputShutdownEvent.Instance && _allowHalfClosed) { _clientHalfClosedLatch.SafeSignal(); } else if (evt == ChannelInputShutdownReadComplete.Instance) { ctx.CloseAsync(); } }
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(); } }
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))); }
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))); }
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); }
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); }
public override void ChannelActive(IChannelHandlerContext ctx) { IByteBuffer buf = ctx.Allocator.Buffer(_totalServerBytesWritten); buf.SetWriterIndex(buf.Capacity); ctx.WriteAndFlushAsync(buf).CloseOnComplete(ctx.Channel); _serverInitializedLatch.SafeSignal(); }
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); }
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(); }
public override void ChannelReadComplete(IChannelHandlerContext ctx) { _clientReadCompletes.Increment(); if (_bytesRead == _totalServerBytesWritten) { _clientReadAllDataLatch.SafeSignal(); } if (!_autoRead) { ctx.Read(); } }
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); }
public override void ChannelRead(IChannelHandlerContext ctx, object msg) { if (msg is IByteBuffer buf) { _totalRead += buf.ReadableBytes; if (_totalRead == _expectedBytes) { _latch.SafeSignal(); } } ReferenceCountUtil.Release(msg); }
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))); }
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(); }); }
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(); }
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))); }
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); } }
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(); }
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(); }