public void run() throws IOException { String scheme = uri.getScheme() == null ? "http" : uri.getScheme(); // Configure the client. ClientBootstrap b = new ClientBootstrap( new HttpTunnelingClientSocketChannelFactory( new OioClientSocketChannelFactory(Executors.newCachedThreadPool()))); b.setPipelineFactory( new ChannelPipelineFactory() { public ChannelPipeline getPipeline() throws Exception { return Channels.pipeline( new StringDecoder(), new StringEncoder(), new LoggingHandler(InternalLogLevel.INFO)); } }); // Set additional options required by the HTTP tunneling transport. b.setOption("serverName", uri.getHost()); b.setOption("serverPath", uri.getRawPath()); // Configure SSL if necessary if ("https".equals(scheme)) { b.setOption("sslContext", SecureChatSslContextFactory.getClientContext()); } else if (!"http".equals(scheme)) { // Only HTTP and HTTPS are supported. System.err.println("Only HTTP(S) is supported."); return; } // Make the connection attempt. ChannelFuture channelFuture = b.connect(new InetSocketAddress(uri.getHost(), uri.getPort())); channelFuture.awaitUninterruptibly(); // Read commands from the stdin. System.out.println("Enter text ('quit' to exit)"); ChannelFuture lastWriteFuture = null; BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); for (; ; ) { String line = in.readLine(); if (line == null || "quit".equalsIgnoreCase(line)) { break; } // Sends the received line to the server. lastWriteFuture = channelFuture.getChannel().write(line); } // Wait until all messages are flushed before closing the channel. if (lastWriteFuture != null) { lastWriteFuture.awaitUninterruptibly(); } channelFuture.getChannel().close(); // Wait until the connection is closed or the connection attempt fails. channelFuture.getChannel().getCloseFuture().awaitUninterruptibly(); // Shut down all threads. b.releaseExternalResources(); }
@Test public void testSslEcho() throws Throwable { ServerBootstrap sb = new ServerBootstrap(newServerSocketChannelFactory(Executors.newCachedThreadPool())); ClientBootstrap cb = new ClientBootstrap(newClientSocketChannelFactory(Executors.newCachedThreadPool())); EchoHandler sh = new EchoHandler(true); EchoHandler ch = new EchoHandler(false); SSLEngine sse = SecureChatSslContextFactory.getServerContext().createSSLEngine(); SSLEngine cse = SecureChatSslContextFactory.getClientContext().createSSLEngine(); sse.setUseClientMode(false); cse.setUseClientMode(true); // Workaround for blocking I/O transport write-write dead lock. sb.setOption("receiveBufferSize", 1048576); sb.setOption("receiveBufferSize", 1048576); sb.getPipeline().addFirst("ssl", new SslHandler(sse)); sb.getPipeline().addLast("handler", sh); cb.getPipeline().addFirst("ssl", new SslHandler(cse)); cb.getPipeline().addLast("handler", ch); ExecutorService eventExecutor = null; if (isExecutorRequired()) { eventExecutor = new OrderedMemoryAwareThreadPoolExecutor(16, 0, 0); sb.getPipeline().addFirst("executor", new ExecutionHandler(eventExecutor)); cb.getPipeline().addFirst("executor", new ExecutionHandler(eventExecutor)); } Channel sc = sb.bind(new InetSocketAddress(0)); int port = ((InetSocketAddress) sc.getLocalAddress()).getPort(); ChannelFuture ccf = cb.connect(new InetSocketAddress(TestUtil.getLocalHost(), port)); ccf.awaitUninterruptibly(); if (!ccf.isSuccess()) { logger.error("Connection attempt failed", ccf.getCause()); sc.close().awaitUninterruptibly(); } assertTrue(ccf.isSuccess()); Channel cc = ccf.getChannel(); ChannelFuture hf = cc.getPipeline().get(SslHandler.class).handshake(); hf.awaitUninterruptibly(); if (!hf.isSuccess()) { logger.error("Handshake failed", hf.getCause()); sh.channel.close().awaitUninterruptibly(); ch.channel.close().awaitUninterruptibly(); sc.close().awaitUninterruptibly(); } assertTrue(hf.isSuccess()); for (int i = 0; i < data.length; ) { int length = Math.min(random.nextInt(1024 * 64), data.length - i); cc.write(ChannelBuffers.wrappedBuffer(data, i, length)); i += length; } while (ch.counter < data.length) { if (sh.exception.get() != null) { break; } if (ch.exception.get() != null) { break; } try { Thread.sleep(1); } catch (InterruptedException e) { // Ignore. } } while (sh.counter < data.length) { if (sh.exception.get() != null) { break; } if (ch.exception.get() != null) { break; } try { Thread.sleep(1); } catch (InterruptedException e) { // Ignore. } } sh.channel.close().awaitUninterruptibly(); ch.channel.close().awaitUninterruptibly(); sc.close().awaitUninterruptibly(); cb.shutdown(); sb.shutdown(); cb.releaseExternalResources(); sb.releaseExternalResources(); if (eventExecutor != null) { eventExecutor.shutdown(); } if (sh.exception.get() != null && !(sh.exception.get() instanceof IOException)) { throw sh.exception.get(); } if (ch.exception.get() != null && !(ch.exception.get() instanceof IOException)) { throw ch.exception.get(); } if (sh.exception.get() != null) { throw sh.exception.get(); } if (ch.exception.get() != null) { throw ch.exception.get(); } }