Verify SslHandler#unwrap send fireChannelRead event after a notification for a handshake success (#11203)

Motivation:

#11210 fixed a regression caused by #11156. This change adds a unit test for it.

Modifications:

- Add test

Result:

Verify fix in #11210 

Co-authored-by: Norman Maurer <norman_maurer@apple.com>
This commit is contained in:
Violeta Georgieva 2021-04-29 13:12:43 +03:00 committed by GitHub
parent 63352b135a
commit c0708fc464
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -31,7 +31,9 @@ import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.ssl.ApplicationProtocolConfig; import io.netty.handler.ssl.ApplicationProtocolConfig;
import io.netty.handler.ssl.ApplicationProtocolNames; import io.netty.handler.ssl.ApplicationProtocolNames;
import io.netty.handler.ssl.ApplicationProtocolNegotiationHandler;
import io.netty.handler.ssl.ClientAuth; import io.netty.handler.ssl.ClientAuth;
import io.netty.handler.ssl.OpenSsl;
import io.netty.handler.ssl.SslContext; import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.SslHandshakeCompletionEvent; import io.netty.handler.ssl.SslHandshakeCompletionEvent;
@ -443,4 +445,132 @@ public class Http2MultiplexTransportTest {
} }
} }
} }
@Test(timeout = 5000L)
public void testFireChannelReadAfterHandshakeSuccess_JDK() throws Exception {
assumeTrue(SslProvider.isAlpnSupported(SslProvider.JDK));
testFireChannelReadAfterHandshakeSuccess(SslProvider.JDK);
}
@Test(timeout = 5000L)
public void testFireChannelReadAfterHandshakeSuccess_OPENSSL() throws Exception {
assumeTrue(OpenSsl.isAvailable());
assumeTrue(SslProvider.isAlpnSupported(SslProvider.OPENSSL));
testFireChannelReadAfterHandshakeSuccess(SslProvider.OPENSSL);
}
private void testFireChannelReadAfterHandshakeSuccess(SslProvider provider) throws Exception {
SelfSignedCertificate ssc = null;
try {
ssc = new SelfSignedCertificate();
final SslContext serverCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey())
.sslProvider(provider)
.ciphers(Http2SecurityUtil.CIPHERS, SupportedCipherSuiteFilter.INSTANCE)
.applicationProtocolConfig(new ApplicationProtocolConfig(
ApplicationProtocolConfig.Protocol.ALPN,
ApplicationProtocolConfig.SelectorFailureBehavior.NO_ADVERTISE,
ApplicationProtocolConfig.SelectedListenerFailureBehavior.ACCEPT,
ApplicationProtocolNames.HTTP_2,
ApplicationProtocolNames.HTTP_1_1))
.build();
ServerBootstrap sb = new ServerBootstrap();
sb.group(eventLoopGroup);
sb.channel(NioServerSocketChannel.class);
sb.childHandler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel ch) {
ch.pipeline().addLast(serverCtx.newHandler(ch.alloc()));
ch.pipeline().addLast(new ApplicationProtocolNegotiationHandler(ApplicationProtocolNames.HTTP_1_1) {
@Override
protected void configurePipeline(ChannelHandlerContext ctx, String protocol) {
ctx.pipeline().addLast(new Http2FrameCodecBuilder(true).build());
ctx.pipeline().addLast(new Http2MultiplexHandler(new ChannelInboundHandlerAdapter() {
@Override
public void channelRead(final ChannelHandlerContext ctx, Object msg) {
if (msg instanceof Http2HeadersFrame && ((Http2HeadersFrame) msg).isEndStream()) {
ctx.writeAndFlush(new DefaultHttp2HeadersFrame(
new DefaultHttp2Headers(), false))
.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) {
ctx.writeAndFlush(new DefaultHttp2DataFrame(
Unpooled.copiedBuffer("Hello World", CharsetUtil.US_ASCII),
true));
}
});
}
ReferenceCountUtil.release(msg);
}
}));
}
});
}
});
serverChannel = sb.bind(new InetSocketAddress(NetUtil.LOCALHOST, 0)).sync().channel();
final SslContext clientCtx = SslContextBuilder.forClient()
.sslProvider(provider)
.ciphers(Http2SecurityUtil.CIPHERS, SupportedCipherSuiteFilter.INSTANCE)
.trustManager(InsecureTrustManagerFactory.INSTANCE)
.applicationProtocolConfig(new ApplicationProtocolConfig(
ApplicationProtocolConfig.Protocol.ALPN,
ApplicationProtocolConfig.SelectorFailureBehavior.NO_ADVERTISE,
ApplicationProtocolConfig.SelectedListenerFailureBehavior.ACCEPT,
ApplicationProtocolNames.HTTP_2,
ApplicationProtocolNames.HTTP_1_1))
.build();
final CountDownLatch latch = new CountDownLatch(1);
Bootstrap bs = new Bootstrap();
bs.group(eventLoopGroup);
bs.channel(NioSocketChannel.class);
bs.handler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel ch) {
ch.pipeline().addLast(clientCtx.newHandler(ch.alloc()));
ch.pipeline().addLast(new Http2FrameCodecBuilder(false).build());
ch.pipeline().addLast(new Http2MultiplexHandler(DISCARD_HANDLER));
ch.pipeline().addLast(new ChannelInboundHandlerAdapter() {
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
if (evt instanceof SslHandshakeCompletionEvent) {
SslHandshakeCompletionEvent handshakeCompletionEvent =
(SslHandshakeCompletionEvent) evt;
if (handshakeCompletionEvent.isSuccess()) {
Http2StreamChannelBootstrap h2Bootstrap =
new Http2StreamChannelBootstrap(clientChannel);
h2Bootstrap.handler(new ChannelInboundHandlerAdapter() {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
if (msg instanceof Http2DataFrame && ((Http2DataFrame) msg).isEndStream()) {
latch.countDown();
}
ReferenceCountUtil.release(msg);
}
});
h2Bootstrap.open().addListener(new FutureListener<Channel>() {
@Override
public void operationComplete(Future<Channel> future) {
if (future.isSuccess()) {
future.getNow().writeAndFlush(new DefaultHttp2HeadersFrame(
new DefaultHttp2Headers(), true));
}
}
});
}
}
}
});
}
});
clientChannel = bs.connect(serverChannel.localAddress()).sync().channel();
latch.await();
} finally {
if (ssc != null) {
ssc.delete();
}
}
}
} }