@Test public void testOpenedClosedAreInvoked() throws Exception { initConnector(null); final CountDownLatch openedLatch = new CountDownLatch(1); final CountDownLatch closedLatch = new CountDownLatch(1); connector.addNetworkTrafficListener( new NetworkTrafficListener.Empty() { public volatile Socket socket; @Override public void opened(Socket socket) { this.socket = socket; openedLatch.countDown(); } @Override public void closed(Socket socket) { if (this.socket == socket) closedLatch.countDown(); } }); int port = connector.getLocalPort(); // Connect to the server Socket socket = new Socket("localhost", port); assertTrue(openedLatch.await(10, TimeUnit.SECONDS)); socket.close(); assertTrue(closedLatch.await(10, TimeUnit.SECONDS)); }
@Test public void testTrafficWithRequestContentWithResponseRedirectOnPersistentConnection() throws Exception { final String location = "/redirect"; initConnector( new AbstractHandler() { public void handle( String uri, Request request, HttpServletRequest servletRequest, HttpServletResponse servletResponse) throws IOException, ServletException { request.setHandled(true); servletResponse.sendRedirect(location); } }); final AtomicReference<String> incomingData = new AtomicReference<String>(); final CountDownLatch incomingLatch = new CountDownLatch(1); final AtomicReference<String> outgoingData = new AtomicReference<String>(""); final CountDownLatch outgoingLatch = new CountDownLatch(1); connector.addNetworkTrafficListener( new NetworkTrafficListener.Empty() { public void incoming(Socket socket, ByteBuffer bytes) { incomingData.set(BufferUtil.toString(bytes, StringUtil.__UTF8_CHARSET)); incomingLatch.countDown(); } public void outgoing(Socket socket, ByteBuffer bytes) { outgoingData.set( outgoingData.get() + BufferUtil.toString(bytes, StringUtil.__UTF8_CHARSET)); outgoingLatch.countDown(); } }); int port = connector.getLocalPort(); String requestContent = "a=1&b=2"; String request = "" + "POST / HTTP/1.1\r\n" + "Host: localhost:" + port + "\r\n" + "Content-Type: application/x-www-form-urlencoded\r\n" + "Content-Length: " + requestContent.length() + "\r\n" + "\r\n" + requestContent; String expectedResponse = "" + "HTTP/1.1 302 Found\r\n" + "Location: http://localhost:" + port + location + "\r\n" + "Content-Length: 0\r\n" + "\r\n"; Socket socket = new Socket("localhost", port); OutputStream output = socket.getOutputStream(); output.write(request.getBytes("UTF-8")); output.flush(); assertTrue(incomingLatch.await(1, TimeUnit.SECONDS)); assertEquals(request, incomingData.get()); assertTrue(outgoingLatch.await(1, TimeUnit.SECONDS)); assertEquals(expectedResponse, outgoingData.get()); byte[] responseBytes = readResponse(socket); String response = new String(responseBytes, "UTF-8"); assertEquals(expectedResponse, response); socket.close(); }
@Test public void testTrafficWithBigRequestContentOnPersistentConnection() throws Exception { initConnector( new AbstractHandler() { public void handle( String uri, Request request, HttpServletRequest servletRequest, HttpServletResponse servletResponse) throws IOException, ServletException { // Read and discard the request body to make the test more // reliable, otherwise there is a race between request body // upload and response download InputStream input = servletRequest.getInputStream(); byte[] buffer = new byte[4096]; while (true) { int read = input.read(buffer); if (read < 0) break; } request.setHandled(true); } }); final AtomicReference<String> incomingData = new AtomicReference<String>(""); final AtomicReference<String> outgoingData = new AtomicReference<String>(""); final CountDownLatch outgoingLatch = new CountDownLatch(1); connector.addNetworkTrafficListener( new NetworkTrafficListener.Empty() { public void incoming(Socket socket, ByteBuffer bytes) { incomingData.set( incomingData.get() + BufferUtil.toString(bytes, StringUtil.__UTF8_CHARSET)); } public void outgoing(Socket socket, ByteBuffer bytes) { outgoingData.set( outgoingData.get() + BufferUtil.toString(bytes, StringUtil.__UTF8_CHARSET)); outgoingLatch.countDown(); } }); int port = connector.getLocalPort(); // Generate 32 KiB of request content String requestContent = "0123456789ABCDEF"; for (int i = 0; i < 11; ++i) requestContent += requestContent; String request = "" + "POST / HTTP/1.1\r\n" + "Host: localhost:" + port + "\r\n" + "Content-Type: text/plain\r\n" + "Content-Length: " + requestContent.length() + "\r\n" + "\r\n" + requestContent; String expectedResponse = "" + "HTTP/1.1 200 OK\r\n" + "Content-Length: 0\r\n" + "\r\n"; Socket socket = new Socket("localhost", port); OutputStream output = socket.getOutputStream(); output.write(request.getBytes("UTF-8")); output.flush(); assertTrue(outgoingLatch.await(1, TimeUnit.SECONDS)); assertEquals(expectedResponse, outgoingData.get()); byte[] responseBytes = readResponse(socket); String response = new String(responseBytes, "UTF-8"); assertEquals(expectedResponse, response); assertEquals(request, incomingData.get()); socket.close(); }
@Test public void testTrafficWithResponseContentChunkedOnPersistentConnection() throws Exception { final String responseContent = "response_content"; final String responseChunk1 = "response_content".substring(0, responseContent.length() / 2); final String responseChunk2 = "response_content".substring(responseContent.length() / 2, responseContent.length()); initConnector( new AbstractHandler() { public void handle( String uri, Request request, HttpServletRequest servletRequest, HttpServletResponse servletResponse) throws IOException, ServletException { request.setHandled(true); ServletOutputStream output = servletResponse.getOutputStream(); output.write(responseChunk1.getBytes("UTF-8")); output.flush(); output.write(responseChunk2.getBytes("UTF-8")); output.flush(); } }); final AtomicReference<String> incomingData = new AtomicReference<String>(); final CountDownLatch incomingLatch = new CountDownLatch(1); final AtomicReference<String> outgoingData = new AtomicReference<String>(""); final CountDownLatch outgoingLatch = new CountDownLatch(4); connector.addNetworkTrafficListener( new NetworkTrafficListener.Empty() { public void incoming(Socket socket, ByteBuffer bytes) { incomingData.set(BufferUtil.toString(bytes, StringUtil.__UTF8_CHARSET)); incomingLatch.countDown(); } public void outgoing(Socket socket, ByteBuffer bytes) { outgoingData.set( outgoingData.get() + BufferUtil.toString(bytes, StringUtil.__UTF8_CHARSET)); outgoingLatch.countDown(); } }); int port = connector.getLocalPort(); String request = "" + "GET / HTTP/1.1\r\n" + "Host: localhost:" + port + "\r\n" + "\r\n"; String expectedResponse = "" + "HTTP/1.1 200 OK\r\n" + "Transfer-Encoding: chunked\r\n" + "\r\n" + responseChunk1.length() + "\r\n" + responseChunk1 + "\r\n" + responseChunk2.length() + "\r\n" + responseChunk2 + "\r\n" + "0\r\n" + "\r\n"; Socket socket = new Socket("localhost", port); OutputStream output = socket.getOutputStream(); output.write(request.getBytes("UTF-8")); output.flush(); assertTrue(incomingLatch.await(1, TimeUnit.SECONDS)); assertEquals(request, incomingData.get()); assertTrue(outgoingLatch.await(1, TimeUnit.SECONDS)); assertEquals(expectedResponse, outgoingData.get()); byte[] responseBytes = readResponse(socket); String response = new String(responseBytes, "UTF-8"); assertEquals(expectedResponse, response); socket.close(); }