package org.webpieces.nio.api.integ; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import org.webpieces.asyncserver.api.AsyncConfig; import org.webpieces.asyncserver.api.AsyncServer; import org.webpieces.asyncserver.api.AsyncServerManager; import org.webpieces.asyncserver.api.AsyncServerMgrFactory; import org.webpieces.data.api.BufferCreationPool; import org.webpieces.data.api.BufferPool; import org.webpieces.nio.api.ChannelManager; import org.webpieces.nio.api.ChannelManagerFactory; import org.webpieces.nio.api.channels.Channel; import org.webpieces.nio.api.channels.TCPChannel; import org.webpieces.nio.api.handlers.DataListener; import org.webpieces.util.logging.Logger; import org.webpieces.util.logging.LoggerFactory; import org.webpieces.util.threading.NamedThreadFactory; public class IntegTestLocalhostThroughput { private static final Logger log = LoggerFactory.getLogger(IntegTestLocalhostThroughput.class); private BytesRecorder recorder = new BytesRecorder(); /** * Here, we will simulate a bad hacker client that sets his side so_timeout to infinite * and then refuses to read response data back in but keeps writing into our server to * crash the server as it backs up on responses....ie. we keep receiving requests and holding * on to them so memory keeps growing and growing or our write queue keeps growing unbounded * * so this test ensures we fix that scenario * @throws InterruptedException */ public static void main(String[] args) throws InterruptedException { new IntegTestLocalhostThroughput().testSoTimeoutOnSocket(); } public void testSoTimeoutOnSocket() throws InterruptedException { Executor executor = Executors.newFixedThreadPool(10, new NamedThreadFactory("serverThread")); BufferPool pool = new BufferCreationPool(); ChannelManagerFactory factory = ChannelManagerFactory.createFactory(); ChannelManager mgr = factory.createMultiThreadedChanMgr("server", pool, executor); AsyncServerManager serverMgr = AsyncServerMgrFactory.createAsyncServer(mgr); AsyncServer server = serverMgr.createTcpServer(new AsyncConfig("tcpServer"), new IntegTestLocalhostServerListener()); server.start(new InetSocketAddress(8080)); BufferPool pool2 = new BufferCreationPool(); DataListener listener = new ClientDataListener(pool2, recorder); Executor executor2 = Executors.newFixedThreadPool(10, new NamedThreadFactory("clientThread")); TCPChannel channel = createClientChannel(pool2, executor2); //TCPChannel channel = createNettyChannel(); recorder.start(); CompletableFuture<Channel> connect = channel.connect(new InetSocketAddress(8080), listener); connect.thenAccept(p -> runWriting(channel)); synchronized(this) { this.wait(); } } private TCPChannel createClientChannel(BufferPool pool2, Executor executor) { ChannelManagerFactory factory = ChannelManagerFactory.createFactory(); ChannelManager mgr = factory.createMultiThreadedChanMgr("client", pool2, executor); TCPChannel channel = mgr.createTCPChannel("clientChan"); return channel; } private void runWriting(Channel channel) { log.info("starting writing"); write(channel, null); } private void write(Channel channel, String reason) { byte[] data = new byte[10240]; ByteBuffer buffer = ByteBuffer.wrap(data); CompletableFuture<Channel> write = channel.write(buffer); write .thenAccept(p -> write(channel, "wrote data from client")) .whenComplete((r, e) -> finished(r, e)) .exceptionally(e -> { logIt(e); return null; }); } private void logIt(Throwable e) { log.error("failed to write", e); } private void finished(Void r, Throwable e) { if(e != null) log.info("failed due to reason="+e.getMessage()); } }