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 2011/09/01 14:32:58 UTC
svn commit: r1164047 -
/httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/
Author: olegk
Date: Thu Sep 1 12:32:57 2011
New Revision: 1164047
URL: http://svn.apache.org/viewvc?rev=1164047&view=rev
Log:
Complete rewrite of core async HTTP protocol handlers (client side protocol handler)
Added:
httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncClientExchangeHandler.java (with props)
httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncClientExchangeHandlerImpl.java (with props)
httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncClientProtocolHandler.java (contents, props changed)
- copied, changed from r1164041, httpcomponents/httpasyncclient/trunk/httpasyncclient/src/main/java/org/apache/http/impl/nio/client/NHttpClientProtocolHandler.java
httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/MessageState.java (contents, props changed)
- copied, changed from r1164042, httpcomponents/httpasyncclient/trunk/httpasyncclient/src/main/java/org/apache/http/impl/nio/client/MessageState.java
Modified:
httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/AbstractAsyncRequestConsumer.java
httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/AbstractAsyncResponseConsumer.java
httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestConsumer.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/protocol/NullRequestConsumer.java
Modified: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/AbstractAsyncRequestConsumer.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/AbstractAsyncRequestConsumer.java?rev=1164047&r1=1164046&r2=1164047&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/AbstractAsyncRequestConsumer.java (original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/AbstractAsyncRequestConsumer.java Thu Sep 1 12:32:57 2011
@@ -96,4 +96,8 @@ public abstract class AbstractAsyncReque
return this.result;
}
+ public boolean isDone() {
+ return this.completed;
+ }
+
}
Modified: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/AbstractAsyncResponseConsumer.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/AbstractAsyncResponseConsumer.java?rev=1164047&r1=1164046&r2=1164047&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/AbstractAsyncResponseConsumer.java (original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/AbstractAsyncResponseConsumer.java Thu Sep 1 12:32:57 2011
@@ -114,4 +114,8 @@ public abstract class AbstractAsyncRespo
return this.result;
}
+ public boolean isDone() {
+ return this.completed;
+ }
+
}
Added: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncClientExchangeHandler.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncClientExchangeHandler.java?rev=1164047&view=auto
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncClientExchangeHandler.java (added)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncClientExchangeHandler.java Thu Sep 1 12:32:57 2011
@@ -0,0 +1,42 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.nio.protocol;
+
+import org.apache.http.ConnectionReuseStrategy;
+import org.apache.http.protocol.HttpContext;
+
+/**
+ * @since 4.2
+ */
+public interface HttpAsyncClientExchangeHandler<T> extends HttpAsyncRequestProducer, HttpAsyncResponseConsumer<T> {
+
+ HttpContext getContext();
+
+ ConnectionReuseStrategy getConnectionReuseStrategy();
+
+}
Propchange: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncClientExchangeHandler.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncClientExchangeHandler.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncClientExchangeHandler.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncClientExchangeHandlerImpl.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncClientExchangeHandlerImpl.java?rev=1164047&view=auto
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncClientExchangeHandlerImpl.java (added)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncClientExchangeHandlerImpl.java Thu Sep 1 12:32:57 2011
@@ -0,0 +1,178 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.nio.protocol;
+
+import java.io.IOException;
+
+import org.apache.http.ConnectionReuseStrategy;
+import org.apache.http.HttpException;
+import org.apache.http.HttpHost;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.nio.ContentDecoder;
+import org.apache.http.nio.ContentEncoder;
+import org.apache.http.nio.IOControl;
+import org.apache.http.nio.NHttpClientConnection;
+import org.apache.http.params.DefaultedHttpParams;
+import org.apache.http.params.HttpParams;
+import org.apache.http.protocol.ExecutionContext;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.HttpProcessor;
+
+class HttpAsyncClientExchangeHandlerImpl<T> implements HttpAsyncClientExchangeHandler<T> {
+
+ private final HttpAsyncRequestProducer requestProducer;
+ private final HttpAsyncResponseConsumer<T> responseConsumer;
+ private final HttpContext localContext;
+ private final HttpProcessor httppocessor;
+ private final NHttpClientConnection conn;
+ private final ConnectionReuseStrategy reuseStrategy;
+ private final HttpParams params;
+
+ public HttpAsyncClientExchangeHandlerImpl(
+ final HttpAsyncRequestProducer requestProducer,
+ final HttpAsyncResponseConsumer<T> responseConsumer,
+ final HttpContext localContext,
+ final HttpProcessor httppocessor,
+ final NHttpClientConnection conn,
+ final ConnectionReuseStrategy reuseStrategy,
+ final HttpParams params) {
+ super();
+ if (requestProducer == null) {
+ throw new IllegalArgumentException("Request producer may not be null");
+ }
+ if (responseConsumer == null) {
+ throw new IllegalArgumentException("Response consumer may not be null");
+ }
+ if (localContext == null) {
+ throw new IllegalArgumentException("HTTP context may not be null");
+ }
+ if (httppocessor == null) {
+ throw new IllegalArgumentException("HTTP processor may not be null");
+ }
+ if (conn == null) {
+ throw new IllegalArgumentException("HTTP connection may not be null");
+ }
+ if (reuseStrategy == null) {
+ throw new IllegalArgumentException("Connection reuse strategy may not be null");
+ }
+ if (params == null) {
+ throw new IllegalArgumentException("HTTP parameters may not be null");
+ }
+ this.requestProducer = requestProducer;
+ this.responseConsumer = responseConsumer;
+ this.localContext = localContext;
+ this.httppocessor = httppocessor;
+ this.conn = conn;
+ this.reuseStrategy = reuseStrategy;
+ this.params = params;
+ }
+
+ public void close() throws IOException {
+ this.responseConsumer.close();
+ this.requestProducer.close();
+ }
+
+ public HttpHost getTarget() {
+ return this.requestProducer.getTarget();
+ }
+
+ public HttpRequest generateRequest() throws IOException, HttpException {
+ HttpHost target = this.requestProducer.getTarget();
+ HttpRequest request = this.requestProducer.generateRequest();
+ request.setParams(new DefaultedHttpParams(request.getParams(), this.params));
+
+ this.localContext.setAttribute(ExecutionContext.HTTP_REQUEST, request);
+ this.localContext.setAttribute(ExecutionContext.HTTP_TARGET_HOST, target);
+ this.localContext.setAttribute(ExecutionContext.HTTP_CONNECTION, this.conn);
+
+ this.httppocessor.process(request, this.localContext);
+
+ return request;
+ }
+
+ public void produceContent(
+ final ContentEncoder encoder, final IOControl ioctrl) throws IOException {
+ this.requestProducer.produceContent(encoder, ioctrl);
+ if (encoder.isCompleted()) {
+ this.requestProducer.close();
+ }
+ }
+
+ public boolean isRepeatable() {
+ return false;
+ }
+
+ public void resetRequest() {
+ }
+
+ public void responseReceived(final HttpResponse response) throws IOException, HttpException {
+ response.setParams(new DefaultedHttpParams(response.getParams(), this.params));
+ this.localContext.setAttribute(ExecutionContext.HTTP_RESPONSE, response);
+ this.httppocessor.process(response, this.localContext);
+ this.responseConsumer.responseReceived(response);
+ }
+
+ public void consumeContent(
+ final ContentDecoder decoder, final IOControl ioctrl) throws IOException {
+ this.responseConsumer.consumeContent(decoder, ioctrl);
+ }
+
+ public void responseCompleted(final HttpContext context) {
+ this.responseConsumer.responseCompleted(context);
+ }
+
+ public void failed(final Exception ex) {
+ this.responseConsumer.failed(ex);
+ }
+
+ public void cancel() {
+ this.responseConsumer.cancel();
+ }
+
+ public T getResult() {
+ return this.responseConsumer.getResult();
+ }
+
+ public Exception getException() {
+ return this.responseConsumer.getException();
+ }
+
+ public HttpContext getContext() {
+ return this.localContext;
+ }
+
+ public ConnectionReuseStrategy getConnectionReuseStrategy() {
+ return this.reuseStrategy;
+ }
+
+ public boolean isDone() {
+ return this.responseConsumer.isDone();
+ }
+
+}
Propchange: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncClientExchangeHandlerImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncClientExchangeHandlerImpl.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncClientExchangeHandlerImpl.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Copied: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncClientProtocolHandler.java (from r1164041, httpcomponents/httpasyncclient/trunk/httpasyncclient/src/main/java/org/apache/http/impl/nio/client/NHttpClientProtocolHandler.java)
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncClientProtocolHandler.java?p2=httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncClientProtocolHandler.java&p1=httpcomponents/httpasyncclient/trunk/httpasyncclient/src/main/java/org/apache/http/impl/nio/client/NHttpClientProtocolHandler.java&r1=1164041&r2=1164047&rev=1164047&view=diff
==============================================================================
--- httpcomponents/httpasyncclient/trunk/httpasyncclient/src/main/java/org/apache/http/impl/nio/client/NHttpClientProtocolHandler.java (original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncClientProtocolHandler.java Thu Sep 1 12:32:57 2011
@@ -25,14 +25,13 @@
*
*/
-package org.apache.http.impl.nio.client;
+package org.apache.http.nio.protocol;
import java.io.IOException;
import java.net.ProtocolException;
import java.net.SocketTimeoutException;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.http.ConnectionReuseStrategy;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
@@ -43,76 +42,39 @@ import org.apache.http.nio.ContentEncode
import org.apache.http.nio.NHttpClientConnection;
import org.apache.http.nio.NHttpClientHandler;
import org.apache.http.nio.NHttpConnection;
-import org.apache.http.nio.client.HttpAsyncExchangeHandler;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.http.protocol.HttpContext;
/**
- * Fully asynchronous HTTP client side protocol handler that implements the
- * essential requirements of the HTTP protocol for the server side message
- * processing as described by RFC 2616. It is capable of executing HTTP requests
- * with nearly constant memory footprint. Only HTTP message heads are stored in
- * memory, while content of message bodies is streamed directly from the entity
- * to the underlying channel (and vice versa) using {@link ConsumingNHttpEntity}
- * and {@link ProducingNHttpEntity} interfaces.
+ * @since 4.2
*/
-class NHttpClientProtocolHandler implements NHttpClientHandler {
-
- private final Log log = LogFactory.getLog(getClass());
+public class HttpAsyncClientProtocolHandler implements NHttpClientHandler {
+ public static final String HTTP_HANDLER = "http.nio.exchange-handler";
private static final String HTTP_EXCHNAGE = "http.nio.exchange";
- public NHttpClientProtocolHandler() {
+ public HttpAsyncClientProtocolHandler() {
super();
}
- private void closeConnection(final NHttpClientConnection conn) {
- try {
- conn.close();
- } catch (IOException ex) {
- try {
- conn.shutdown();
- } catch (IOException ignore) {
- this.log.debug("I/O error terminating connection: " + ex.getMessage(), ex);
- }
- }
- }
-
- protected void shutdownConnection(final NHttpClientConnection conn) {
- try {
- conn.shutdown();
- } catch (IOException ex) {
- this.log.debug("I/O error terminating connection: " + ex.getMessage(), ex);
- }
- }
-
public void connected(final NHttpClientConnection conn, final Object attachment) {
HttpExchange httpexchange = new HttpExchange();
HttpContext context = conn.getContext();
- if (this.log.isDebugEnabled()) {
- this.log.debug(conn + ": Connected");
- }
context.setAttribute(HTTP_EXCHNAGE, httpexchange);
requestReady(conn);
}
public void closed(final NHttpClientConnection conn) {
- HttpContext context = conn.getContext();
- HttpAsyncExchangeHandler<?> handler = getHandler(context);
- if (this.log.isDebugEnabled()) {
- this.log.debug(conn + ": Disconnected");
- }
+ HttpExchange httpexchange = getHttpExchange(conn);
+ HttpAsyncClientExchangeHandler<?> handler = httpexchange.getHandler();
if (handler != null) {
handler.cancel();
}
}
public void exception(final NHttpClientConnection conn, final HttpException ex) {
- HttpContext context = conn.getContext();
- HttpAsyncExchangeHandler<?> handler = getHandler(context);
- if (this.log.isErrorEnabled()) {
- this.log.error(conn + " HTTP protocol exception: " + ex.getMessage(), ex);
- }
+ HttpExchange httpexchange = getHttpExchange(conn);
+ HttpAsyncClientExchangeHandler<?> handler = httpexchange.getHandler();
if (handler != null) {
handler.failed(ex);
}
@@ -120,11 +82,8 @@ class NHttpClientProtocolHandler impleme
}
public void exception(final NHttpClientConnection conn, final IOException ex) {
- HttpContext context = conn.getContext();
- HttpAsyncExchangeHandler<?> handler = getHandler(context);
- if (this.log.isErrorEnabled()) {
- this.log.error(conn + " I/O error: " + ex.getMessage(), ex);
- }
+ HttpExchange httpexchange = getHttpExchange(conn);
+ HttpAsyncClientExchangeHandler<?> handler = httpexchange.getHandler();
if (handler != null) {
handler.failed(ex);
}
@@ -132,19 +91,17 @@ class NHttpClientProtocolHandler impleme
}
public void requestReady(final NHttpClientConnection conn) {
- HttpContext context = conn.getContext();
- HttpExchange httpexchange = getHttpExchange(context);
- HttpAsyncExchangeHandler<?> handler = getHandler(context);
- if (this.log.isDebugEnabled()) {
- this.log.debug(conn + " Request ready");
- }
+ HttpExchange httpexchange = getHttpExchange(conn);
if (httpexchange.getRequestState() != MessageState.READY) {
return;
}
+ HttpAsyncClientExchangeHandler<?> handler = httpexchange.getHandler();
+ if (handler == null) {
+ handler = (HttpAsyncClientExchangeHandler<?>) conn.getContext().removeAttribute(
+ HTTP_HANDLER);
+ httpexchange.setHandler(handler);
+ }
if (handler == null || handler.isDone()) {
- if (this.log.isDebugEnabled()) {
- this.log.debug(conn + " No request submitted");
- }
return;
}
try {
@@ -172,80 +129,62 @@ class NHttpClientProtocolHandler impleme
} else {
httpexchange.setRequestState(MessageState.COMPLETED);
}
- } catch (IOException ex) {
- if (this.log.isDebugEnabled()) {
- this.log.debug(conn + " I/O error: " + ex.getMessage(), ex);
- }
+ } catch (RuntimeException ex) {
shutdownConnection(conn);
handler.failed(ex);
- } catch (HttpException ex) {
- if (this.log.isDebugEnabled()) {
- this.log.debug(conn + " HTTP protocol exception: " + ex.getMessage(), ex);
- }
- closeConnection(conn);
+ throw ex;
+ } catch (Exception ex) {
+ shutdownConnection(conn);
handler.failed(ex);
+ onException(ex);
}
}
public void inputReady(final NHttpClientConnection conn, final ContentDecoder decoder) {
- HttpContext context = conn.getContext();
- HttpExchange httpexchange = getHttpExchange(context);
- HttpAsyncExchangeHandler<?> handler = getHandler(context);
- if (this.log.isDebugEnabled()) {
- this.log.debug(conn + " Input ready");
- }
+ HttpExchange httpexchange = getHttpExchange(conn);
+ HttpAsyncClientExchangeHandler<?> handler = httpexchange.getHandler();
try {
handler.consumeContent(decoder, conn);
- if (this.log.isDebugEnabled()) {
- this.log.debug(conn + " Content decoder " + decoder);
- }
if (decoder.isCompleted()) {
processResponse(conn, httpexchange, handler);
}
- } catch (IOException ex) {
- if (this.log.isDebugEnabled()) {
- this.log.debug("I/O error: " + ex.getMessage(), ex);
- }
+ } catch (RuntimeException ex) {
+ shutdownConnection(conn);
+ handler.failed(ex);
+ throw ex;
+ } catch (Exception ex) {
shutdownConnection(conn);
handler.failed(ex);
+ onException(ex);
}
}
public void outputReady(final NHttpClientConnection conn, final ContentEncoder encoder) {
- HttpContext context = conn.getContext();
- HttpExchange httpexchange = getHttpExchange(context);
- HttpAsyncExchangeHandler<?> handler = getHandler(context);
- if (this.log.isDebugEnabled()) {
- this.log.debug(conn + " Output ready");
- }
+ HttpExchange httpexchange = getHttpExchange(conn);
+ HttpAsyncClientExchangeHandler<?> handler = httpexchange.getHandler();
try {
if (httpexchange.getRequestState() == MessageState.ACK) {
conn.suspendOutput();
return;
}
handler.produceContent(encoder, conn);
- if (this.log.isDebugEnabled()) {
- this.log.debug(conn + " Content encoder " + encoder);
- }
if (encoder.isCompleted()) {
httpexchange.setRequestState(MessageState.COMPLETED);
}
- } catch (IOException ex) {
- if (this.log.isDebugEnabled()) {
- this.log.debug(conn + " I/O error: " + ex.getMessage(), ex);
- }
+ } catch (RuntimeException ex) {
+ shutdownConnection(conn);
+ handler.failed(ex);
+ throw ex;
+ } catch (Exception ex) {
shutdownConnection(conn);
handler.failed(ex);
+ onException(ex);
}
}
public void responseReceived(final NHttpClientConnection conn) {
- HttpContext context = conn.getContext();
- HttpExchange httpexchange = getHttpExchange(context);
- HttpAsyncExchangeHandler<?> handler = getHandler(context);
- if (this.log.isDebugEnabled()) {
- this.log.debug(conn + " Response received");
- }
+ HttpExchange httpexchange = getHttpExchange(conn);
+ HttpAsyncClientExchangeHandler<?> handler = httpexchange.getHandler();
try {
HttpResponse response = conn.getHttpResponse();
HttpRequest request = httpexchange.getRequest();
@@ -285,27 +224,23 @@ class NHttpClientProtocolHandler impleme
conn.resetInput();
processResponse(conn, httpexchange, handler);
}
- } catch (IOException ex) {
- if (this.log.isDebugEnabled()) {
- this.log.debug("I/O error: " + ex.getMessage(), ex);
- }
+ } catch (RuntimeException ex) {
shutdownConnection(conn);
handler.failed(ex);
- } catch (HttpException ex) {
- if (this.log.isDebugEnabled()) {
- this.log.debug("HTTP protocol exception: " + ex.getMessage(), ex);
- }
- closeConnection(conn);
+ throw ex;
+ } catch (Exception ex) {
+ shutdownConnection(conn);
handler.failed(ex);
+ onException(ex);
}
}
public void timeout(final NHttpClientConnection conn) {
- HttpContext context = conn.getContext();
- HttpExchange httpexchange = getHttpExchange(context);
- HttpAsyncExchangeHandler<?> handler = getHandler(context);
- if (this.log.isDebugEnabled()) {
- this.log.debug(conn + " Timeout");
+ HttpExchange httpexchange = getHttpExchange(conn);
+ HttpAsyncClientExchangeHandler<?> handler = httpexchange.getHandler();
+ if (handler == null) {
+ shutdownConnection(conn);
+ return;
}
try {
if (httpexchange.getRequestState() == MessageState.ACK) {
@@ -326,49 +261,66 @@ class NHttpClientProtocolHandler impleme
conn.shutdown();
}
}
- } catch (IOException ex) {
- if (this.log.isDebugEnabled()) {
- this.log.debug("I/O error: " + ex.getMessage(), ex);
- }
+ } catch (RuntimeException ex) {
shutdownConnection(conn);
handler.failed(ex);
+ throw ex;
+ } catch (Exception ex) {
+ shutdownConnection(conn);
+ handler.failed(ex);
+ onException(ex);
}
}
- private HttpExchange getHttpExchange(final HttpContext context) {
- return (HttpExchange) context.getAttribute(HTTP_EXCHNAGE);
+ protected void onException(final Exception ex) {
}
- private HttpAsyncExchangeHandler<?> getHandler(final HttpContext context) {
- return (HttpAsyncExchangeHandler<?>) context.getAttribute(
- DefaultAsyncRequestDirector.HTTP_EXCHANGE_HANDLER);
+ private void closeConnection(final NHttpConnection conn) {
+ try {
+ conn.close();
+ } catch (IOException ex) {
+ try {
+ conn.shutdown();
+ } catch (IOException ex2) {
+ onException(ex2);
+ }
+ }
+ }
+
+ private void shutdownConnection(final NHttpConnection conn) {
+ try {
+ conn.shutdown();
+ } catch (IOException ex) {
+ onException(ex);
+ }
+ }
+
+ private HttpExchange getHttpExchange(final NHttpConnection conn) {
+ return (HttpExchange) conn.getContext().getAttribute(HTTP_EXCHNAGE);
}
private void processResponse(
final NHttpClientConnection conn,
final HttpExchange httpexchange,
- final HttpAsyncExchangeHandler<?> handler) throws IOException {
+ final HttpAsyncClientExchangeHandler<?> handler) throws IOException {
if (!httpexchange.isValid()) {
conn.close();
}
+ HttpContext context = handler.getContext();
HttpRequest request = httpexchange.getRequest();
HttpResponse response = httpexchange.getResponse();
String method = request.getRequestLine().getMethod();
int status = response.getStatusLine().getStatusCode();
if (method.equalsIgnoreCase("CONNECT") && status == HttpStatus.SC_OK) {
- this.log.debug("CONNECT method succeeded");
conn.resetInput();
} else {
- if (!handler.keepAlive(response)) {
- this.log.debug("Connection cannot be kept alive");
+ ConnectionReuseStrategy connReuseStrategy = handler.getConnectionReuseStrategy();
+ if (!connReuseStrategy.keepAlive(response, context)) {
conn.close();
}
}
- if (this.log.isDebugEnabled()) {
- this.log.debug(conn + " Response processed");
- }
- handler.responseCompleted();
+ handler.responseCompleted(context);
httpexchange.reset();
}
@@ -389,4 +341,117 @@ class NHttpClientProtocolHandler impleme
&& status != HttpStatus.SC_RESET_CONTENT;
}
+ class HttpExchange {
+
+ private volatile HttpAsyncClientExchangeHandler<?> handler;
+ private volatile MessageState requestState;
+ private volatile MessageState responseState;
+ private volatile HttpRequest request;
+ private volatile HttpResponse response;
+ private volatile boolean valid;
+ private volatile int timeout;
+
+ HttpExchange() {
+ super();
+ this.valid = true;
+ this.requestState = MessageState.READY;
+ this.responseState = MessageState.READY;
+ }
+
+ public HttpAsyncClientExchangeHandler<?> getHandler() {
+ return this.handler;
+ }
+
+ public void setHandler(final HttpAsyncClientExchangeHandler<?> handler) {
+ if (this.handler != null) {
+ throw new IllegalStateException("Handler already set");
+ }
+ this.handler = handler;
+ }
+
+ public MessageState getRequestState() {
+ return this.requestState;
+ }
+
+ public void setRequestState(final MessageState state) {
+ this.requestState = state;
+ }
+
+ public MessageState getResponseState() {
+ return this.responseState;
+ }
+
+ public void setResponseState(final MessageState state) {
+ this.responseState = state;
+ }
+
+ public HttpRequest getRequest() {
+ return this.request;
+ }
+
+ public void setRequest(final HttpRequest request) {
+ if (this.request != null) {
+ throw new IllegalStateException("Request already set");
+ }
+ this.request = request;
+ }
+
+ public HttpResponse getResponse() {
+ return this.response;
+ }
+
+ public void setResponse(final HttpResponse response) {
+ if (this.request != null) {
+ throw new IllegalStateException("Response already set");
+ }
+ this.response = response;
+ }
+
+ public int getTimeout() {
+ return this.timeout;
+ }
+
+ public void setTimeout(int timeout) {
+ this.timeout = timeout;
+ }
+
+ public void reset() {
+ this.responseState = MessageState.READY;
+ this.requestState = MessageState.READY;
+ this.handler = null;
+ this.response = null;
+ this.request = null;
+ }
+
+ public boolean isValid() {
+ return this.valid;
+ }
+
+ public void invalidate() {
+ this.valid = false;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder buf = new StringBuilder();
+ buf.append("request state: ");
+ buf.append(this.requestState);
+ buf.append("; request: ");
+ if (this.request != null) {
+ buf.append(this.request.getRequestLine());
+ }
+ buf.append("; response state: ");
+ buf.append(this.responseState);
+ buf.append("; response: ");
+ if (this.response != null) {
+ buf.append(this.response.getStatusLine());
+ }
+ buf.append("; valid: ");
+ buf.append(this.valid);
+ buf.append(";");
+ return buf.toString();
+ }
+
+ }
+
}
Propchange: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncClientProtocolHandler.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncClientProtocolHandler.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncClientProtocolHandler.java
------------------------------------------------------------------------------
--- svn:mergeinfo (added)
+++ svn:mergeinfo Thu Sep 1 12:32:57 2011
@@ -0,0 +1 @@
+/httpcomponents/httpasyncclient/branches/conn-mgmt-redesign/httpasyncclient/src/main/java/org/apache/http/impl/nio/client/NHttpClientProtocolHandler.java:1155312-1159070
Propchange: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncClientProtocolHandler.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestConsumer.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestConsumer.java?rev=1164047&r1=1164046&r2=1164047&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestConsumer.java (original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestConsumer.java Thu Sep 1 12:32:57 2011
@@ -49,4 +49,6 @@ public interface HttpAsyncRequestConsume
T getResult();
+ boolean isDone();
+
}
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=1164047&r1=1164046&r2=1164047&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 Thu Sep 1 12:32:57 2011
@@ -54,4 +54,6 @@ public interface HttpAsyncResponseConsum
Exception getException();
+ boolean isDone();
+
}
Copied: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/MessageState.java (from r1164042, httpcomponents/httpasyncclient/trunk/httpasyncclient/src/main/java/org/apache/http/impl/nio/client/MessageState.java)
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/MessageState.java?p2=httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/MessageState.java&p1=httpcomponents/httpasyncclient/trunk/httpasyncclient/src/main/java/org/apache/http/impl/nio/client/MessageState.java&r1=1164042&r2=1164047&rev=1164047&view=diff
==============================================================================
--- httpcomponents/httpasyncclient/trunk/httpasyncclient/src/main/java/org/apache/http/impl/nio/client/MessageState.java (original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/MessageState.java Thu Sep 1 12:32:57 2011
@@ -24,7 +24,7 @@
* <http://www.apache.org/>.
*
*/
-package org.apache.http.impl.nio.client;
+package org.apache.http.nio.protocol;
enum MessageState {
Propchange: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/MessageState.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/MessageState.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/MessageState.java
------------------------------------------------------------------------------
--- svn:mergeinfo (added)
+++ svn:mergeinfo Thu Sep 1 12:32:57 2011
@@ -0,0 +1 @@
+/httpcomponents/httpasyncclient/branches/conn-mgmt-redesign/httpasyncclient/src/main/java/org/apache/http/impl/nio/client/MessageState.java:1155312-1159070
Propchange: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/MessageState.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/NullRequestConsumer.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/NullRequestConsumer.java?rev=1164047&r1=1164046&r2=1164047&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/NullRequestConsumer.java (original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/NullRequestConsumer.java Thu Sep 1 12:32:57 2011
@@ -38,6 +38,7 @@ import org.apache.http.protocol.HttpCont
class NullRequestConsumer implements HttpAsyncRequestConsumer<Object> {
private final ByteBuffer buffer;
+ private volatile boolean completed;
NullRequestConsumer() {
super();
@@ -57,13 +58,15 @@ class NullRequestConsumer implements Htt
}
public void requestCompleted(final HttpContext context) {
+ this.completed = true;
}
public void failed(final Exception ex) {
+ this.completed = true;
}
public Object getResult() {
- return Boolean.TRUE;
+ return this.completed;
}
public Exception getException() {
@@ -71,6 +74,11 @@ class NullRequestConsumer implements Htt
}
public void close() throws IOException {
+ this.completed = true;
+ }
+
+ public boolean isDone() {
+ return this.completed;
}
}
\ No newline at end of file