@Test public void test_Redirect_WithExpect100Continue_WithContent() throws Exception { // A request with Expect: 100-Continue cannot receive non-final responses like 3xx final String data = "success"; start( new AbstractHandler() { @Override public void handle( String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { baseRequest.setHandled(true); if (request.getRequestURI().endsWith("/done")) { // Send 100-Continue and consume the content IO.copy(request.getInputStream(), new ByteArrayOutputStream()); response.getOutputStream().print(data); } else { // Send a redirect response.sendRedirect("/done"); } } }); byte[] content = new byte[10240]; final CountDownLatch latch = new CountDownLatch(1); client .newRequest("localhost", connector.getLocalPort()) .scheme(scheme) .method(HttpMethod.POST) .path("/redirect") .header(HttpHeader.EXPECT.asString(), HttpHeaderValue.CONTINUE.asString()) .content(new BytesContentProvider(content)) .send( new BufferingResponseListener() { @Override public void onComplete(Result result) { Assert.assertTrue(result.isFailed()); Assert.assertNotNull(result.getRequestFailure()); Assert.assertNull(result.getResponseFailure()); Assert.assertEquals(302, result.getResponse().getStatus()); latch.countDown(); } }); Assert.assertTrue(latch.await(5, TimeUnit.SECONDS)); }
@Slow @Test public void test_Expect100Continue_WithContent_WithResponseFailure_After100Continue() throws Exception { final long idleTimeout = 1000; start( new AbstractHandler() { @Override public void handle( String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { baseRequest.setHandled(true); // Send 100-Continue and consume the content IO.copy(request.getInputStream(), new ByteArrayOutputStream()); try { TimeUnit.MILLISECONDS.sleep(2 * idleTimeout); } catch (InterruptedException x) { throw new ServletException(x); } } }); client.setIdleTimeout(idleTimeout); byte[] content = new byte[1024]; final CountDownLatch latch = new CountDownLatch(1); client .newRequest("localhost", connector.getLocalPort()) .scheme(scheme) .header(HttpHeader.EXPECT.asString(), HttpHeaderValue.CONTINUE.asString()) .content(new BytesContentProvider(content)) .send( new BufferingResponseListener() { @Override public void onComplete(Result result) { Assert.assertTrue(result.isFailed()); Assert.assertNull(result.getRequestFailure()); Assert.assertNotNull(result.getResponseFailure()); latch.countDown(); } }); Assert.assertTrue(latch.await(3 * idleTimeout, TimeUnit.MILLISECONDS)); }
@Test public void test_Expect100Continue_WithChunkedContent_Respond100Continue() throws Exception { start( new AbstractHandler() { @Override public void handle( String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { baseRequest.setHandled(true); // Send 100-Continue and copy the content back ServletInputStream input = request.getInputStream(); // Make sure we chunk the response too response.flushBuffer(); IO.copy(input, response.getOutputStream()); } }); byte[] content1 = new byte[10240]; byte[] content2 = new byte[16384]; ContentResponse response = client .newRequest("localhost", connector.getLocalPort()) .scheme(scheme) .header(HttpHeader.EXPECT.asString(), HttpHeaderValue.CONTINUE.asString()) .content( new BytesContentProvider(content1, content2) { @Override public long getLength() { return -1; } }) .send() .get(5, TimeUnit.SECONDS); Assert.assertNotNull(response); Assert.assertEquals(200, response.getStatus()); int index = 0; byte[] responseContent = response.getContent(); for (byte b : content1) Assert.assertEquals(b, responseContent[index++]); for (byte b : content2) Assert.assertEquals(b, responseContent[index++]); }
private void test_Expect100Continue_WithContent_RespondError(final int error) throws Exception { start( new AbstractHandler() { @Override public void handle( String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { baseRequest.setHandled(true); response.sendError(error); } }); byte[] content1 = new byte[10240]; byte[] content2 = new byte[16384]; final CountDownLatch latch = new CountDownLatch(1); client .newRequest("localhost", connector.getLocalPort()) .scheme(scheme) .header(HttpHeader.EXPECT.asString(), HttpHeaderValue.CONTINUE.asString()) .content(new BytesContentProvider(content1, content2)) .send( new BufferingResponseListener() { @Override public void onComplete(Result result) { Assert.assertTrue(result.isFailed()); Assert.assertNotNull(result.getRequestFailure()); Assert.assertNull(result.getResponseFailure()); byte[] content = getContent(); Assert.assertNotNull(content); Assert.assertTrue(content.length > 0); Assert.assertEquals(error, result.getResponse().getStatus()); latch.countDown(); } }); Assert.assertTrue(latch.await(5, TimeUnit.SECONDS)); }
private void test_Expect100Continue_Respond100Continue(byte[]... contents) throws Exception { start( new AbstractHandler() { @Override public void handle( String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { baseRequest.setHandled(true); // Send 100-Continue and copy the content back IO.copy(request.getInputStream(), response.getOutputStream()); } }); ContentResponse response = client .newRequest("localhost", connector.getLocalPort()) .scheme(scheme) .header(HttpHeader.EXPECT.asString(), HttpHeaderValue.CONTINUE.asString()) .content(new BytesContentProvider(contents)) .send() .get(5, TimeUnit.SECONDS); Assert.assertNotNull(response); Assert.assertEquals(200, response.getStatus()); int index = 0; byte[] responseContent = response.getContent(); for (byte[] content : contents) { for (byte b : content) { Assert.assertEquals(b, responseContent[index++]); } } }
@Test public void test_Expect100Continue_WithContent_WithResponseFailure_During100Continue() throws Exception { start( new AbstractHandler() { @Override public void handle( String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { baseRequest.setHandled(true); // Send 100-Continue and consume the content IO.copy(request.getInputStream(), new ByteArrayOutputStream()); } }); client.getProtocolHandlers().clear(); client .getProtocolHandlers() .add( new ContinueProtocolHandler(client) { @Override public Response.Listener getResponseListener() { final Response.Listener listener = super.getResponseListener(); return new Response.Listener.Empty() { @Override public void onBegin(Response response) { response.abort(null); } @Override public void onFailure(Response response, Throwable failure) { listener.onFailure(response, failure); } }; } }); try { Log.getLogger(HttpChannel.class).info("Expecting Close warning..."); ((StdErrLog) Log.getLogger(HttpChannel.class)).setHideStacks(true); byte[] content = new byte[1024]; final CountDownLatch latch = new CountDownLatch(1); client .newRequest("localhost", connector.getLocalPort()) .scheme(scheme) .header(HttpHeader.EXPECT.asString(), HttpHeaderValue.CONTINUE.asString()) .content(new BytesContentProvider(content)) .send( new BufferingResponseListener() { @Override public void onComplete(Result result) { Assert.assertTrue(result.isFailed()); Assert.assertNotNull(result.getRequestFailure()); Assert.assertNotNull(result.getResponseFailure()); latch.countDown(); } }); Assert.assertTrue(latch.await(5, TimeUnit.SECONDS)); } finally { ((StdErrLog) Log.getLogger(HttpChannel.class)).setHideStacks(false); } }