You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2014/04/02 16:44:37 UTC
svn commit: r1584060 [2/2] - in
/httpcomponents/httpcore/trunk/httpcore-nio/src:
main/java/org/apache/http/impl/nio/ main/java/org/apache/http/nio/protocol/
test/java/org/apache/http/impl/nio/
test/java/org/apache/http/nio/integration/ test/java/org/ap...
Modified: httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestHttpAsyncService.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestHttpAsyncService.java?rev=1584060&r1=1584059&r2=1584060&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestHttpAsyncService.java (original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestHttpAsyncService.java Wed Apr 2 14:44:36 2014
@@ -29,14 +29,16 @@ package org.apache.http.nio.protocol;
import java.io.IOException;
import java.net.SocketTimeoutException;
+import java.util.Queue;
import org.apache.http.ConnectionReuseStrategy;
+import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpException;
+import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.HttpResponseFactory;
import org.apache.http.HttpStatus;
import org.apache.http.HttpVersion;
-import org.apache.http.UnsupportedHttpVersionException;
import org.apache.http.concurrent.Cancellable;
import org.apache.http.impl.DefaultHttpResponseFactory;
import org.apache.http.message.BasicHttpEntityEnclosingRequest;
@@ -47,7 +49,11 @@ import org.apache.http.nio.ContentEncode
import org.apache.http.nio.NHttpClientConnection;
import org.apache.http.nio.NHttpServerConnection;
import org.apache.http.nio.entity.NStringEntity;
+import org.apache.http.nio.protocol.HttpAsyncService.Incoming;
+import org.apache.http.nio.protocol.HttpAsyncService.Outgoing;
+import org.apache.http.nio.protocol.HttpAsyncService.PipelineEntry;
import org.apache.http.nio.protocol.HttpAsyncService.State;
+import org.apache.http.nio.reactor.SessionBufferStatus;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext;
@@ -57,6 +63,7 @@ import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
+import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatcher;
import org.mockito.Mockito;
@@ -116,17 +123,24 @@ public class TestHttpAsyncService {
Assert.assertNotNull(state);
Assert.assertEquals(MessageState.READY, state.getRequestState());
Assert.assertEquals(MessageState.READY, state.getResponseState());
- Assert.assertEquals("request state: READY; request: ; " +
- "response state: READY; response: ;", state.toString());
+ Assert.assertEquals("[incoming READY; outgoing READY]", state.toString());
}
@Test
public void testClosed() throws Exception {
- final State state = new HttpAsyncService.State();
+ final State state = new State();
state.setRequestState(MessageState.COMPLETED);
state.setResponseState(MessageState.COMPLETED);
- state.setRequestConsumer(this.requestConsumer);
- state.setResponseProducer(this.responseProducer);
+ final HttpContext exchangeContext = new BasicHttpContext();
+
+ final HttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
+ final Incoming incoming = new Incoming(
+ request, this.requestHandler, this.requestConsumer, exchangeContext);
+ state.setIncoming(incoming);
+ final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+ final Outgoing outgoing = new Outgoing(
+ request, response, this.responseProducer, exchangeContext);
+ state.setOutgoing(outgoing);
state.setCancellable(this.cancellable);
this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
@@ -141,10 +155,14 @@ public class TestHttpAsyncService {
@Test
public void testHttpExceptionHandling() throws Exception {
- final State state = new HttpAsyncService.State();
+ final State state = new State();
state.setRequestState(MessageState.READY);
state.setResponseState(MessageState.READY);
- state.setRequestConsumer(this.requestConsumer);
+ final HttpContext exchangeContext = new BasicHttpContext();
+ final HttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
+ final Incoming incoming = new Incoming(
+ request, this.requestHandler, this.requestConsumer, exchangeContext);
+ state.setIncoming(incoming);
state.setCancellable(this.cancellable);
this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
@@ -153,9 +171,11 @@ public class TestHttpAsyncService {
Assert.assertEquals(MessageState.READY, state.getRequestState());
Assert.assertEquals(MessageState.BODY_STREAM, state.getResponseState());
- Assert.assertNotNull(state.getResponseProducer());
- Assert.assertNotNull(state.getResponse());
- Assert.assertEquals(500, state.getResponse().getStatusLine().getStatusCode());
+ final Outgoing outgoing = state.getOutgoing();
+ Assert.assertNotNull(outgoing);
+ Assert.assertNotNull(outgoing.getProducer());
+ Assert.assertNotNull(outgoing.getResponse());
+ Assert.assertEquals(500, outgoing.getResponse().getStatusLine().getStatusCode());
Mockito.verify(this.requestConsumer).failed(httpex);
Mockito.verify(this.requestConsumer).close();
@@ -165,18 +185,36 @@ public class TestHttpAsyncService {
}
@Test
- public void testHttpExceptionHandlingRuntimeException() throws Exception {
- final State state = new HttpAsyncService.State();
- final HttpContext exchangeContext = state.getContext();
+ public void testExceptionHandlingNoState() throws Exception {
+ this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, null);
+
+ final Exception ex = new Exception("Oopsie");
+ this.protocolHandler.exception(conn, ex);
+
+ Mockito.verify(conn).getContext();
+ Mockito.verify(conn).shutdown();
+ Mockito.verifyNoMoreInteractions(conn);
+ }
+
+ @Test
+ public void testExceptionHandlingRuntimeException() throws Exception {
+ final State state = new State();
state.setRequestState(MessageState.READY);
state.setResponseState(MessageState.READY);
- state.setRequestConsumer(this.requestConsumer);
- state.setResponseProducer(this.responseProducer);
+ final HttpContext exchangeContext = new BasicHttpContext();
+ final HttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
+ final Incoming incoming = new Incoming(
+ request, this.requestHandler, this.requestConsumer, exchangeContext);
+ state.setIncoming(incoming);
+ final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+ final Outgoing outgoing = new Outgoing(
+ request, response, this.responseProducer, exchangeContext);
+ state.setOutgoing(outgoing);
state.setCancellable(this.cancellable);
this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
Mockito.doThrow(new RuntimeException()).when(this.httpProcessor).process(
- Mockito.any(HttpResponse.class), Mockito.eq(exchangeContext));
+ Mockito.any(HttpResponse.class), Mockito.any(HttpContext.class));
final HttpException httpex = new HttpException();
try {
this.protocolHandler.exception(this.conn, httpex);
@@ -193,17 +231,23 @@ public class TestHttpAsyncService {
@Test
public void testHttpExceptionHandlingIOException() throws Exception {
- final State state = new HttpAsyncService.State();
- final HttpContext exchangeContext = state.getContext();
+ final State state = new State();
state.setRequestState(MessageState.READY);
state.setResponseState(MessageState.READY);
- state.setRequestConsumer(this.requestConsumer);
- state.setResponseProducer(this.responseProducer);
+ final HttpContext exchangeContext = new BasicHttpContext();
+ final HttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
+ final Incoming incoming = new Incoming(
+ request, this.requestHandler, this.requestConsumer, exchangeContext);
+ state.setIncoming(incoming);
+ final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+ final Outgoing outgoing = new Outgoing(
+ request, response, this.responseProducer, exchangeContext);
+ state.setOutgoing(outgoing);
state.setCancellable(this.cancellable);
this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
Mockito.doThrow(new IOException()).when(this.httpProcessor).process(
- Mockito.any(HttpResponse.class), Mockito.eq(exchangeContext));
+ Mockito.any(HttpResponse.class), Mockito.any(HttpContext.class));
final HttpException httpex = new HttpException();
this.protocolHandler.exception(this.conn, httpex);
@@ -218,11 +262,18 @@ public class TestHttpAsyncService {
@Test
public void testHttpExceptionHandlingResponseSubmitted() throws Exception {
- final State state = new HttpAsyncService.State();
+ final State state = new State();
state.setRequestState(MessageState.READY);
state.setResponseState(MessageState.READY);
- state.setRequestConsumer(this.requestConsumer);
- state.setResponseProducer(this.responseProducer);
+ final HttpContext exchangeContext = new BasicHttpContext();
+ final HttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
+ final Incoming incoming = new Incoming(
+ request, this.requestHandler, this.requestConsumer, exchangeContext);
+ state.setIncoming(incoming);
+ final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+ final Outgoing outgoing = new Outgoing(
+ request, response, this.responseProducer, exchangeContext);
+ state.setOutgoing(outgoing);
this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
Mockito.when(this.conn.isResponseSubmitted()).thenReturn(Boolean.TRUE);
@@ -239,36 +290,14 @@ public class TestHttpAsyncService {
}
@Test
- public void testIOExceptionHandling() throws Exception {
- final State state = new HttpAsyncService.State();
- state.setRequestState(MessageState.READY);
- state.setResponseState(MessageState.READY);
- state.setRequestConsumer(this.requestConsumer);
- state.setResponseProducer(this.responseProducer);
- this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
-
- final IOException httpex = new IOException();
- this.protocolHandler.exception(this.conn, httpex);
-
- Assert.assertEquals(MessageState.READY, state.getRequestState());
- Assert.assertEquals(MessageState.READY, state.getResponseState());
- Mockito.verify(this.conn).shutdown();
- Mockito.verify(this.requestConsumer).failed(httpex);
- Mockito.verify(this.requestConsumer).close();
- Mockito.verify(this.responseProducer).failed(httpex);
- Mockito.verify(this.responseProducer).close();
- }
-
- @Test
public void testBasicRequest() throws Exception {
- final State state = new HttpAsyncService.State();
- final HttpContext exchangeContext = state.getContext();
+ final State state = new State();
this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
- final BasicHttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
+ final HttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
Mockito.when(this.conn.getHttpRequest()).thenReturn(request);
Mockito.when(this.requestHandler.processRequest(
- request, exchangeContext)).thenReturn(this.requestConsumer);
+ Mockito.eq(request), Mockito.any(HttpContext.class))).thenReturn(this.requestConsumer);
Mockito.when(this.requestConsumer.getException()).thenReturn(null);
final Object data = new Object();
Mockito.when(this.requestConsumer.getResult()).thenReturn(data);
@@ -278,63 +307,157 @@ public class TestHttpAsyncService {
Assert.assertEquals(MessageState.COMPLETED, state.getRequestState());
Assert.assertEquals(MessageState.INIT, state.getResponseState());
- Assert.assertSame(request, state.getRequest());
- Assert.assertSame(this.requestHandler, state.getRequestHandler());
- Assert.assertSame(this.requestConsumer, state.getRequestConsumer());
+ final Incoming incoming = state.getIncoming();
+ Assert.assertNull(incoming);
+
+ final ArgumentCaptor<HttpContext> argumentCaptor = ArgumentCaptor.forClass(HttpContext.class);
+ Mockito.verify(this.httpProcessor).process(Mockito.eq(request), argumentCaptor.capture());
+ final HttpContext exchangeContext = argumentCaptor.getValue();
+ Assert.assertNotNull(exchangeContext);
+
Assert.assertSame(request, exchangeContext.getAttribute(HttpCoreContext.HTTP_REQUEST));
Assert.assertSame(this.conn, exchangeContext.getAttribute(HttpCoreContext.HTTP_CONNECTION));
- Mockito.verify(this.httpProcessor).process(request, exchangeContext);
Mockito.verify(this.requestConsumer).requestReceived(request);
Mockito.verify(this.requestConsumer).requestCompleted(exchangeContext);
Mockito.verify(this.requestHandler).handle(
Mockito.eq(data),
Mockito.any(HttpAsyncExchange.class),
Mockito.eq(exchangeContext));
+ Assert.assertTrue(state.getPipeline().isEmpty());
+ }
+
+ @Test
+ public void testRequestPipelineIfResponseInitiated() throws Exception {
+ final State state = new State();
+ state.setRequestState(MessageState.READY);
+ state.setResponseState(MessageState.INIT);
+ this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
+
+ final HttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
+ Mockito.when(this.conn.getHttpRequest()).thenReturn(request);
+ Mockito.when(this.requestHandler.processRequest(
+ Mockito.eq(request), Mockito.any(HttpContext.class))).thenReturn(this.requestConsumer);
+ Mockito.when(this.requestConsumer.getException()).thenReturn(null);
+ final Object data = new Object();
+ Mockito.when(this.requestConsumer.getResult()).thenReturn(data);
+
+ this.protocolHandler.requestReceived(this.conn);
+
+ Assert.assertEquals(MessageState.COMPLETED, state.getRequestState());
+ Assert.assertEquals(MessageState.INIT, state.getResponseState());
+
+ final Incoming incoming = state.getIncoming();
+ Assert.assertNull(incoming);
+
+ Mockito.verify(this.requestConsumer).requestReceived(request);
+ Mockito.verify(this.requestConsumer).requestCompleted(Mockito.<HttpContext>any());
+ Mockito.verify(this.requestHandler, Mockito.never()).handle(
+ Mockito.any(),
+ Mockito.any(HttpAsyncExchange.class),
+ Mockito.any(HttpContext.class));
+
+ Assert.assertFalse(state.getPipeline().isEmpty());
+ final PipelineEntry entry = state.getPipeline().remove();
+ Assert.assertSame(request, entry.getRequest());
+ Assert.assertSame(data, entry.getResult());
+ }
+
+ @Test
+ public void testRequestPipelineIfPipelineNotEmpty() throws Exception {
+ final State state = new State();
+ state.setRequestState(MessageState.READY);
+ state.setResponseState(MessageState.READY);
+
+ final Queue<PipelineEntry> pipeline = state.getPipeline();
+
+ final HttpContext exchangeContext = new BasicHttpContext();
+ final HttpRequest pipelinedRequest = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
+ final PipelineEntry entry = new PipelineEntry(pipelinedRequest, pipelinedRequest,
+ null, requestHandler, exchangeContext);
+ pipeline.add(entry);
+
+ this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
+
+ final HttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
+ Mockito.when(this.conn.getHttpRequest()).thenReturn(request);
+ Mockito.when(this.requestHandler.processRequest(
+ Mockito.eq(request), Mockito.any(HttpContext.class))).thenReturn(this.requestConsumer);
+ Mockito.when(this.requestConsumer.getException()).thenReturn(null);
+ final Object data = new Object();
+ Mockito.when(this.requestConsumer.getResult()).thenReturn(data);
+
+ this.protocolHandler.requestReceived(this.conn);
+
+ Assert.assertEquals(MessageState.COMPLETED, state.getRequestState());
+ Assert.assertEquals(MessageState.READY, state.getResponseState());
+
+ final Incoming incoming = state.getIncoming();
+ Assert.assertNull(incoming);
+
+ Mockito.verify(this.requestConsumer).requestReceived(request);
+ Mockito.verify(this.requestConsumer).requestCompleted(Mockito.<HttpContext>any());
+ Mockito.verify(this.requestHandler, Mockito.never()).handle(
+ Mockito.any(),
+ Mockito.any(HttpAsyncExchange.class),
+ Mockito.any(HttpContext.class));
+
+ Assert.assertFalse(state.getPipeline().isEmpty());
+ final PipelineEntry entry1 = state.getPipeline().remove();
+ Assert.assertSame(entry, entry1);
+ final PipelineEntry entry2 = state.getPipeline().remove();
+ Assert.assertSame(request, entry2.getRequest());
+ Assert.assertSame(data, entry2.getResult());
}
@Test
public void testRequestNoMatchingHandler() throws Exception {
- final State state = new HttpAsyncService.State();
- final HttpContext exchangeContext = state.getContext();
+ final State state = new State();
this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
- final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST",
+ final HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST",
"/stuff", HttpVersion.HTTP_1_1);
request.setEntity(new NStringEntity("stuff"));
Mockito.when(this.conn.getHttpRequest()).thenReturn(request);
Mockito.when(this.requestHandler.processRequest(
- request, exchangeContext)).thenReturn(this.requestConsumer);
+ Mockito.eq(request), Mockito.any(HttpContext.class))).thenReturn(this.requestConsumer);
this.protocolHandler.requestReceived(this.conn);
Assert.assertEquals(MessageState.BODY_STREAM, state.getRequestState());
Assert.assertEquals(MessageState.READY, state.getResponseState());
- Assert.assertSame(request, state.getRequest());
- Assert.assertTrue(state.getRequestHandler() instanceof NullRequestHandler);
+ final Incoming incoming = state.getIncoming();
+ Assert.assertNotNull(incoming);
+ Assert.assertSame(request, incoming.getRequest());
+ Assert.assertTrue(incoming.getHandler() instanceof NullRequestHandler);
}
@Test
public void testEntityEnclosingRequest() throws Exception {
- final State state = new HttpAsyncService.State();
- final HttpContext exchangeContext = state.getContext();
+ final State state = new State();
this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
- final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
+ final HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
HttpVersion.HTTP_1_1);
Mockito.when(this.conn.getHttpRequest()).thenReturn(request);
Mockito.when(this.requestHandler.processRequest(
- request, exchangeContext)).thenReturn(this.requestConsumer);
+ Mockito.eq(request), Mockito.any(HttpContext.class))).thenReturn(this.requestConsumer);
this.protocolHandler.requestReceived(this.conn);
Assert.assertEquals(MessageState.BODY_STREAM, state.getRequestState());
Assert.assertEquals(MessageState.READY, state.getResponseState());
- Assert.assertSame(request, state.getRequest());
- Assert.assertSame(this.requestHandler, state.getRequestHandler());
- Assert.assertSame(this.requestConsumer, state.getRequestConsumer());
+ final Incoming incoming = state.getIncoming();
+ Assert.assertNotNull(incoming);
+ Assert.assertSame(request, incoming.getRequest());
+ Assert.assertSame(this.requestHandler, incoming.getHandler());
+ Assert.assertSame(this.requestConsumer, incoming.getConsumer());
+
+ final HttpContext exchangeContext = incoming.getContext();
+ Assert.assertNotNull(exchangeContext);
+
Assert.assertSame(request, exchangeContext.getAttribute(HttpCoreContext.HTTP_REQUEST));
Assert.assertSame(this.conn, exchangeContext.getAttribute(HttpCoreContext.HTTP_CONNECTION));
@@ -345,25 +468,30 @@ public class TestHttpAsyncService {
@Test
public void testEntityEnclosingRequestContinueWithoutVerification() throws Exception {
- final State state = new HttpAsyncService.State();
- final HttpContext exchangeContext = state.getContext();
+ final State state = new State();
this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
- final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
+ final HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
HttpVersion.HTTP_1_1);
request.addHeader(HTTP.EXPECT_DIRECTIVE, HTTP.EXPECT_CONTINUE);
Mockito.when(this.conn.getHttpRequest()).thenReturn(request);
Mockito.when(this.requestHandler.processRequest(
- request, exchangeContext)).thenReturn(this.requestConsumer);
+ Mockito.eq(request), Mockito.any(HttpContext.class))).thenReturn(this.requestConsumer);
this.protocolHandler.requestReceived(this.conn);
Assert.assertEquals(MessageState.BODY_STREAM, state.getRequestState());
Assert.assertEquals(MessageState.READY, state.getResponseState());
- Assert.assertSame(request, state.getRequest());
- Assert.assertSame(this.requestHandler, state.getRequestHandler());
- Assert.assertSame(this.requestConsumer, state.getRequestConsumer());
+ final Incoming incoming = state.getIncoming();
+ Assert.assertNotNull(incoming);
+ Assert.assertSame(request, incoming.getRequest());
+ Assert.assertSame(this.requestHandler, incoming.getHandler());
+ Assert.assertSame(this.requestConsumer, incoming.getConsumer());
+
+ final HttpContext exchangeContext = incoming.getContext();
+ Assert.assertNotNull(exchangeContext);
+
Assert.assertSame(request, exchangeContext.getAttribute(HttpCoreContext.HTTP_REQUEST));
Assert.assertSame(this.conn, exchangeContext.getAttribute(HttpCoreContext.HTTP_CONNECTION));
@@ -388,25 +516,30 @@ public class TestHttpAsyncService {
this.httpProcessor, this.reuseStrategy, this.responseFactory,
this.handlerResolver, expectationVerifier);
- final State state = new HttpAsyncService.State();
- final HttpContext exchangeContext = state.getContext();
+ final State state = new State();
this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
- final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
+ final HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
HttpVersion.HTTP_1_1);
request.addHeader(HTTP.EXPECT_DIRECTIVE, HTTP.EXPECT_CONTINUE);
Mockito.when(this.conn.getHttpRequest()).thenReturn(request);
Mockito.when(this.requestHandler.processRequest(
- request, exchangeContext)).thenReturn(this.requestConsumer);
+ Mockito.eq(request), Mockito.any(HttpContext.class))).thenReturn(this.requestConsumer);
this.protocolHandler.requestReceived(this.conn);
Assert.assertEquals(MessageState.ACK_EXPECTED, state.getRequestState());
Assert.assertEquals(MessageState.READY, state.getResponseState());
- Assert.assertSame(request, state.getRequest());
- Assert.assertSame(this.requestHandler, state.getRequestHandler());
- Assert.assertSame(this.requestConsumer, state.getRequestConsumer());
+ final Incoming incoming = state.getIncoming();
+ Assert.assertNotNull(incoming);
+ Assert.assertSame(request, incoming.getRequest());
+ Assert.assertSame(this.requestHandler, incoming.getHandler());
+ Assert.assertSame(this.requestConsumer, incoming.getConsumer());
+
+ final HttpContext exchangeContext = incoming.getContext();
+ Assert.assertNotNull(exchangeContext);
+
Assert.assertSame(request, exchangeContext.getAttribute(HttpCoreContext.HTTP_REQUEST));
Assert.assertSame(this.conn, exchangeContext.getAttribute(HttpCoreContext.HTTP_CONNECTION));
@@ -420,21 +553,24 @@ public class TestHttpAsyncService {
@Test
public void testRequestExpectationFailed() throws Exception {
- final State state = new HttpAsyncService.State();
+ final State state = new State();
state.setRequestState(MessageState.ACK_EXPECTED);
this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
- final HttpAsyncExchange httpexchanage = new HttpAsyncService.Exchange(
+ final HttpContext exchangeContext = new BasicHttpContext();
+ final HttpAsyncExchange httpexchanage = new HttpAsyncService.HttpAsyncExchangeImpl(
new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1),
new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"),
- state, this.conn);
+ state, this.conn, exchangeContext);
Assert.assertFalse(httpexchanage.isCompleted());
httpexchanage.submitResponse(this.responseProducer);
Assert.assertTrue(httpexchanage.isCompleted());
Assert.assertEquals(MessageState.ACK_EXPECTED, state.getRequestState());
Assert.assertEquals(MessageState.READY, state.getResponseState());
- Assert.assertSame(this.responseProducer, state.getResponseProducer());
+ final Outgoing outgoing = state.getOutgoing();
+ Assert.assertNotNull(outgoing);
+ Assert.assertSame(this.responseProducer, outgoing.getProducer());
Mockito.verify(this.conn).requestOutput();
@@ -447,32 +583,120 @@ public class TestHttpAsyncService {
@Test(expected=IllegalArgumentException.class)
public void testRequestExpectationFailedInvalidResponseProducer() throws Exception {
- final State state = new HttpAsyncService.State();
+ final State state = new State();
state.setRequestState(MessageState.ACK_EXPECTED);
this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
- final HttpAsyncExchange httpexchanage = new HttpAsyncService.Exchange(
+ final HttpContext exchangeContext = new BasicHttpContext();
+ final HttpAsyncExchange httpexchanage = new HttpAsyncService.HttpAsyncExchangeImpl(
new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1),
new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"),
- state, this.conn);
+ state, this.conn, exchangeContext);
httpexchanage.submitResponse(null);
}
@Test
+ public void testRequestExpectationNoHandshakeIfResponseInitiated() throws Exception {
+ final State state = new State();
+ state.setRequestState(MessageState.READY);
+ state.setResponseState(MessageState.INIT);
+ this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
+
+ final HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
+ HttpVersion.HTTP_1_1);
+ request.addHeader(HTTP.EXPECT_DIRECTIVE, HTTP.EXPECT_CONTINUE);
+
+ Mockito.when(this.conn.getHttpRequest()).thenReturn(request);
+ Mockito.when(this.requestHandler.processRequest(
+ Mockito.eq(request), Mockito.any(HttpContext.class))).thenReturn(this.requestConsumer);
+
+ this.protocolHandler.requestReceived(this.conn);
+
+ Mockito.verify(this.requestConsumer).requestReceived(request);
+
+ Assert.assertEquals(MessageState.BODY_STREAM, state.getRequestState());
+ Assert.assertEquals(MessageState.INIT, state.getResponseState());
+ }
+
+ @Test
+ public void testRequestExpectationNoHandshakeIfPipelineNotEmpty() throws Exception {
+ final State state = new State();
+ state.setRequestState(MessageState.READY);
+ state.setResponseState(MessageState.READY);
+
+ final Queue<PipelineEntry> pipeline = state.getPipeline();
+
+ final HttpContext exchangeContext = new BasicHttpContext();
+ final HttpRequest pipelinedRequest = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
+ final PipelineEntry entry = new PipelineEntry(pipelinedRequest, pipelinedRequest,
+ null, requestHandler, exchangeContext);
+ pipeline.add(entry);
+
+ this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
+
+ final HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
+ HttpVersion.HTTP_1_1);
+ request.addHeader(HTTP.EXPECT_DIRECTIVE, HTTP.EXPECT_CONTINUE);
+
+ Mockito.when(this.conn.getHttpRequest()).thenReturn(request);
+ Mockito.when(this.requestHandler.processRequest(
+ Mockito.eq(request), Mockito.any(HttpContext.class))).thenReturn(this.requestConsumer);
+
+ this.protocolHandler.requestReceived(this.conn);
+
+ Mockito.verify(this.requestConsumer).requestReceived(request);
+
+ Assert.assertEquals(MessageState.BODY_STREAM, state.getRequestState());
+ Assert.assertEquals(MessageState.READY, state.getResponseState());
+ }
+
+ @Test
+ public void testRequestExpectationNoHandshakeIfMoreInputAvailable() throws Exception {
+ final State state = new State();
+ state.setRequestState(MessageState.READY);
+ state.setResponseState(MessageState.READY);
+
+ this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
+
+ this.conn = Mockito.mock(NHttpServerConnection.class,
+ Mockito.withSettings().extraInterfaces(SessionBufferStatus.class));
+
+ final HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
+ HttpVersion.HTTP_1_1);
+ request.addHeader(HTTP.EXPECT_DIRECTIVE, HTTP.EXPECT_CONTINUE);
+
+ Mockito.when(this.conn.getContext()).thenReturn(this.connContext);
+ Mockito.when(this.conn.getHttpRequest()).thenReturn(request);
+ Mockito.when(this.requestHandler.processRequest(
+ Mockito.eq(request), Mockito.any(HttpContext.class))).thenReturn(this.requestConsumer);
+ Mockito.when(((SessionBufferStatus) this.conn).hasBufferedInput()).thenReturn(Boolean.TRUE);
+
+ this.protocolHandler.requestReceived(this.conn);
+
+ Mockito.verify(this.requestConsumer).requestReceived(request);
+
+ Assert.assertEquals(MessageState.BODY_STREAM, state.getRequestState());
+ Assert.assertEquals(MessageState.READY, state.getResponseState());
+ }
+
+ @Test
public void testRequestContinue() throws Exception {
- final State state = new HttpAsyncService.State();
+ final State state = new State();
state.setRequestState(MessageState.ACK_EXPECTED);
this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
- final HttpAsyncExchange httpexchanage = new HttpAsyncService.Exchange(
+ final HttpContext exchangeContext = new BasicHttpContext();
+ final HttpAsyncExchange httpexchanage = new HttpAsyncService.HttpAsyncExchangeImpl(
new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1),
new BasicHttpResponse(HttpVersion.HTTP_1_1, 100, "Continue"),
- state, this.conn);
+ state, this.conn, exchangeContext);
Assert.assertFalse(httpexchanage.isCompleted());
httpexchanage.submitResponse();
Assert.assertTrue(httpexchanage.isCompleted());
- final HttpAsyncResponseProducer responseProducer = state.getResponseProducer();
+ final Outgoing outgoing = state.getOutgoing();
+ Assert.assertNotNull(outgoing);
+ final HttpAsyncResponseProducer responseProducer = outgoing.getProducer();
Assert.assertNotNull(responseProducer);
Assert.assertEquals(MessageState.ACK_EXPECTED, state.getRequestState());
Assert.assertEquals(MessageState.READY, state.getResponseState());
@@ -490,12 +714,14 @@ public class TestHttpAsyncService {
@Test
public void testRequestContent() throws Exception {
- final State state = new HttpAsyncService.State();
- final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
+ final State state = new State();
+ final HttpContext exchangeContext = new BasicHttpContext();
+ final HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
HttpVersion.HTTP_1_1);
state.setRequestState(MessageState.BODY_STREAM);
- state.setRequest(request);
- state.setRequestConsumer(this.requestConsumer);
+ final Incoming incoming = new Incoming(
+ request, this.requestHandler, this.requestConsumer, exchangeContext);
+ state.setIncoming(incoming);
this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
Mockito.when(this.decoder.isCompleted()).thenReturn(Boolean.FALSE);
@@ -510,14 +736,14 @@ public class TestHttpAsyncService {
@Test
public void testRequestContentCompleted() throws Exception {
- final State state = new HttpAsyncService.State();
- final HttpContext exchangeContext = state.getContext();
- final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
+ final State state = new State();
+ final HttpContext exchangeContext = new BasicHttpContext();
+ final HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
HttpVersion.HTTP_1_1);
state.setRequestState(MessageState.BODY_STREAM);
- state.setRequest(request);
- state.setRequestConsumer(this.requestConsumer);
- state.setRequestHandler(this.requestHandler);
+ final Incoming incoming = new Incoming(
+ request, this.requestHandler, this.requestConsumer, exchangeContext);
+ state.setIncoming(incoming);
this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
Mockito.when(this.decoder.isCompleted()).thenReturn(Boolean.TRUE);
Mockito.when(this.requestConsumer.getException()).thenReturn(null);
@@ -539,14 +765,14 @@ public class TestHttpAsyncService {
@Test
public void testRequestCompletedWithException() throws Exception {
- final State state = new HttpAsyncService.State();
- final HttpContext exchangeContext = state.getContext();
- final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
+ final State state = new State();
+ final HttpContext exchangeContext = new BasicHttpContext();
+ final HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
HttpVersion.HTTP_1_1);
state.setRequestState(MessageState.BODY_STREAM);
- state.setRequest(request);
- state.setRequestConsumer(this.requestConsumer);
- state.setRequestHandler(this.requestHandler);
+ final Incoming incoming = new Incoming(
+ request, this.requestHandler, this.requestConsumer, exchangeContext);
+ state.setIncoming(incoming);
this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
Mockito.when(this.decoder.isCompleted()).thenReturn(Boolean.TRUE);
Mockito.when(this.requestConsumer.getException()).thenReturn(new HttpException());
@@ -556,7 +782,9 @@ public class TestHttpAsyncService {
Assert.assertEquals(MessageState.COMPLETED, state.getRequestState());
Assert.assertEquals(MessageState.INIT, state.getResponseState());
- Assert.assertNotNull(state.getResponseProducer());
+ final Outgoing outgoing = state.getOutgoing();
+ Assert.assertNotNull(outgoing);
+ Assert.assertNotNull(outgoing.getProducer());
Mockito.verify(this.requestConsumer).consumeContent(this.decoder, this.conn);
Mockito.verify(this.requestConsumer).requestCompleted(exchangeContext);
@@ -564,84 +792,98 @@ public class TestHttpAsyncService {
Mockito.verify(this.requestHandler, Mockito.never()).handle(
Mockito.any(),
Mockito.any(HttpAsyncExchange.class),
- Mockito.any(HttpContext.class));
+ Mockito.eq(exchangeContext));
}
@Test
- public void testRequestHandlingHttpException() throws Exception {
- final State state = new HttpAsyncService.State();
- final HttpContext exchangeContext = state.getContext();
- final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
- HttpVersion.HTTP_1_1);
- state.setRequestState(MessageState.BODY_STREAM);
- state.setRequest(request);
- state.setRequestConsumer(this.requestConsumer);
- state.setRequestHandler(this.requestHandler);
+ public void testBasicResponse() throws Exception {
+ final State state = new State();
+ final HttpContext exchangeContext = new BasicHttpContext();
+ final HttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
+ final Incoming incoming = new Incoming(
+ request, this.requestHandler, this.requestConsumer, exchangeContext);
+ state.setIncoming(incoming);
+ state.setRequestState(MessageState.COMPLETED);
+ final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+ final Outgoing outgoing = new Outgoing(
+ request, response, this.responseProducer, exchangeContext);
+ state.setOutgoing(outgoing);
this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
- Mockito.when(this.decoder.isCompleted()).thenReturn(Boolean.TRUE);
- Mockito.when(this.requestConsumer.getException()).thenReturn(null);
- final Object data = new Object();
- Mockito.when(this.requestConsumer.getResult()).thenReturn(data);
- Mockito.doThrow(new UnsupportedHttpVersionException()).when(
- this.requestHandler).handle(
- Mockito.eq(data),
- Mockito.any(HttpAsyncExchange.class),
- Mockito.eq(exchangeContext));
- this.protocolHandler.inputReady(conn, this.decoder);
+ Mockito.when(this.responseProducer.generateResponse()).thenReturn(response);
+ Mockito.when(this.reuseStrategy.keepAlive(response, exchangeContext)).thenReturn(Boolean.TRUE);
- Assert.assertEquals(MessageState.COMPLETED, state.getRequestState());
- Assert.assertEquals(MessageState.INIT, state.getResponseState());
- Assert.assertNotNull(state.getResponseProducer());
+ this.protocolHandler.responseReady(this.conn);
- Mockito.verify(this.requestConsumer).consumeContent(this.decoder, this.conn);
- Mockito.verify(this.requestConsumer).requestCompleted(exchangeContext);
- Mockito.verify(this.conn).requestOutput();
+ Assert.assertEquals(MessageState.READY, state.getResponseState());
+
+ Mockito.verify(this.httpProcessor).process(response, exchangeContext);
+ Mockito.verify(this.conn).submitResponse(response);
+ Mockito.verify(this.responseProducer).responseCompleted(exchangeContext);
+ Mockito.verify(this.conn).requestInput();
+ Mockito.verify(this.conn).suspendOutput();
+ Mockito.verify(this.conn, Mockito.never()).close();
}
@Test
- public void testBasicResponse() throws Exception {
- final State state = new HttpAsyncService.State();
- final HttpContext exchangeContext = state.getContext();
- final BasicHttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
- state.setRequest(request);
+ public void testBasicResponseWithPipelining() throws Exception {
+ final State state = new State();
+ final HttpContext exchangeContext = new BasicHttpContext();
+ final HttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
+ final Incoming incoming = new Incoming(
+ request, this.requestHandler, this.requestConsumer, exchangeContext);
+ state.setIncoming(incoming);
state.setRequestState(MessageState.COMPLETED);
- state.setResponseProducer(this.responseProducer);
+ final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+ final Outgoing outgoing = new Outgoing(
+ request, response, this.responseProducer, exchangeContext);
+ state.setOutgoing(outgoing);
+
+ final Queue<PipelineEntry> pipeline = state.getPipeline();
+
+ final HttpContext exchangeContext2 = new BasicHttpContext();
+ final HttpRequest pipelinedRequest = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
+ final PipelineEntry entry = new PipelineEntry(pipelinedRequest, pipelinedRequest,
+ null, requestHandler, exchangeContext2);
+ pipeline.add(entry);
+
this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
- final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
Mockito.when(this.responseProducer.generateResponse()).thenReturn(response);
Mockito.when(this.reuseStrategy.keepAlive(response, exchangeContext)).thenReturn(Boolean.TRUE);
this.protocolHandler.responseReady(this.conn);
- Assert.assertEquals(MessageState.READY, state.getRequestState());
Assert.assertEquals(MessageState.READY, state.getResponseState());
Mockito.verify(this.httpProcessor).process(response, exchangeContext);
Mockito.verify(this.conn).submitResponse(response);
Mockito.verify(this.responseProducer).responseCompleted(exchangeContext);
Mockito.verify(this.conn).requestInput();
+ Mockito.verify(this.conn, Mockito.never()).suspendOutput();
Mockito.verify(this.conn, Mockito.never()).close();
}
@Test
public void testBasicResponseNoKeepAlive() throws Exception {
- final State state = new HttpAsyncService.State();
- final HttpContext exchangeContext = state.getContext();
- final BasicHttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
- state.setRequest(request);
+ final State state = new State();
+ final HttpContext exchangeContext = new BasicHttpContext();
+ final HttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
+ final Incoming incoming = new Incoming(
+ request, this.requestHandler, this.requestConsumer, exchangeContext);
+ state.setIncoming(incoming);
state.setRequestState(MessageState.COMPLETED);
- state.setResponseProducer(this.responseProducer);
+ final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+ final Outgoing outgoing = new Outgoing(
+ request, response, this.responseProducer, exchangeContext);
+ state.setOutgoing(outgoing);
this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
- final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
Mockito.when(this.responseProducer.generateResponse()).thenReturn(response);
Mockito.when(this.reuseStrategy.keepAlive(response, exchangeContext)).thenReturn(Boolean.FALSE);
this.protocolHandler.responseReady(this.conn);
- Assert.assertEquals(MessageState.READY, state.getRequestState());
Assert.assertEquals(MessageState.READY, state.getResponseState());
Mockito.verify(this.httpProcessor).process(response, exchangeContext);
@@ -652,15 +894,19 @@ public class TestHttpAsyncService {
@Test
public void testEntityEnclosingResponse() throws Exception {
- final State state = new HttpAsyncService.State();
- final HttpContext exchangeContext = state.getContext();
- final BasicHttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
- state.setRequest(request);
+ final State state = new State();
+ final HttpContext exchangeContext = new BasicHttpContext();
+ final HttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
+ final Incoming incoming = new Incoming(
+ request, this.requestHandler, this.requestConsumer, exchangeContext);
+ state.setIncoming(incoming);
state.setRequestState(MessageState.COMPLETED);
- state.setResponseProducer(this.responseProducer);
+ final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+ final Outgoing outgoing = new Outgoing(
+ request, response, this.responseProducer, exchangeContext);
+ state.setOutgoing(outgoing);
this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
- final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
response.setEntity(new NStringEntity("stuff"));
Mockito.when(this.responseProducer.generateResponse()).thenReturn(response);
@@ -668,8 +914,8 @@ public class TestHttpAsyncService {
Assert.assertEquals(MessageState.COMPLETED, state.getRequestState());
Assert.assertEquals(MessageState.BODY_STREAM, state.getResponseState());
- Assert.assertEquals("request state: COMPLETED; request: GET / HTTP/1.1; " +
- "response state: BODY_STREAM; response: HTTP/1.1 200 OK;", state.toString());
+ Assert.assertEquals("[incoming COMPLETED GET / HTTP/1.1; outgoing BODY_STREAM HTTP/1.1 200 OK]",
+ state.toString());
Mockito.verify(this.httpProcessor).process(response, exchangeContext);
Mockito.verify(this.conn).submitResponse(response);
@@ -678,22 +924,25 @@ public class TestHttpAsyncService {
@Test
public void testResponseToHead() throws Exception {
- final State state = new HttpAsyncService.State();
- final HttpContext exchangeContext = state.getContext();
- final BasicHttpRequest request = new BasicHttpRequest("HEAD", "/", HttpVersion.HTTP_1_1);
- state.setRequest(request);
+ final State state = new State();
+ final HttpContext exchangeContext = new BasicHttpContext();
+ final HttpRequest request = new BasicHttpRequest("HEAD", "/", HttpVersion.HTTP_1_1);
+ final Incoming incoming = new Incoming(
+ request, this.requestHandler, this.requestConsumer, exchangeContext);
+ state.setIncoming(incoming);
state.setRequestState(MessageState.COMPLETED);
- state.setResponseProducer(this.responseProducer);
+ final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+ final Outgoing outgoing = new Outgoing(
+ request, response, this.responseProducer, exchangeContext);
+ state.setOutgoing(outgoing);
this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
- final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
response.setEntity(new NStringEntity("stuff"));
Mockito.when(this.responseProducer.generateResponse()).thenReturn(response);
Mockito.when(this.reuseStrategy.keepAlive(response, exchangeContext)).thenReturn(Boolean.TRUE);
this.protocolHandler.responseReady(this.conn);
- Assert.assertEquals(MessageState.READY, state.getRequestState());
Assert.assertEquals(MessageState.READY, state.getResponseState());
Mockito.verify(this.httpProcessor).process(response, exchangeContext);
@@ -705,23 +954,26 @@ public class TestHttpAsyncService {
@Test
public void testResponseNotModified() throws Exception {
- final State state = new HttpAsyncService.State();
- final HttpContext exchangeContext = state.getContext();
- final BasicHttpRequest request = new BasicHttpRequest("HEAD", "/", HttpVersion.HTTP_1_1);
- state.setRequest(request);
+ final State state = new State();
+ final HttpContext exchangeContext = new BasicHttpContext();
+ final HttpRequest request = new BasicHttpRequest("HEAD", "/", HttpVersion.HTTP_1_1);
+ final Incoming incoming = new Incoming(
+ request, this.requestHandler, this.requestConsumer, exchangeContext);
+ state.setIncoming(incoming);
state.setRequestState(MessageState.COMPLETED);
- state.setResponseProducer(this.responseProducer);
+ final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
+ HttpStatus.SC_NOT_MODIFIED, "Not modified");
+ final Outgoing outgoing = new Outgoing(
+ request, response, this.responseProducer, exchangeContext);
+ state.setOutgoing(outgoing);
this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
- final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
- HttpStatus.SC_NOT_MODIFIED, "Not modified");
response.setEntity(new NStringEntity("stuff"));
Mockito.when(this.responseProducer.generateResponse()).thenReturn(response);
Mockito.when(this.reuseStrategy.keepAlive(response, exchangeContext)).thenReturn(Boolean.TRUE);
this.protocolHandler.responseReady(this.conn);
- Assert.assertEquals(MessageState.READY, state.getRequestState());
Assert.assertEquals(MessageState.READY, state.getResponseState());
Mockito.verify(this.httpProcessor).process(response, exchangeContext);
@@ -733,16 +985,21 @@ public class TestHttpAsyncService {
@Test
public void testResponseContinue() throws Exception {
- final State state = new HttpAsyncService.State();
- final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
+ final State state = new State();
+ final HttpContext exchangeContext = new BasicHttpContext();
+ final HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
HttpVersion.HTTP_1_1);
- state.setRequest(request);
+ final Incoming incoming = new Incoming(
+ request, this.requestHandler, this.requestConsumer, exchangeContext);
+ state.setIncoming(incoming);
state.setRequestState(MessageState.ACK_EXPECTED);
- state.setResponseProducer(this.responseProducer);
+ final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
+ HttpStatus.SC_CONTINUE, "Continue");
+ final Outgoing outgoing = new Outgoing(
+ request, response, this.responseProducer, exchangeContext);
+ state.setOutgoing(outgoing);
this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
- final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
- HttpStatus.SC_CONTINUE, "Continue");
Mockito.when(this.responseProducer.generateResponse()).thenReturn(response);
this.protocolHandler.responseReady(this.conn);
@@ -764,16 +1021,21 @@ public class TestHttpAsyncService {
@Test
public void testResponseFailedExpectation() throws Exception {
- final State state = new HttpAsyncService.State();
- final HttpContext exchangeContext = state.getContext();
- final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
+ final State state = new State();
+ final HttpContext exchangeContext = new BasicHttpContext();
+ final HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
HttpVersion.HTTP_1_1);
- state.setRequest(request);
+ final Incoming incoming = new Incoming(
+ request, this.requestHandler, this.requestConsumer, exchangeContext);
+ state.setIncoming(incoming);
state.setRequestState(MessageState.ACK_EXPECTED);
- state.setResponseProducer(this.responseProducer);
+ final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
+ 417, "Expectation failed");
+ final Outgoing outgoing = new Outgoing(
+ request, response, this.responseProducer, exchangeContext);
+ state.setOutgoing(outgoing);
this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
- final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 417, "Expectation failed");
response.setEntity(new NStringEntity("stuff"));
Mockito.when(this.responseProducer.generateResponse()).thenReturn(response);
@@ -788,18 +1050,100 @@ public class TestHttpAsyncService {
Mockito.verify(this.responseProducer, Mockito.never()).responseCompleted(exchangeContext);
}
+ @Test
+ public void testResponsePipelinedEmpty() throws Exception {
+ final State state = new State();
+
+ state.setRequestState(MessageState.READY);
+ this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
+
+ this.protocolHandler.responseReady(this.conn);
+
+ Assert.assertEquals(MessageState.READY, state.getRequestState());
+ Assert.assertEquals(MessageState.READY, state.getResponseState());
+ Assert.assertNull(state.getOutgoing());
+
+ Mockito.verify(conn).getContext();
+ Mockito.verifyNoMoreInteractions(requestHandler, conn);
+ }
+
+ @Test
+ public void testResponseHandlePipelinedRequest() throws Exception {
+ final State state = new State();
+ final Queue<PipelineEntry> pipeline = state.getPipeline();
+
+ final HttpContext exchangeContext = new BasicHttpContext();
+ final HttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
+ final PipelineEntry entry = new PipelineEntry(request, request, null, requestHandler, exchangeContext);
+ pipeline.add(entry);
+
+ state.setRequestState(MessageState.READY);
+ this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
+
+ this.protocolHandler.responseReady(this.conn);
+
+ Assert.assertEquals(MessageState.READY, state.getRequestState());
+ Assert.assertEquals(MessageState.INIT, state.getResponseState());
+ Assert.assertNull(state.getOutgoing());
+
+ final ArgumentCaptor<HttpAsyncExchange> argCaptor = ArgumentCaptor.forClass(HttpAsyncExchange.class);
+ Mockito.verify(this.requestHandler).handle(Mockito.same(request),
+ argCaptor.capture(), Mockito.same(exchangeContext));
+ final HttpAsyncExchange exchange = argCaptor.getValue();
+
+ Assert.assertNotNull(exchange);
+ Assert.assertSame(request, exchange.getRequest());
+ Assert.assertNotNull(exchange.getResponse());
+ Assert.assertEquals(200, exchange.getResponse().getStatusLine().getStatusCode());
+ }
+
+ @Test
+ public void testResponseHandleFailedPipelinedRequest() throws Exception {
+ final State state = new State();
+ final Queue<PipelineEntry> pipeline = state.getPipeline();
+
+ final HttpContext exchangeContext = new BasicHttpContext();
+ final HttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
+ final Exception ex = new Exception("Opppsie");
+ final PipelineEntry entry = new PipelineEntry(request, null, ex, requestHandler, exchangeContext);
+ pipeline.add(entry);
+
+ state.setRequestState(MessageState.READY);
+ this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
+
+ this.protocolHandler.responseReady(this.conn);
+
+ Assert.assertEquals(MessageState.READY, state.getRequestState());
+ Assert.assertEquals(MessageState.BODY_STREAM, state.getResponseState());
+
+ final Outgoing outgoing = state.getOutgoing();
+ Assert.assertNotNull(outgoing.getProducer());
+ final HttpResponse response = outgoing.getResponse();
+ Assert.assertNotNull(response);
+ Assert.assertEquals(500, response.getStatusLine().getStatusCode());
+
+ Mockito.verify(this.requestHandler, Mockito.never()).handle(Mockito.<HttpRequest>any(),
+ Mockito.<HttpAsyncExchange>any(), Mockito.<HttpContext>any());
+ Mockito.verify(this.conn).submitResponse(Mockito.same(response));
+ }
+
@Test(expected=HttpException.class)
public void testInvalidResponseStatus() throws Exception {
- final State state = new HttpAsyncService.State();
- final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
+ final State state = new State();
+ final HttpContext exchangeContext = new BasicHttpContext();
+ final HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
HttpVersion.HTTP_1_1);
- state.setRequest(request);
+ final Incoming incoming = new Incoming(
+ request, this.requestHandler, this.requestConsumer, exchangeContext);
+ state.setIncoming(incoming);
state.setRequestState(MessageState.COMPLETED);
state.setResponseState(MessageState.READY);
- state.setResponseProducer(this.responseProducer);
+ final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 112, "Something stupid");
+ final Outgoing outgoing = new Outgoing(
+ request, response, this.responseProducer, exchangeContext);
+ state.setOutgoing(outgoing);
this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
- final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 112, "Something stupid");
Mockito.when(this.responseProducer.generateResponse()).thenReturn(response);
Mockito.when(this.conn.isResponseSubmitted()).thenReturn(Boolean.FALSE);
@@ -808,17 +1152,22 @@ public class TestHttpAsyncService {
@Test(expected=HttpException.class)
public void testInvalidResponseStatusToExpection() throws Exception {
- final State state = new HttpAsyncService.State();
- final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
+ final State state = new State();
+ final HttpContext exchangeContext = new BasicHttpContext();
+ final HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
HttpVersion.HTTP_1_1);
- state.setRequest(request);
+ final Incoming incoming = new Incoming(
+ request, this.requestHandler, this.requestConsumer, exchangeContext);
+ state.setIncoming(incoming);
state.setRequestState(MessageState.ACK_EXPECTED);
state.setResponseState(MessageState.READY);
- state.setResponseProducer(this.responseProducer);
+ final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+ response.setEntity(new NStringEntity("stuff"));
+ final Outgoing outgoing = new Outgoing(
+ request, response, this.responseProducer, exchangeContext);
+ state.setOutgoing(outgoing);
this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
- final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
- response.setEntity(new NStringEntity("stuff"));
Mockito.when(this.responseProducer.generateResponse()).thenReturn(response);
Mockito.when(this.conn.isResponseSubmitted()).thenReturn(Boolean.FALSE);
@@ -827,22 +1176,25 @@ public class TestHttpAsyncService {
@Test
public void testResponseTrigger() throws Exception {
- final State state = new HttpAsyncService.State();
+ final State state = new State();
state.setRequestState(MessageState.COMPLETED);
state.setResponseState(MessageState.READY);
this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
- final HttpAsyncExchange httpexchanage = new HttpAsyncService.Exchange(
+ final HttpContext exchangeContext = new BasicHttpContext();
+ final HttpAsyncExchange httpexchanage = new HttpAsyncService.HttpAsyncExchangeImpl(
new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1),
new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"),
- state, this.conn);
+ state, this.conn, exchangeContext);
Assert.assertFalse(httpexchanage.isCompleted());
httpexchanage.submitResponse(this.responseProducer);
Assert.assertTrue(httpexchanage.isCompleted());
Assert.assertEquals(MessageState.COMPLETED, state.getRequestState());
Assert.assertEquals(MessageState.READY, state.getResponseState());
- Assert.assertSame(this.responseProducer, state.getResponseProducer());
+ final Outgoing outgoing = state.getOutgoing();
+ Assert.assertNotNull(outgoing);
+ Assert.assertSame(this.responseProducer, outgoing.getProducer());
Mockito.verify(this.conn).requestOutput();
@@ -855,26 +1207,30 @@ public class TestHttpAsyncService {
@Test(expected=IllegalArgumentException.class)
public void testResponseTriggerInvalidResponseProducer() throws Exception {
- final State state = new HttpAsyncService.State();
+ final State state = new State();
state.setRequestState(MessageState.ACK_EXPECTED);
this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
- final HttpAsyncExchange httpexchanage = new HttpAsyncService.Exchange(
+ final HttpContext exchangeContext = new BasicHttpContext();
+ final HttpAsyncExchange httpexchanage = new HttpAsyncService.HttpAsyncExchangeImpl(
new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1),
new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"),
- state, this.conn);
+ state, this.conn, exchangeContext);
httpexchanage.submitResponse(null);
}
@Test
public void testResponseContent() throws Exception {
- final State state = new HttpAsyncService.State();
- final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
- response.setEntity(new NStringEntity("stuff"));
+ final State state = new State();
state.setRequestState(MessageState.COMPLETED);
state.setResponseState(MessageState.BODY_STREAM);
- state.setResponse(response);
- state.setResponseProducer(this.responseProducer);
+ final HttpContext exchangeContext = new BasicHttpContext();
+ final HttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
+ final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+ response.setEntity(new NStringEntity("stuff"));
+ final Outgoing outgoing = new Outgoing(
+ request, response, this.responseProducer, exchangeContext);
+ state.setOutgoing(outgoing);
this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
Mockito.when(this.encoder.isCompleted()).thenReturn(Boolean.FALSE);
@@ -890,21 +1246,22 @@ public class TestHttpAsyncService {
@Test
public void testResponseContentCompleted() throws Exception {
- final State state = new HttpAsyncService.State();
- final HttpContext exchangeContext = state.getContext();
- final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
- response.setEntity(new NStringEntity("stuff"));
+ final State state = new State();
state.setRequestState(MessageState.COMPLETED);
state.setResponseState(MessageState.BODY_STREAM);
- state.setResponse(response);
- state.setResponseProducer(this.responseProducer);
+ final HttpContext exchangeContext = new BasicHttpContext();
+ final HttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
+ final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+ response.setEntity(new NStringEntity("stuff"));
+ final Outgoing outgoing = new Outgoing(
+ request, response, this.responseProducer, exchangeContext);
+ state.setOutgoing(outgoing);
this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
Mockito.when(this.encoder.isCompleted()).thenReturn(true);
Mockito.when(this.reuseStrategy.keepAlive(response, exchangeContext)).thenReturn(Boolean.TRUE);
this.protocolHandler.outputReady(conn, this.encoder);
- Assert.assertEquals(MessageState.READY, state.getRequestState());
Assert.assertEquals(MessageState.READY, state.getResponseState());
Mockito.verify(this.responseProducer).produceContent(this.encoder, this.conn);
@@ -915,21 +1272,22 @@ public class TestHttpAsyncService {
@Test
public void testResponseContentCompletedNoKeepAlive() throws Exception {
- final State state = new HttpAsyncService.State();
- final HttpContext exchangeContext = state.getContext();
- final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
- response.setEntity(new NStringEntity("stuff"));
+ final State state = new State();
state.setRequestState(MessageState.COMPLETED);
state.setResponseState(MessageState.BODY_STREAM);
- state.setResponse(response);
- state.setResponseProducer(this.responseProducer);
+ final HttpContext exchangeContext = new BasicHttpContext();
+ final HttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
+ final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+ response.setEntity(new NStringEntity("stuff"));
+ final Outgoing outgoing = new Outgoing(
+ request, response, this.responseProducer, exchangeContext);
+ state.setOutgoing(outgoing);
this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
Mockito.when(this.encoder.isCompleted()).thenReturn(true);
Mockito.when(this.reuseStrategy.keepAlive(response, exchangeContext)).thenReturn(Boolean.FALSE);
this.protocolHandler.outputReady(conn, this.encoder);
- Assert.assertEquals(MessageState.READY, state.getRequestState());
Assert.assertEquals(MessageState.READY, state.getResponseState());
Mockito.verify(this.responseProducer).produceContent(this.encoder, this.conn);
@@ -939,8 +1297,30 @@ public class TestHttpAsyncService {
}
@Test
+ public void testEndOfInput() throws Exception {
+
+ Mockito.when(this.conn.getSocketTimeout()).thenReturn(1000);
+
+ this.protocolHandler.endOfInput(this.conn);
+
+ Mockito.verify(this.conn, Mockito.never()).setSocketTimeout(Mockito.anyInt());
+ Mockito.verify(this.conn).close();
+ }
+
+ @Test
+ public void testEndOfInputNoTimeout() throws Exception {
+
+ Mockito.when(this.conn.getSocketTimeout()).thenReturn(0);
+
+ this.protocolHandler.endOfInput(this.conn);
+
+ Mockito.verify(this.conn).setSocketTimeout(1000);
+ Mockito.verify(this.conn).close();
+ }
+
+ @Test
public void testTimeoutActiveConnection() throws Exception {
- final State state = new HttpAsyncService.State();
+ final State state = new State();
this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
Mockito.when(this.conn.getStatus()).thenReturn(NHttpClientConnection.ACTIVE, NHttpClientConnection.CLOSED);
@@ -952,7 +1332,7 @@ public class TestHttpAsyncService {
@Test
public void testTimeoutActiveConnectionBufferedData() throws Exception {
- final State state = new HttpAsyncService.State();
+ final State state = new State();
this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
Mockito.when(this.conn.getStatus()).thenReturn(NHttpClientConnection.ACTIVE, NHttpClientConnection.CLOSING);
@@ -964,9 +1344,16 @@ public class TestHttpAsyncService {
@Test
public void testTimeoutClosingConnection() throws Exception {
- final State state = new HttpAsyncService.State();
- state.setRequestConsumer(this.requestConsumer);
- state.setResponseProducer(this.responseProducer);
+ final State state = new State();
+ final HttpContext exchangeContext = new BasicHttpContext();
+ final HttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
+ final Incoming incoming = new Incoming(
+ request, this.requestHandler, this.requestConsumer, exchangeContext);
+ state.setIncoming(incoming);
+ final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+ final Outgoing outgoing = new Outgoing(
+ request, response, this.responseProducer, exchangeContext);
+ state.setOutgoing(outgoing);
this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
Mockito.when(this.conn.getStatus()).thenReturn(NHttpClientConnection.CLOSING);