netty: prevent IndexOutOfBoundsException when no handler is passed to BufferingHandler
diff --git a/netty/src/main/java/io/grpc/netty/ProtocolNegotiators.java b/netty/src/main/java/io/grpc/netty/ProtocolNegotiators.java
index c028b6b..2d47eb6 100644
--- a/netty/src/main/java/io/grpc/netty/ProtocolNegotiators.java
+++ b/netty/src/main/java/io/grpc/netty/ProtocolNegotiators.java
@@ -465,7 +465,7 @@
* This check is necessary as a channel may be registered with different event loops during it
* lifetime and we only want to configure it once.
*/
- if (handlers != null) {
+ if (handlers != null && handlers.length > 0) {
for (ChannelHandler handler : handlers) {
ctx.pipeline().addBefore(ctx.name(), null, handler);
}
diff --git a/netty/src/test/java/io/grpc/netty/ProtocolNegotiatorsTest.java b/netty/src/test/java/io/grpc/netty/ProtocolNegotiatorsTest.java
index 6beda2a..df1c052 100644
--- a/netty/src/test/java/io/grpc/netty/ProtocolNegotiatorsTest.java
+++ b/netty/src/test/java/io/grpc/netty/ProtocolNegotiatorsTest.java
@@ -32,6 +32,7 @@
import io.grpc.SecurityLevel;
import io.grpc.internal.GrpcAttributes;
import io.grpc.internal.testing.TestUtils;
+import io.grpc.netty.ProtocolNegotiators.AbstractBufferingHandler;
import io.grpc.netty.ProtocolNegotiators.HostPort;
import io.grpc.netty.ProtocolNegotiators.ServerTlsHandler;
import io.grpc.netty.ProtocolNegotiators.TlsNegotiator;
@@ -584,6 +585,24 @@
elg.shutdownGracefully();
}
+ @Test(expected = Test.None.class /* no exception expected */)
+ @SuppressWarnings("TestExceptionChecker")
+ public void bufferingHandler_shouldNotThrowForEmptyHandler() throws Exception {
+ LocalAddress addr = new LocalAddress("local");
+ ChannelFuture unused = new Bootstrap()
+ .channel(LocalChannel.class)
+ .handler(new BufferingHandlerWithoutHandlers())
+ .group(group)
+ .register().sync();
+ ChannelFuture sf = new ServerBootstrap()
+ .channel(LocalServerChannel.class)
+ .childHandler(new ChannelHandlerAdapter() {})
+ .group(group)
+ .bind(addr);
+ // sync will trigger client's NoHandlerBufferingHandler which should not throw
+ sf.sync();
+ }
+
private static class FakeGrpcHttp2ConnectionHandler extends GrpcHttp2ConnectionHandler {
static GrpcHttp2ConnectionHandler noopHandler() {
@@ -629,4 +648,11 @@
private static ByteBuf bb(String s, Channel c) {
return ByteBufUtil.writeUtf8(c.alloc(), s);
}
+
+ private static class BufferingHandlerWithoutHandlers extends AbstractBufferingHandler {
+
+ public BufferingHandlerWithoutHandlers(ChannelHandler... handlers) {
+ super(handlers);
+ }
+ }
}