netty - channelReadComplete called before channelRead0 when ssl is used -
i have set junit test starting server first , connecting client. response comes should. add ssl , response still comes client, reason seems channelreadcomplete
method called twice before channelread0. it's easy avoid exceptions creates on null object attempted relayed next handler firechannelread(msg)
, testing null before calling firechannelread(msg)
, if there can avoid behavior please enlighten me. ssl handlers set in telnet example. using 4.0.25.final.
here ssl code server:
channelpipeline cp = ch.pipeline(); selfsignedcertificate cert = new selfsignedcertificate(); sslcontext cont = sslcontext.newservercontext( cert.certificate(), cert.privatekey()); cp.addlast("ssl", cont.newhandler(ch.alloc()));
and client:
channelpipeline pipeline = ch.pipeline(); sslcontext cont = sslcontext.newclientcontext(insecuretrustmanagerfactory.instance); pipeline.addlast(cont.newhandler(ch.alloc(),host, server_secure_port));
here junit test:
public class myssltest { private static logger utillogger = logger.getlogger("my.logger.clientside"); private static eventloopgroup bossgroup; private static eventloopgroup workergroup; private static final int server_secure_port = 5061; private static final int client_port = 5062; private static final string host = "localhost"; @beforeclass public static void setupbeforeclass() throws exception { utillogger.info("starting up"); try { serverbootstrap b = new serverbootstrap(); bossgroup = new nioeventloopgroup(1); workergroup = new nioeventloopgroup(); b.group(bossgroup, workergroup) .channel(nioserversocketchannel.class) .handler(new logginghandler(loglevel.debug)) .childhandler(new channelinitializer<socketchannel>() { @override protected void initchannel(socketchannel ch) throws exception { channelpipeline cp = ch.pipeline(); selfsignedcertificate cert = new selfsignedcertificate(); sslcontext cont = sslcontext.newservercontext( cert.certificate(), cert.privatekey()); cp.addlast("ssl", cont.newhandler(ch.alloc())); cp.addlast( "inhandler", new mysimplechannelinboundtcphandlerserver()); } }); // b.bind(server_secure_port).sync().channel().closefuture().sync(); b.bind(server_secure_port).sync(); } catch (interruptedexception e) { e.printstacktrace(); } { } } @afterclass public static void takedownafterclass() { bossgroup.shutdowngracefully(); workergroup.shutdowngracefully(); } @test public void testsendandreceivepacket() { eventloopgroup group = null; utillogger.info("test"); try { bootstrap b = new bootstrap(); group = new nioeventloopgroup(); b.group(group).channel(niosocketchannel.class) .option(channeloption.ip_tos, 24) .handler(new channelinitializer<socketchannel>() { @override protected void initchannel(socketchannel ch) throws exception { channelpipeline pipeline = ch.pipeline(); sslcontext cont = sslcontext .newclientcontext(insecuretrustmanagerfactory.instance); pipeline.addlast(cont.newhandler(ch.alloc(), host, server_secure_port)); pipeline.addlast(new mysimplechannelinboundtcphandlerbugreport()); } }); channel ch = null; inetsocketaddress ria = new inetsocketaddress(host, server_secure_port); inetsocketaddress lia = new inetsocketaddress(host, client_port); try { utillogger.info("connecting"); ch = b.connect(ria, lia).sync().channel(); } catch (exception e) { e.printstacktrace(); } if (ch != null) { utillogger.info("sending request"); channelfuture wcf = null; bytebuf bb = null; bb = unpooled.copiedbuffer("register", charsetutil.utf_8); wcf = ch.write(bb); ch.flush(); utillogger.info("request sent"); if (!wcf.await(600)) { utillogger.info("request not written"); ch.close(); } if (!ch.closefuture().await(1000)) utillogger.info("not closed within 1000ms"); } } catch (interruptedexception e) { e.printstacktrace(); } catch (throwable e) { e.printstacktrace(); } { group.shutdowngracefully(); } asserttrue(mysimplechannelinboundtcphandlerbugreport.test_succeded); } }
here server handler:
public class mysimplechannelinboundtcphandlerserver extends simplechannelinboundhandler<bytebuf> { private logger utillogger = logger.getlogger("my.logger.serverside"); @override protected void channelread0(channelhandlercontext ctx, bytebuf bb) throws exception { utillogger.info("channelread0"); string response = bb.tostring(charsetutil.utf_8); bytebuf bbout = unpooled.copiedbuffer(response, charsetutil.utf_8); ctx.write(bbout); ctx.flush(); } @override public void channelreadcomplete(channelhandlercontext ctx) throws exception { super.channelreadcomplete(ctx); utillogger.info("channelreadcomplete"); } @override public void exceptioncaught(channelhandlercontext ctx, throwable cause) throws exception { cause.printstacktrace(); ctx.close(); } }
and client handler:
public class mysimplechannelinboundtcphandlerbugreport extends simplechannelinboundhandler<bytebuf> { public static boolean test_succeded = false; private logger utillogger = logger.getlogger("my.logger.clientside"); @override protected void channelread0(channelhandlercontext ctx, bytebuf bb) throws exception { string response = bb.tostring(charsetutil.utf_8); utillogger.info("response: " + response); if (response.startswith("register")) { test_succeded = true; ctx.close(); } } @override public void channelreadcomplete(channelhandlercontext ctx) throws exception { super.channelreadcomplete(ctx); } @override public void exceptioncaught(channelhandlercontext ctx, throwable cause) throws exception { cause.printstacktrace(); ctx.close(); } }
Comments
Post a Comment