diff --git a/common/src/main/java/io/netty/util/internal/Hidden.java b/common/src/main/java/io/netty/util/internal/Hidden.java
index 86348a04d5..e9ec19e757 100644
--- a/common/src/main/java/io/netty/util/internal/Hidden.java
+++ b/common/src/main/java/io/netty/util/internal/Hidden.java
@@ -62,6 +62,16 @@ class Hidden {
"confirmShutdown"
);
+ builder.allowBlockingCallsInside(
+ "io.netty.handler.ssl.SslHandler",
+ "handshake"
+ );
+
+ builder.allowBlockingCallsInside(
+ "io.netty.handler.ssl.SslHandler",
+ "runAllDelegatedTasks"
+ );
+
builder.nonBlockingThreadPredicate(p -> thread ->
p.test(thread) || thread instanceof FastThreadLocalThread);
}
diff --git a/handler/src/test/java/io/netty/handler/ssl/SslHandlerTest.java b/handler/src/test/java/io/netty/handler/ssl/SslHandlerTest.java
index b3a67c915d..2006732246 100644
--- a/handler/src/test/java/io/netty/handler/ssl/SslHandlerTest.java
+++ b/handler/src/test/java/io/netty/handler/ssl/SslHandlerTest.java
@@ -911,7 +911,7 @@ public class SslHandlerTest {
}
}
- private void testHandshakeWithExecutor(Executor executor) throws Exception {
+ private static void testHandshakeWithExecutor(Executor executor) throws Exception {
final SslContext sslClientCtx = SslContextBuilder.forClient()
.trustManager(InsecureTrustManagerFactory.INSTANCE)
.sslProvider(SslProvider.JDK).build();
@@ -968,7 +968,7 @@ public class SslHandlerTest {
testHandshakeTimeoutBecauseExecutorNotExecute(false);
}
- private void testHandshakeTimeoutBecauseExecutorNotExecute(final boolean client) throws Exception {
+ private static void testHandshakeTimeoutBecauseExecutorNotExecute(final boolean client) throws Exception {
final SslContext sslClientCtx = SslContextBuilder.forClient()
.trustManager(InsecureTrustManagerFactory.INSTANCE)
.sslProvider(SslProvider.JDK).build();
diff --git a/transport-blockhound-tests/pom.xml b/transport-blockhound-tests/pom.xml
index f2709cd4c7..ba0ee7f94f 100644
--- a/transport-blockhound-tests/pom.xml
+++ b/transport-blockhound-tests/pom.xml
@@ -46,6 +46,8 @@
1.8
1.8
+
+ --add-exports java.base/sun.security.x509=ALL-UNNAMED
true
@@ -55,7 +57,17 @@
netty-transport
${project.version}
+
+ ${project.groupId}
+ netty-handler
+ ${project.version}
+
+
+ org.bouncycastle
+ bcpkix-jdk15on
+ true
+
io.projectreactor.tools
blockhound
diff --git a/transport-blockhound-tests/src/test/java/io/netty/util/internal/NettyBlockHoundIntegrationTest.java b/transport-blockhound-tests/src/test/java/io/netty/util/internal/NettyBlockHoundIntegrationTest.java
index 4482a67f50..8c7720582f 100644
--- a/transport-blockhound-tests/src/test/java/io/netty/util/internal/NettyBlockHoundIntegrationTest.java
+++ b/transport-blockhound-tests/src/test/java/io/netty/util/internal/NettyBlockHoundIntegrationTest.java
@@ -15,15 +15,41 @@
*/
package io.netty.util.internal;
+import io.netty.bootstrap.Bootstrap;
+import io.netty.bootstrap.ServerBootstrap;
+import io.netty.buffer.UnpooledByteBufAllocator;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.nio.NioServerSocketChannel;
+import io.netty.channel.socket.nio.NioSocketChannel;
+import io.netty.handler.ssl.SslContext;
+import io.netty.handler.ssl.SslContextBuilder;
+import io.netty.handler.ssl.SslHandler;
+import io.netty.handler.ssl.SslHandshakeCompletionEvent;
+import io.netty.handler.ssl.SslProvider;
+import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
+import io.netty.handler.ssl.util.SelfSignedCertificate;
+import io.netty.util.ReferenceCountUtil;
import io.netty.util.concurrent.GlobalEventExecutor;
+import io.netty.util.concurrent.ImmediateEventExecutor;
+import io.netty.util.concurrent.ImmediateExecutor;
import io.netty.util.internal.Hidden.NettyBlockHoundIntegration;
import org.junit.BeforeClass;
import org.junit.Test;
import reactor.blockhound.BlockHound;
import reactor.blockhound.integration.BlockHoundIntegration;
+import java.net.InetSocketAddress;
import java.util.ServiceLoader;
import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
@@ -66,4 +92,89 @@ public class NettyBlockHoundIntegrationTest {
assertTrue("Blocking call was reported", throwable.getMessage().contains("Blocking call"));
}
}
+
+ // Tests copied from io.netty.handler.ssl.SslHandlerTest
+ @Test
+ public void testHandshakeWithExecutorThatExecuteDirectory() throws Exception {
+ testHandshakeWithExecutor(Runnable::run);
+ }
+
+ @Test
+ public void testHandshakeWithImmediateExecutor() throws Exception {
+ testHandshakeWithExecutor(ImmediateExecutor.INSTANCE);
+ }
+
+ @Test
+ public void testHandshakeWithImmediateEventExecutor() throws Exception {
+ testHandshakeWithExecutor(ImmediateEventExecutor.INSTANCE);
+ }
+
+ @Test
+ public void testHandshakeWithExecutor() throws Exception {
+ ExecutorService executorService = Executors.newCachedThreadPool();
+ try {
+ testHandshakeWithExecutor(executorService);
+ } finally {
+ executorService.shutdown();
+ }
+ }
+
+ private static void testHandshakeWithExecutor(Executor executor) throws Exception {
+ final SslContext sslClientCtx = SslContextBuilder.forClient()
+ .trustManager(InsecureTrustManagerFactory.INSTANCE)
+ .sslProvider(SslProvider.JDK).build();
+
+ final SelfSignedCertificate cert = new SelfSignedCertificate();
+ final SslContext sslServerCtx = SslContextBuilder.forServer(cert.key(), cert.cert())
+ .sslProvider(SslProvider.JDK).build();
+
+ EventLoopGroup group = new NioEventLoopGroup();
+ Channel sc = null;
+ Channel cc = null;
+ final SslHandler clientSslHandler = sslClientCtx.newHandler(UnpooledByteBufAllocator.DEFAULT, executor);
+ final SslHandler serverSslHandler = sslServerCtx.newHandler(UnpooledByteBufAllocator.DEFAULT, executor);
+
+ try {
+ sc = new ServerBootstrap()
+ .group(group)
+ .channel(NioServerSocketChannel.class)
+ .childHandler(serverSslHandler)
+ .bind(new InetSocketAddress(0)).syncUninterruptibly().channel();
+
+ ChannelFuture future = new Bootstrap()
+ .group(group)
+ .channel(NioSocketChannel.class)
+ .handler(new ChannelInitializer() {
+ @Override
+ protected void initChannel(Channel ch) {
+ ch.pipeline()
+ .addLast(clientSslHandler)
+ .addLast(new ChannelInboundHandlerAdapter() {
+
+ @Override
+ public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
+ if (evt instanceof SslHandshakeCompletionEvent &&
+ ((SslHandshakeCompletionEvent) evt).cause() != null) {
+ ((SslHandshakeCompletionEvent) evt).cause().printStackTrace();
+ }
+ ctx.fireUserEventTriggered(evt);
+ }
+ });
+ }
+ }).connect(sc.localAddress());
+ cc = future.syncUninterruptibly().channel();
+
+ assertTrue(clientSslHandler.handshakeFuture().await().isSuccess());
+ assertTrue(serverSslHandler.handshakeFuture().await().isSuccess());
+ } finally {
+ if (cc != null) {
+ cc.close().syncUninterruptibly();
+ }
+ if (sc != null) {
+ sc.close().syncUninterruptibly();
+ }
+ group.shutdownGracefully();
+ ReferenceCountUtil.release(sslClientCtx);
+ }
+ }
}