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 2012/01/16 20:55:41 UTC
svn commit: r1232131 - in /httpcomponents/httpcore/trunk:
httpcore-nio/src/main/java/org/apache/http/nio/entity/
httpcore-nio/src/main/java/org/apache/http/nio/protocol/
httpcore-nio/src/main/java/org/apache/http/nio/reactor/ssl/
httpcore-nio/src/test/...
Author: olegk
Date: Mon Jan 16 19:55:41 2012
New Revision: 1232131
URL: http://svn.apache.org/viewvc?rev=1232131&view=rev
Log:
Tweaked BasicAsyncRequestExecutionHandler API; updated tutorial and javadocs
Modified:
httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/entity/HttpAsyncContentProducer.java
httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncRequestExecutionHandler.java
httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncResponseProducer.java
httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncExchange.java
httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestExecutionHandler.java
httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestExecutor.java
httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequester.java
httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncResponseConsumer.java
httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/reactor/ssl/SSLSetupHandler.java
httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestBasicAsyncRequestExecutionHandler.java
httpcomponents/httpcore/trunk/src/docbkx/nio-ext.xml
Modified: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/entity/HttpAsyncContentProducer.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/entity/HttpAsyncContentProducer.java?rev=1232131&r1=1232130&r2=1232131&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/entity/HttpAsyncContentProducer.java (original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/entity/HttpAsyncContentProducer.java Mon Jan 16 19:55:41 2012
@@ -57,7 +57,7 @@ public interface HttpAsyncContentProduce
/**
* Determines whether or not this producer is capable of producing
- * its content more than once. Repeatable content producers are expected
+ * its content more than once. Repeatable content producers are expected
* to be able to recreate their content even after having been closed.
*/
boolean isRepeatable();
Modified: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncRequestExecutionHandler.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncRequestExecutionHandler.java?rev=1232131&r1=1232130&r2=1232131&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncRequestExecutionHandler.java (original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncRequestExecutionHandler.java Mon Jan 16 19:55:41 2012
@@ -28,6 +28,7 @@
package org.apache.http.nio.protocol;
import java.io.IOException;
+import java.util.concurrent.Future;
import org.apache.http.ConnectionReuseStrategy;
import org.apache.http.HttpException;
@@ -35,6 +36,7 @@ import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.concurrent.BasicFuture;
+import org.apache.http.concurrent.FutureCallback;
import org.apache.http.nio.ContentDecoder;
import org.apache.http.nio.ContentEncoder;
import org.apache.http.nio.IOControl;
@@ -43,28 +45,32 @@ import org.apache.http.params.HttpParams
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.HttpProcessor;
-class BasicAsyncRequestExecutionHandler<T> implements HttpAsyncRequestExecutionHandler<T> {
+/**
+ * Basic implementation of {@link HttpAsyncRequestExecutionHandler} that executes
+ * a single HTTP request / response exchange.
+ *
+ * @param <T> the result type of request execution.
+ * @since 4.2
+ */
+public class BasicAsyncRequestExecutionHandler<T> implements HttpAsyncRequestExecutionHandler<T> {
- private final BasicFuture<T> future;
private final HttpAsyncRequestProducer requestProducer;
private final HttpAsyncResponseConsumer<T> responseConsumer;
+ private final BasicFuture<T> future;
private final HttpContext localContext;
private final HttpProcessor httppocessor;
private final ConnectionReuseStrategy reuseStrategy;
private final HttpParams params;
public BasicAsyncRequestExecutionHandler(
- final BasicFuture<T> future,
final HttpAsyncRequestProducer requestProducer,
final HttpAsyncResponseConsumer<T> responseConsumer,
+ final FutureCallback<T> callback,
final HttpContext localContext,
final HttpProcessor httppocessor,
final ConnectionReuseStrategy reuseStrategy,
final HttpParams params) {
super();
- if (future == null) {
- throw new IllegalArgumentException("Request future may not be null");
- }
if (requestProducer == null) {
throw new IllegalArgumentException("Request producer may not be null");
}
@@ -83,15 +89,29 @@ class BasicAsyncRequestExecutionHandler<
if (params == null) {
throw new IllegalArgumentException("HTTP parameters may not be null");
}
- this.future = future;
this.requestProducer = requestProducer;
this.responseConsumer = responseConsumer;
+ this.future = new BasicFuture<T>(callback);
this.localContext = localContext;
this.httppocessor = httppocessor;
this.reuseStrategy = reuseStrategy;
this.params = params;
}
+ public BasicAsyncRequestExecutionHandler(
+ final HttpAsyncRequestProducer requestProducer,
+ final HttpAsyncResponseConsumer<T> responseConsumer,
+ final HttpContext localContext,
+ final HttpProcessor httppocessor,
+ final ConnectionReuseStrategy reuseStrategy,
+ final HttpParams params) {
+ this(requestProducer, responseConsumer, null, localContext, httppocessor, reuseStrategy, params);
+ }
+
+ public Future<T> getFuture() {
+ return this.future;
+ }
+
private void releaseResources() {
try {
this.responseConsumer.close();
Modified: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncResponseProducer.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncResponseProducer.java?rev=1232131&r1=1232130&r2=1232131&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncResponseProducer.java (original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncResponseProducer.java Mon Jan 16 19:55:41 2012
@@ -42,7 +42,7 @@ import org.apache.http.protocol.HttpCont
* Basic implementation of {@link HttpAsyncResponseProducer}. The producer
* can make use of the {@link HttpAsyncContentProducer} interface to
* efficiently stream out message content to the underlying non-blocking HTTP
- * connection, if it is implemented by the {@link HttpEntity} inclosed in
+ * connection, if it is implemented by the {@link HttpEntity} inclosed in
* the response.
*
* @see HttpAsyncContentProducer
Modified: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncExchange.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncExchange.java?rev=1232131&r1=1232130&r2=1232131&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncExchange.java (original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncExchange.java Mon Jan 16 19:55:41 2012
@@ -98,10 +98,10 @@ public interface HttpAsyncExchange {
* Sets timeout for this message exchange.
*/
void setTimeout(int timeout);
-
+
/**
* Returns timeout for this message exchange.
*/
int getTimeout();
-
+
}
Modified: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestExecutionHandler.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestExecutionHandler.java?rev=1232131&r1=1232130&r2=1232131&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestExecutionHandler.java (original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestExecutionHandler.java Mon Jan 16 19:55:41 2012
@@ -51,13 +51,13 @@ public interface HttpAsyncRequestExecuti
HttpContext getContext();
/**
- * Returns {@link HttpProcessor} implementation to be used to process
+ * Returns {@link HttpProcessor} implementation to be used to process
* HTTP request and response messages for protocol compliance.
*
* @return HTTP protocol processor.
*/
HttpProcessor getHttpProcessor();
-
+
/**
* Returns {@link ConnectionReuseStrategy} implementation to be used
* to determine whether or not the underlying connection can be kept alive
Modified: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestExecutor.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestExecutor.java?rev=1232131&r1=1232130&r2=1232131&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestExecutor.java (original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestExecutor.java Mon Jan 16 19:55:41 2012
@@ -52,13 +52,13 @@ import org.apache.http.protocol.HttpCont
import org.apache.http.protocol.HttpProcessor;
/**
- * <tt>HttpAsyncRequestExecutor</tt> is a fully asynchronous HTTP client side
+ * <tt>HttpAsyncRequestExecutor</tt> is a fully asynchronous HTTP client side
* protocol handler based on the NIO (non-blocking) I/O model.
- * <tt>HttpAsyncRequestExecutor</tt> translates individual events fired through
- * the {@link NHttpClientEventHandler} interface into logically related HTTP
+ * <tt>HttpAsyncRequestExecutor</tt> translates individual events fired through
+ * the {@link NHttpClientEventHandler} interface into logically related HTTP
* message exchanges.
* <p/>
- * <tt>HttpAsyncRequestExecutor</tt> relies on {@link HttpProcessor}
+ * <tt>HttpAsyncRequestExecutor</tt> relies on {@link HttpProcessor}
* to generate mandatory protocol headers for all outgoing messages and apply
* common, cross-cutting message transformations to all incoming and outgoing
* messages, whereas individual {@link HttpAsyncRequestExecutionHandler}s
@@ -68,7 +68,7 @@ import org.apache.http.protocol.HttpProc
* of HTTP message exchanges through the connection context using
* {@link #HTTP_HANDLER} attribute. HTTP exchange sequence is considered
* complete when the {@link HttpAsyncRequestExecutionHandler#isDone()} method
- * returns <code>true</tt>. The {@link HttpAsyncRequester} utility class can
+ * returns <code>true</code>. The {@link HttpAsyncRequester} utility class can
* be used to facilitate initiation of asynchronous HTTP request execution.
* <p/>
* The following parameters can be used to customize the behavior of this
@@ -150,12 +150,12 @@ public class HttpAsyncRequestExecutor im
HttpRequest request = handler.generateRequest();
context.setAttribute(ExecutionContext.HTTP_REQUEST, request);
-
+
conn.setSocketTimeout(HttpConnectionParams.getSoTimeout(request.getParams()));
-
+
HttpProcessor httppocessor = handler.getHttpProcessor();
httppocessor.process(request, context);
-
+
state.setRequest(request);
conn.submitRequest(request);
@@ -236,13 +236,13 @@ public class HttpAsyncRequestExecutor im
}
handler.responseReceived(response);
-
+
HttpContext context = handler.getContext();
HttpProcessor httpprocessor = handler.getHttpProcessor();
-
+
context.setAttribute(ExecutionContext.HTTP_RESPONSE, response);
httpprocessor.process(response, context);
-
+
state.setResponseState(MessageState.BODY_STREAM);
if (!canResponseHaveBody(request, response)) {
conn.resetInput();
Modified: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequester.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequester.java?rev=1232131&r1=1232130&r2=1232131&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequester.java (original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequester.java Mon Jan 16 19:55:41 2012
@@ -99,13 +99,12 @@ public class HttpAsyncRequester {
if (context == null) {
throw new IllegalArgumentException("HTTP context may not be null");
}
- BasicFuture<T> future = new BasicFuture<T>(callback);
- HttpAsyncRequestExecutionHandler<T> handler = new BasicAsyncRequestExecutionHandler<T>(
- future, requestProducer, responseConsumer, context,
+ BasicAsyncRequestExecutionHandler<T> handler = new BasicAsyncRequestExecutionHandler<T>(
+ requestProducer, responseConsumer, callback, context,
this.httppocessor, this.reuseStrategy, this.params);
conn.getContext().setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, handler);
conn.requestOutput();
- return future;
+ return handler.getFuture();
}
/**
@@ -243,11 +242,10 @@ public class HttpAsyncRequester {
return;
}
NHttpClientConnection conn = result.getConnection();
- BasicFuture<T> execFuture = new BasicFuture<T>(new RequestExecutionCallback<T, E>(
- this.requestFuture, result, this.connPool));
- HttpAsyncRequestExecutionHandler<T> handler = new BasicAsyncRequestExecutionHandler<T>(
- execFuture, this.requestProducer, this.responseConsumer, this.context,
- httppocessor, reuseStrategy, params);
+ BasicAsyncRequestExecutionHandler<T> handler = new BasicAsyncRequestExecutionHandler<T>(
+ this.requestProducer, this.responseConsumer,
+ new RequestExecutionCallback<T, E>(this.requestFuture, result, this.connPool),
+ this.context, httppocessor, reuseStrategy, params);
conn.getContext().setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, handler);
conn.requestOutput();
}
Modified: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncResponseConsumer.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncResponseConsumer.java?rev=1232131&r1=1232130&r2=1232131&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncResponseConsumer.java (original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncResponseConsumer.java Mon Jan 16 19:55:41 2012
@@ -97,7 +97,7 @@ public interface HttpAsyncResponseConsum
/**
* Returns a result of the response processing, when available. This method
- * returns <code>null</code> if response processing is still ongoing.
+ * returns <code>null</code> if the response processing is still ongoing.
*
* @see #isDone()
*/
Modified: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/reactor/ssl/SSLSetupHandler.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/reactor/ssl/SSLSetupHandler.java?rev=1232131&r1=1232130&r2=1232131&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/reactor/ssl/SSLSetupHandler.java (original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/reactor/ssl/SSLSetupHandler.java Mon Jan 16 19:55:41 2012
@@ -37,7 +37,7 @@ import org.apache.http.nio.reactor.IOSes
* Callback interface that can be used to customize various aspects of
* the TLS/SSl protocol.
*
- * @since 4.1
+ * @since 4.2
*/
public interface SSLSetupHandler {
Modified: httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestBasicAsyncRequestExecutionHandler.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestBasicAsyncRequestExecutionHandler.java?rev=1232131&r1=1232130&r2=1232131&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestBasicAsyncRequestExecutionHandler.java (original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestBasicAsyncRequestExecutionHandler.java Mon Jan 16 19:55:41 2012
@@ -35,7 +35,6 @@ import org.apache.http.ConnectionReuseSt
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpVersion;
-import org.apache.http.concurrent.BasicFuture;
import org.apache.http.message.BasicHttpRequest;
import org.apache.http.message.BasicHttpResponse;
import org.apache.http.nio.ContentDecoder;
@@ -53,7 +52,6 @@ import org.mockito.Mockito;
public class TestBasicAsyncRequestExecutionHandler {
- private BasicFuture<Object> future;
private HttpAsyncRequestProducer requestProducer;
private HttpAsyncResponseConsumer<Object> responseConsumer;
private HttpContext context;
@@ -68,7 +66,6 @@ public class TestBasicAsyncRequestExecut
@SuppressWarnings("unchecked")
@Before
public void setUp() throws Exception {
- this.future = new BasicFuture<Object>(null);
this.requestProducer = Mockito.mock(HttpAsyncRequestProducer.class);
this.responseConsumer = Mockito.mock(HttpAsyncResponseConsumer.class);
this.context = new BasicHttpContext();
@@ -76,7 +73,6 @@ public class TestBasicAsyncRequestExecut
this.reuseStrategy = Mockito.mock(ConnectionReuseStrategy.class);
this.params = new BasicHttpParams();
this.exchangeHandler = new BasicAsyncRequestExecutionHandler<Object>(
- this.future,
this.requestProducer,
this.responseConsumer,
this.context,
@@ -96,7 +92,6 @@ public class TestBasicAsyncRequestExecut
try {
new BasicAsyncRequestExecutionHandler<Object>(
null,
- this.requestProducer,
this.responseConsumer,
this.context,
this.httpProcessor,
@@ -107,19 +102,6 @@ public class TestBasicAsyncRequestExecut
}
try {
new BasicAsyncRequestExecutionHandler<Object>(
- this.future,
- null,
- this.responseConsumer,
- this.context,
- this.httpProcessor,
- this.reuseStrategy,
- this.params);
- Assert.fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException ex) {
- }
- try {
- new BasicAsyncRequestExecutionHandler<Object>(
- this.future,
this.requestProducer,
null,
this.context,
@@ -131,7 +113,6 @@ public class TestBasicAsyncRequestExecut
}
try {
new BasicAsyncRequestExecutionHandler<Object>(
- this.future,
this.requestProducer,
this.responseConsumer,
null,
@@ -143,7 +124,6 @@ public class TestBasicAsyncRequestExecut
}
try {
new BasicAsyncRequestExecutionHandler<Object>(
- this.future,
this.requestProducer,
this.responseConsumer,
this.context,
@@ -155,7 +135,6 @@ public class TestBasicAsyncRequestExecut
}
try {
new BasicAsyncRequestExecutionHandler<Object>(
- this.future,
this.requestProducer,
this.responseConsumer,
this.context,
@@ -167,7 +146,6 @@ public class TestBasicAsyncRequestExecut
}
try {
new BasicAsyncRequestExecutionHandler<Object>(
- this.future,
this.requestProducer,
this.responseConsumer,
this.context,
@@ -181,20 +159,11 @@ public class TestBasicAsyncRequestExecut
@Test
public void testClose() throws Exception {
- Assert.assertFalse(this.future.isCancelled());
+ Assert.assertFalse(this.exchangeHandler.getFuture().isCancelled());
this.exchangeHandler.close();
Mockito.verify(this.requestProducer).close();
Mockito.verify(this.responseConsumer).close();
- Assert.assertTrue(this.future.isCancelled());
- }
-
- @Test
- public void testCloseFutureDone() throws Exception {
- this.future.completed(null);
- this.exchangeHandler.close();
- Mockito.verify(this.requestProducer).close();
- Mockito.verify(this.responseConsumer).close();
- Assert.assertFalse(this.future.isCancelled());
+ Assert.assertTrue(this.exchangeHandler.getFuture().isCancelled());
}
@Test
@@ -212,7 +181,7 @@ public class TestBasicAsyncRequestExecut
HttpRequest result = this.exchangeHandler.generateRequest();
Assert.assertSame(request, result);
-
+
Mockito.verify(this.requestProducer).generateRequest();
}
@@ -267,7 +236,7 @@ public class TestBasicAsyncRequestExecut
Mockito.verify(this.requestProducer).close();
Mockito.verify(this.responseConsumer).close();
try {
- this.future.get();
+ this.exchangeHandler.getFuture().get();
} catch (ExecutionException ex) {
Assert.assertSame(ooopsie, ex.getCause());
}
@@ -284,7 +253,7 @@ public class TestBasicAsyncRequestExecut
Mockito.verify(this.requestProducer).close();
Mockito.verify(this.responseConsumer).close();
try {
- this.future.get();
+ this.exchangeHandler.getFuture().get();
} catch (ExecutionException exex) {
Assert.assertSame(ooopsie, exex.getCause());
}
@@ -298,7 +267,7 @@ public class TestBasicAsyncRequestExecut
Mockito.verify(this.responseConsumer).cancel();
Mockito.verify(this.requestProducer).close();
Mockito.verify(this.responseConsumer).close();
- Assert.assertTrue(this.future.isCancelled());
+ Assert.assertTrue(this.exchangeHandler.getFuture().isCancelled());
}
@Test
@@ -311,7 +280,7 @@ public class TestBasicAsyncRequestExecut
Mockito.verify(this.requestProducer).close();
Mockito.verify(this.responseConsumer).close();
try {
- this.future.get();
+ this.exchangeHandler.getFuture().get();
Assert.fail("ExecutionException expected");
} catch (ExecutionException exex) {
}
@@ -328,7 +297,7 @@ public class TestBasicAsyncRequestExecut
Mockito.verify(this.responseConsumer).responseCompleted(this.context);
Mockito.verify(this.requestProducer).close();
Mockito.verify(this.responseConsumer).close();
- Object result = this.future.get();
+ Object result = this.exchangeHandler.getFuture().get();
Assert.assertSame(obj, result);
}
@@ -343,7 +312,7 @@ public class TestBasicAsyncRequestExecut
Mockito.verify(this.requestProducer).close();
Mockito.verify(this.responseConsumer).close();
try {
- this.future.get();
+ this.exchangeHandler.getFuture().get();
} catch (ExecutionException exex) {
Assert.assertSame(ooopsie, exex.getCause());
}
@@ -359,7 +328,7 @@ public class TestBasicAsyncRequestExecut
Mockito.verify(this.requestProducer).close();
Mockito.verify(this.responseConsumer).close();
try {
- this.future.get();
+ this.exchangeHandler.getFuture().get();
Assert.fail("ExecutionException expected");
} catch (ExecutionException exex) {
}
Modified: httpcomponents/httpcore/trunk/src/docbkx/nio-ext.xml
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/src/docbkx/nio-ext.xml?rev=1232131&r1=1232130&r2=1232131&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/src/docbkx/nio-ext.xml (original)
+++ httpcomponents/httpcore/trunk/src/docbkx/nio-ext.xml Mon Jan 16 19:55:41 2012
@@ -1480,7 +1480,7 @@ HttpAsyncRequestHandler<HttpRequest> myH
<formalpara>
<title><methodname>generateResponse</methodname>:</title>
<para>
- Invoked to generate a HTTP response message head.
+ Invoked to generate a HTTP response message head.
</para>
</formalpara>
</listitem>
@@ -1496,7 +1496,12 @@ HttpAsyncRequestHandler<HttpRequest> myH
<para>
When all content is finished, the producer MUST call <methodname>
ContentEncoder#complete()</methodname>. Failure to do so may cause
- the entity to be incorrectly delimited
+ the entity to be incorrectly delimited.
+ </para>
+ <para>
+ This event is invoked only for if the outgoing response message has
+ a content entity enclosed in it, that is <methodname>
+ HttpResponse#getEntity()</methodname> returns <code>null</code>.
</para>
</formalpara>
</listitem>
@@ -1566,431 +1571,280 @@ handlerReqistry.register("*", myRequestH
</section>
</section>
<section>
- <title>Asynchronous HTTP client handler</title>
- <para>
- <classname>AsyncNHttpClientHandler</classname> is a fully asynchronous HTTP client side
- protocol handler that implements the essential requirements of the HTTP protocol for
- the client side message processing as described by RFC 2616. <classname>
- AsyncNHttpClientHandler</classname> is capable of executing HTTP requests with nearly
- constant memory footprint for individual HTTP connections. The handler stores headers
- of HTTP messages in memory, while content of message bodies is streamed directly from
- the entity to the underlying channel (and vice versa) using <interfacename>
- ConsumingNHttpEntity</interfacename> and <interfacename>ProducingNHttpEntity
- </interfacename> interfaces.
- </para>
- <para>
- When using this implementation, it is important to ensure that entities supplied for
- writing implement <interfacename>ProducingNHttpEntity</interfacename>. Doing so will
- allow the entity to be written out asynchronously. If entities supplied for writing do
- not implement the <interfacename>ProducingNHttpEntity</interfacename> interface,
- a delegate is added that buffers the entire contents in memory. Additionally, the
- buffering might take place in the I/O dispatch thread, which could cause I/O to block
- temporarily. For best results, one must ensure that all entities set on HTTP requests
- from <interfacename>NHttpRequestExecutionHandler</interfacename> implement
- <interfacename>ProducingNHttpEntity</interfacename>.
- </para>
+ <title>Asynchronous HTTP request executor</title>
<para>
- If incoming responses enclose a content entity, <interfacename>
- NHttpRequestExecutionHandler</interfacename> is expected to return a <interfacename>
- ConsumingNHttpEntity</interfacename> for reading the content. After the entity is
- finished reading the data, <methodname>NHttpRequestExecutionHandler#handleResponse()
- </methodname>method is called to process the response.
+ <classname>HttpAsyncRequestExecutor</classname> is a fully asynchronous client side
+ HTTP protocol handler based on the NIO (non-blocking) I/O model. <classname>
+ HttpAsyncRequestExecutor</classname> translates individual events fired through the
+ <interfacename>NHttpClientEventHandler</interfacename> interface into logically
+ related HTTP message exchanges.
+ </para>
+ <para>
+ <classname>HttpAsyncRequestExecutor</classname> relies on <interfacename>
+ HttpAsyncRequestExecutionHandler</interfacename> to implement application specific
+ content generation and processing and to handle logically related series of HTTP
+ request / response exchanges, which may also span across multiple connections.
+ <interfacename>HttpProcessor</interfacename> provided by the <interfacename>
+ HttpAsyncRequestExecutionHandler</interfacename> instance will be used to generate
+ mandatory protocol headers for all outgoing messages and apply common, cross-cutting
+ message transformations to all incoming and outgoing messages. The caller is expected
+ to pass an instance of <interfacename>HttpAsyncRequestExecutionHandler</interfacename>
+ to be used for the next series of HTTP message exchanges through the connection
+ context using <methodname>HttpAsyncRequestExecutor#HTTP_HANDLER</methodname> attribute.
+ HTTP exchange sequence is considered complete when the <methodname>
+ HttpAsyncRequestExecutionHandler#isDone()</methodname> method returns <code>true</code>.
</para>
+ <programlisting><![CDATA[
+HttpAsyncRequestExecutor protocolHandler = new HttpAsyncRequestExecutor();
+NHttpConnectionFactory<DefaultNHttpClientConnection> connFactory;
+// Initialize HTTP connection factory
+IOEventDispatch ioEventDispatch = new DefaultHttpClientIODispatch(protocolHandler, connFactory);
+]]></programlisting>
<para>
- <classname>AsyncNHttpClientHandler</classname> relies on <interfacename>HttpProcessor
- </interfacename>to generate mandatory protocol headers for all outgoing messages and
- apply common, cross-cutting message transformations to all incoming and outgoing
- messages, whereas HTTP request executor is expected to take care of application
- specific content generation and processing.
+ The <classname>HttpAsyncRequester</classname> utility class can be used to abstract
+ away low level details of <interfacename>HttpAsyncRequestExecutionHandler
+ </interfacename> management. Please note <classname>HttpAsyncRequester</classname>
+ supports single HTTP request / response exchanges only. It does not support HTTP
+ authentication and does not handle redirects automatically.
</para>
<programlisting><![CDATA[
-// Initialize HTTP parameters
HttpParams params;
-//Initialize HTTP processor
-HttpProcessor httpproc;
-//Create HTTP request execution handler
-NHttpRequestExecutionHandler execHandler;
-
-AsyncNHttpClientHandler handler = new AsyncNHttpClientHandler(
- httpproc,
- execHandler,
- new DefaultConnectionReuseStrategy(),
- params);
+// Initialize HTTP parameters
+HttpProcessor httpprocessor;
+// Initialize HTTP processor
+HttpAsyncRequester requester = new HttpAsyncRequester(
+ httpprocessor,
+ new DefaultConnectionReuseStrategy(),
+ params);
+
+//Obtain HTTP connection
+NHttpClientConnection conn;
+Future<HttpResponse> future = requester.execute(
+ new BasicAsyncRequestProducer(
+ new HttpHost("localhost"),
+ new BasicHttpRequest("GET", "/")),
+ new BasicAsyncResponseConsumer(),
+ conn);
+HttpResponse response = future.get();
]]></programlisting>
<section>
- <title>Asynchronous HTTP request execution handler</title>
+ <title>Asynchronous HTTP request producer</title>
<para>
- Asynchronous HTTP request execution handler can be used by client-side protocol
- handlers to trigger the submission of a new HTTP request and the processing of an
- HTTP response.
+ <interfacename>HttpAsyncRequestProducer</interfacename> facilities the process of
+ asynchronous generation of HTTP requests. It is a callback interface whose methods
+ get invoked to generate an HTTP request message and to stream message content to
+ a non-blocking client side HTTP connection.
</para>
<para>
- HTTP request execution events as defined by the <interfacename>
- NHttpRequestExecutionHandler</interfacename> interface:
+ Repeatable request producers capable of generating the same request message more
+ than once can be reset to their initial state by calling the <methodname>
+ resetRequest()</methodname> method, at which point request producers are expected
+ to release currently allocated resources that are no longer needed or re-acquire
+ resources needed to repeat the process.
+ </para>
+ <para>
+ HTTP I/O events and methods as defined by the
+ <interfacename>HttpAsyncRequestProducer</interfacename> interface:
</para>
<itemizedlist>
<listitem>
<formalpara>
- <title><methodname>initalizeContext</methodname>:</title>
+ <title><methodname>getTarget</methodname>:</title>
+ <para>
+ Invoked to obtain the request target host.
+ </para>
+ </formalpara>
+ </listitem>
+ <listitem>
+ <formalpara>
+ <title><methodname>generateRequest</methodname>:</title>
+ <para>
+ Invoked to generate a HTTP request message head. The message is expected
+ to implement the <interfacename>HttpEntityEnclosingRequest</interfacename>
+ interface if it is to enclose a content entity.
+ </para>
+ </formalpara>
+ </listitem>
+ <listitem>
+ <formalpara>
+ <title><methodname>produceContent</methodname>:</title>
+ <para>
+ Invoked to write out a chunk of content to the <interfacename>
+ ContentEncoder</interfacename>. The <interfacename>IOControl
+ </interfacename> interface can be used to suspend output events if
+ the producer is temporarily unable to produce more content.
+ </para>
<para>
- Triggered when a new connection has been established and the HTTP context
- needs to be initialized. The attachment object passed to this method is
- the same object which was passed to the connecting I/O reactor when the
- connection request was made. The attachment may optionally contain some
- state information required in order to correctly initialize the HTTP
- context.
+ When all content is finished, the producer MUST call <methodname>
+ ContentEncoder#complete()</methodname>. Failure to do so may cause
+ the entity to be incorrectly delimited
+ </para>
+ <para>
+ This event is invoked only for if the outgoing request message has
+ a content entity enclosed in it, that is <methodname>
+ HttpEntityEnclosingRequest#getEntity()</methodname> returns <code>null
+ </code>.
</para>
</formalpara>
</listitem>
<listitem>
<formalpara>
- <title><methodname>submitRequest</methodname>:</title>
+ <title><methodname>requestCompleted</methodname>:</title>
<para>
- Triggered when the underlying connection is ready to send a new HTTP
- request to the target host. This method may return null if the client is
- not yet ready to send a request. In this case the connection will remain
- open and can be activated at a later point. If the request encloses an
- entity, the entity must be an instance of <interfacename>
- ProducingNHttpEntity</interfacename>.
+ Invoked to signal that the request has been fully written out.
</para>
</formalpara>
</listitem>
<listitem>
<formalpara>
- <title><methodname>responseEntity</methodname>:</title>
+ <title><methodname>failed</methodname>:</title>
<para>
- Triggered when a response is received with an entity. This method should
- return a <interfacename>ConsumingNHttpEntity</interfacename> that will be
- used to consume the entity. Null is a valid response value, and will
- indicate that the entity should be silently ignored. After the entity is
- fully consumed, <methodname>handleResponse</methodname> method is called
- to notify a full response and enclosed entity are ready to be processed.
+ Invoked to signal that the request processing terminated abnormally.
</para>
</formalpara>
</listitem>
<listitem>
<formalpara>
- <title><methodname>handleResponse</methodname>:</title>
+ <title><methodname>resetRequest</methodname>:</title>
<para>
- Triggered when an HTTP response is ready to be processed.
+ Invoked to reset the producer to its initial state. Repeatable request
+ producers are expected to release currently allocated resources that are
+ no longer needed or re-acquire resources needed to repeat the process.
</para>
</formalpara>
</listitem>
<listitem>
<formalpara>
- <title><methodname>finalizeContext</methodname>:</title>
+ <title><methodname>close</methodname>:</title>
<para>
- Triggered when the connection is terminated. This event can be used to
- release objects stored in the context or perform some other kind of
- cleanup.
+ Closes the producer and releases all resources currently allocated by it.
</para>
</formalpara>
</listitem>
</itemizedlist>
- <programlisting><![CDATA[
-NHttpRequestExecutionHandler execHandler =
- new NHttpRequestExecutionHandler() {
-
- private final static String DONE_FLAG = "done";
-
- public void initalizeContext(
- HttpContext context,
- Object attachment) {
- if (attachment != null) {
- HttpHost virtualHost = (HttpHost) attachment;
- context.setAttribute(ExecutionContext.HTTP_TARGET_HOST,
- virtualHost);
- }
- }
-
- public void finalizeContext(HttpContext context) {
- context.removeAttribute(DONE_FLAG);
- }
-
- public HttpRequest submitRequest(HttpContext context) {
- // Submit HTTP GET once
- Object done = context.getAttribute(DONE_FLAG);
- if (done == null) {
- context.setAttribute(DONE_FLAG, Boolean.TRUE);
- return new BasicHttpRequest("GET", "/");
- } else {
- return null;
- }
- }
-
- public ConsumingNHttpEntity responseEntity(
- HttpResponse response,
- HttpContext context) throws IOException {
- // Buffer incoming content in memory for simplicity
- return new BufferingNHttpEntity(response.getEntity(),
- new HeapByteBufferAllocator());
- }
-
- public void handleResponse(
- HttpResponse response,
- HttpContext context) throws IOException {
- System.out.println(response.getStatusLine());
- if (response.getEntity() != null) {
- System.out.println(
- EntityUtils.toString(response.getEntity()));
- }
- }
-
-};
-]]></programlisting>
- </section>
- </section>
- <section>
- <title>Compatibility with blocking I/O</title>
- <para>
- In addition to asynchronous protocol handlers described above HttpCore ships two
- variants of HTTP protocol handlers that emulate blocking I/O model on top of
- non-blocking one and allow message content to be produced and consumed using standard
- <classname>java.io.OutputStream</classname> / <classname>java.io.InputStream</classname>
- API. Compatibility protocol handlers can work with HTTP request handlers and request
- executors that rely on blocking HttpEntity implementations.
- </para>
- <para>
- Compatibility protocol handlers rely on !HttpProcessor to generate mandatory protocol
- headers for all outgoing messages and apply common, cross-cutting message
- transformations to all incoming and outgoing messages, whereas individual HTTP request
- executors / HTTP request processors are expected to take care of application specific
- content generation and processing.
- </para>
- <section>
- <title>Buffering protocol handlers</title>
<para>
- <classname>BufferingHttpServiceHandler</classname> and <classname>
- BufferingHttpClientHandler</classname> are protocol handler implementations that
- provide compatibility with the blocking I/O by storing the full content of HTTP
- messages in memory. Request / response processing callbacks fire only when the
- entire message content has been read into a in-memory buffer. Please note that
- request execution / request processing take place the main I/O thread and therefore
- individual HTTP request executors / request handlers must ensure they do not block
- indefinitely.
+ <interfacename>HttpAsyncRequestProducer</interfacename> implementations are
+ expected to be tread-safe.
</para>
<para>
- Buffering protocol handler should be used only when dealing with HTTP messages
- that are known to be limited in length.
+ <classname>BasicAsyncRequestProducer</classname> is a basic implementation
+ of the <interfacename>HttpAsyncRequestProducer</interfacename> interface shipped
+ with the library. The producer can make use of the <interfacename>
+ HttpAsyncContentProducer</interfacename> interface to efficiently stream out
+ message content to a non-blocking HTTP connection, if it is implemented by the
+ <interfacename>HttpEntity</interfacename> enclosed in the request.
</para>
</section>
<section>
- <title>Throttling protocol handlers</title>
+ <title>Asynchronous HTTP response consumer</title>
<para>
- <classname>ThrottlingHttpServiceHandler</classname> and <classname>
- ThrottlingHttpClientHandler</classname> are protocol handler implementations that
- provide compatibility with the blocking I/O model by utilizing shared content
- buffers and a fairly small pool of worker threads. The throttling protocol handlers
- allocate input / output buffers of constant length upon initialization and
- control the rate of I/O events in order to ensure those content buffers do not
- ever overflow. This helps ensure nearly constant memory footprint for HTTP
- connections and avoid out of memory conditions while streaming content in and out.
- Request / response processing callbacks fire immediately when a message is
- received. The throttling protocol handlers delegate the task of processing requests
- and generating response content to an Executor, which is expected to perform those
- tasks using dedicated worker threads in order to avoid blocking the I/O thread.
- </para>
- <para>
- Usually throttling protocol handlers need only a modest number of worker threads,
- much fewer than the number of concurrent connections. If the length of the message
- is smaller or about the size of the shared content buffer worker thread will just
- store content in the buffer and terminate almost immediately without blocking.
- The I/O dispatch thread in its turn will take care of sending out the buffered
- content asynchronously. The worker thread will have to block only when processing
- large messages and the shared buffer fills up. It is generally advisable to
- allocate shared buffers of a size of an average content body for optimal
- performance.
+ <interfacename>HttpAsyncResponseConsumer</interfacename> facilities the process of
+ asynchronous processing of HTTP responses. It is a callback interface whose methods
+ get invoked to process an HTTP response message and to stream message content from
+ a non-blocking client side HTTP connection.
</para>
- </section>
- </section>
- <section>
- <title>Connection event listener</title>
- <para>
- Protocol handlers like the rest of HttpCore classes do not do logging in order to not
- impose a choice of a logging framework onto the users. However one can add logging of
- the most important connection events by injecting a <interfacename>EventListener
- </interfacename> implementation into the protocol handler.
- </para>
- <para>
- Connection events as defined by the <interfacename>EventListener</interfacename>
- interface:
- </para>
- <itemizedlist>
- <listitem>
- <formalpara>
- <title><methodname>fatalIOException</methodname>:</title>
- <para>
- Triggered when an I/O error caused the connection to be terminated.
- </para>
- </formalpara>
- </listitem>
- <listitem>
- <formalpara>
- <title><methodname>fatalProtocolException</methodname>:</title>
- <para>
- Triggered when an HTTP protocol error caused the connection to be terminated.
- </para>
- </formalpara>
- </listitem>
- <listitem>
- <formalpara>
- <title><methodname>connectionOpen</methodname>:</title>
- <para>
- Triggered when a new connection has been established.
- </para>
- </formalpara>
- </listitem>
- <listitem>
- <formalpara>
- <title><methodname>connectionClosed</methodname>:</title>
- <para>
- Triggered when the connection has been terminated.
- </para>
- </formalpara>
- </listitem>
- <listitem>
- <formalpara>
- <title><methodname>connectionTimeout</methodname>:</title>
- <para>
- Triggered when the connection has timed out.
- </para>
- </formalpara>
- </listitem>
- </itemizedlist>
- </section>
- </section>
-
- <section>
- <title>Non-blocking HTTP entities</title>
- <para>
- As discussed previously the process of content transfer for non-blocking connections works
- completely differently compared to that for blocking connections. For obvious reasons
- classic I/O abstraction based on inherently blocking <classname>java.io.InputStream
- </classname> and <classname>java.io.OutputStream</classname> classes is not applicable to
- the asynchronous process of data transfer. Therefore, non-blocking HTTP entities provide
- NIO specific extensions to the HttpEntity interface: <interfacename>ProducingNHttpEntity
- </interfacename> and <interfacename>ConsumingNHttpEntity</interfacename> interfaces.
- Implementation classes of these interfaces may throw <classname>
- java.lang.UnsupportedOperationException</classname> from <methodname>
- HttpEntity#getContent()</methodname> or <methodname>HttpEntity#writeTo()</methodname> if
- a particular implementation is unable to represent its content stream as instance of
- <classname>java.io.InputStream</classname> or cannot stream its content out to an
- <classname>java.io.OutputStream</classname>.
- </para>
- <section>
- <title>Content consuming non-blocking HTTP entity</title>
- <para>
- <interfacename>ConsumingNHttpEntity</interfacename> interface represents a non-blocking
- entity that allows content to be consumed from a content decoder. <interfacename>
- ConsumingNHttpEntity</interfacename> extends the base <interfacename>HttpEntity
- </interfacename> interface with a number of NIO specific notification methods:
- </para>
- <itemizedlist>
- <listitem>
- <formalpara>
- <title><methodname>consumeContent</methodname>:</title>
- <para>
- Notification that content is available to be read from the decoder.
- <interfacename>IOControl</interfacename> instance passed as a parameter to the
- method can be used to suspend input events if the entity is temporarily unable
- to allocate more storage to accommodate all incoming content.
- </para>
- </formalpara>
- </listitem>
- <listitem>
- <formalpara>
- <title><methodname>finish</methodname>:</title>
- <para>
- Notification that any resources allocated for reading can be released.
- </para>
- </formalpara>
- </listitem>
- </itemizedlist>
- <para>
- The following implementations of <interfacename>ConsumingNHttpEntity</interfacename>
- provided by HttpCore NIO:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- <link linkend="buffering-n-entity">
- <classname>BufferingNHttpEntity</classname>
- </link>
- </para>
- </listitem>
- <listitem>
- <para>
- <link linkend="consuming-n-entity-template">
- <classname>ConsumingNHttpEntityTemplate</classname>
- </link>
- </para>
- </listitem>
- </itemizedlist>
- <section id="buffering-n-entity">
- <title><classname>BufferingNHttpEntity</classname></title>
<para>
- <classname>BufferingNHttpEntity</classname> is a subclass of <classname>
- HttpEntityWrapper</classname> that consumes all incoming content into memory. Once
- the content body has been fully received it can be retrieved as an <classname>
- java.io.InputStream</classname> via <methodname>HttpEntity#getContent()
- </methodname>, or written to an output stream via <methodname>HttpEntity#writeTo()
- </methodname>.
+ HTTP I/O events and methods as defined by the <interfacename>
+ HttpAsyncResponseConsumer</interfacename> interface:
</para>
- </section>
- <section id="consuming-n-entity-template">
- <title><classname>ConsumingNHttpEntityTemplate</classname></title>
+ <itemizedlist>
+ <listitem>
+ <formalpara>
+ <title><methodname>responseReceived</methodname>:</title>
+ <para>
+ Invoked when a HTTP response message is received.
+ </para>
+ </formalpara>
+ </listitem>
+ <listitem>
+ <formalpara>
+ <title><methodname>consumeContent</methodname>:</title>
+ <para>
+ Invoked to process a chunk of content from the <interfacename>
+ ContentDecoder</interfacename>. The <interfacename>IOControl
+ </interfacename> interface can be used to suspend input events if
+ the consumer is temporarily unable to consume more content.
+ </para>
+ <para>
+ The consumer can use the <methodname>ContentDecoder#isCompleted()
+ </methodname> method to find out whether or not the message content
+ has been fully consumed.
+ </para>
+ <para>
+ This event is invoked only for if the incoming response message has
+ a content entity enclosed in it.
+ </para>
+ </formalpara>
+ </listitem>
+ <listitem>
+ <formalpara>
+ <title><methodname>responseCompleted</methodname>:</title>
+ <para>
+ Invoked to signal that the response has been fully processed.
+ </para>
+ </formalpara>
+ </listitem>
+ <listitem>
+ <formalpara>
+ <title><methodname>failed</methodname>:</title>
+ <para>
+ Invoked to signal that the response processing terminated abnormally.
+ </para>
+ </formalpara>
+ </listitem>
+ <listitem>
+ <formalpara>
+ <title><methodname>getException</methodname>:</title>
+ <para>
+ Returns an exception in case of an abnormal termination. This method
+ returns <code>null</code> if the response processing is still ongoing or
+ if it completed successfully.
+ </para>
+ </formalpara>
+ </listitem>
+ <listitem>
+ <formalpara>
+ <title><methodname>getResult</methodname>:</title>
+ <para>
+ Returns a result of the response processing, when available. This method
+ returns <code>null</code> if the response processing is still ongoing.
+ </para>
+ </formalpara>
+ </listitem>
+ <listitem>
+ <formalpara>
+ <title><methodname>isDone</methodname>:</title>
+ <para>
+ Determines whether or not the response processing completed. If the
+ response processing terminated normally <methodname>getResult()</methodname>
+ can be used to obtain the result. If the response processing terminated
+ abnormally <methodname>getException()</methodname> can be used to obtain
+ the cause.
+ </para>
+ </formalpara>
+ </listitem>
+ <listitem>
+ <formalpara>
+ <title><methodname>close</methodname>:</title>
+ <para>
+ Closes the consumer and releases all resources currently allocated by it.
+ </para>
+ </formalpara>
+ </listitem>
+ </itemizedlist>
<para>
- <classname>ConsumingNHttpEntityTemplate</classname> is a subclass of <classname>
- HttpEntityWrapper</classname> that decorates the incoming HTTP entity and
- delegates the handling of incoming content to a <interfacename>ContentListener
- </interfacename> instance.
+ <interfacename>HttpAsyncResponseConsumer</interfacename> implementations are
+ expected to be tread-safe.
+ </para>
+ <para>
+ <classname>BasicAsyncResponseConsumer</classname> is a very basic implementation
+ of the <interfacename>HttpAsyncResponseConsumer</interfacename> interface shipped
+ with the library. Please note that this consumer buffers response content in memory
+ and therefore should be used for relatively small response messages.
</para>
- <programlisting><![CDATA[
-static class FileWriteListener implements ContentListener {
-
- private final FileChannel fileChannel;
- private long idx = 0;
-
- public FileWriteListener(File file) throws IOException {
- this.fileChannel = new FileInputStream(file).getChannel();
- }
-
- public void contentAvailable(
- ContentDecoder decoder, IOControl ioctrl) throws IOException {
- long transferred;
- if (decoder instanceof FileContentDecoder) {
- transferred = ((FileContentDecoder) decoder).transfer(
- fileChannel, idx, Long.MAX_VALUE);
- } else {
- transferred = fileChannel.transferFrom(
- new ContentDecoderChannel(decoder),
- idx, Long.MAX_VALUE);
- }
- if (transferred > 0) {
- idx += transferred;
- }
- }
-
- public void finished() {
- try {
- fileChannel.close();
- } catch(IOException ignored) {}
- }
-
-}
-
-HttpEntity incomingEntity;
-
-File file = new File("buffer.bin");
-ConsumingNHttpEntity entity = new ConsumingNHttpEntityTemplate(
- incomingEntity,
- new FileWriteListener(file));
-]]></programlisting>
</section>
</section>
</section>
-
-
<section>
<title>Non-blocking TLS/SSL</title>
<section>
@@ -2033,14 +1887,14 @@ ConsumingNHttpEntity entity = new Consum
</listitem>
</itemizedlist>
<section>
- <title>SSL I/O session handler</title>
+ <title>SSL setup handler</title>
<para>
Applications can customize various aspects of the TLS/SSl protocol by passing a
- custom implementation of the <interfacename>SSLIOSessionHandler</interfacename>
+ custom implementation of the <interfacename>SSLSetupHandler</interfacename>
interface.
</para>
<para>
- SSL events as defined by the <interfacename>SSLIOSessionHandler</interfacename>
+ SSL events as defined by the <interfacename>SSLSetupHandler</interfacename>
interface:
</para>
<itemizedlist>
@@ -2076,11 +1930,9 @@ SSLContext sslcontext = SSLContext.getIn
sslcontext.init(null, null, null);
SSLIOSession sslsession = new SSLIOSession(
- iosession, sslcontext, new SSLIOSessionHandler() {
-
- public void initalize(
- SSLEngine sslengine,
- HttpParams params) throws SSLException {
+ iosession, SSLMode.CLIENT, sslcontext, new SSLSetupHandler() {
+
+ public void initalize(final SSLEngine sslengine) throws SSLException {
// Ask clients to authenticate
sslengine.setWantClientAuth(true);
// Enforce strong ciphers
@@ -2091,28 +1943,18 @@ SSLIOSession sslsession = new SSLIOSessi
}
public void verify(
- SocketAddress remoteAddress,
- SSLSession session) throws SSLException {
- X509Certificate[] certs = session.getPeerCertificateChain();
+ final IOSession iosession,
+ final SSLSession sslsession) throws SSLException {
+ X509Certificate[] certs = sslsession.getPeerCertificateChain();
// Examine peer certificate chain
for (X509Certificate cert: certs) {
System.out.println(cert.toString());
}
}
-
-});
+
+});
]]></programlisting>
</section>
</section>
- <section>
- <title>SSL I/O event dispatches</title>
- <para>
- HttpCore provides <classname>SSLClientIOEventDispatch</classname> and <classname>
- SSLServerIOEventDispatch</classname> I/O dispatch implementations that can be used to
- SSL enable connections managed by any arbitrary I/O reactor. The dispatches take all
- the necessary actions to wrap active I/O sessions with the SSL I/O session decorator
- and ensure correct handling of SSL protocol handshaking.
- </para>
- </section>
</section>
</chapter>