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 2017/05/01 11:11:11 UTC
svn commit: r1793308 [8/11] - in /httpcomponents/httpclient/trunk:
httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/
httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/
httpclient5-cache/src/test/java/org/apache/...
Copied: httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/ChainElements.java (from r1793305, httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/auth/CredentialsStore.java)
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/ChainElements.java?p2=httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/ChainElements.java&p1=httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/auth/CredentialsStore.java&r1=1793305&r2=1793308&rev=1793308&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/auth/CredentialsStore.java (original)
+++ httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/ChainElements.java Mon May 1 11:11:09 2017
@@ -24,34 +24,11 @@
* <http://www.apache.org/>.
*
*/
-package org.apache.hc.client5.http.auth;
-/**
- * Abstract store of authentication credentials.
- * <p>
- * Implementations of this interface must be thread-safe. Access to shared
- * data must be synchronized as methods of this interface may be executed
- * from multiple threads.
- *
- * @since 4.0
- */
-public interface CredentialsStore extends CredentialsProvider {
+package org.apache.hc.client5.http.impl.sync;
- /**
- * Sets the {@link Credentials credentials} for the given authentication
- * scope. Any previous credentials for the given scope will be overwritten.
- *
- * @param authscope the {@link AuthScope authentication scope}
- * @param credentials the authentication {@link Credentials credentials}
- * for the given scope.
- *
- * @see #getCredentials(AuthScope, HttpContext)
- */
- void setCredentials(AuthScope authscope, Credentials credentials);
+public enum ChainElements {
- /**
- * Clears all credentials.
- */
- void clear();
+ REDIRECT, BACK_OFF, RETRY_SERVICE_UNAVAILABLE, RETRY_IO_ERROR, PROTOCOL, MAIN_TRANSPORT
-}
+}
\ No newline at end of file
Modified: httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/CloseableHttpResponse.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/CloseableHttpResponse.java?rev=1793308&r1=1793307&r2=1793308&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/CloseableHttpResponse.java (original)
+++ httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/CloseableHttpResponse.java Mon May 1 11:11:09 2017
@@ -27,11 +27,11 @@
package org.apache.hc.client5.http.impl.sync;
-import java.io.Closeable;
import java.io.IOException;
import java.util.Iterator;
import java.util.Locale;
+import org.apache.hc.client5.http.sync.ExecRuntime;
import org.apache.hc.core5.http.ClassicHttpResponse;
import org.apache.hc.core5.http.Header;
import org.apache.hc.core5.http.HttpEntity;
@@ -47,9 +47,9 @@ import org.apache.hc.core5.util.Args;
public final class CloseableHttpResponse implements ClassicHttpResponse {
private final ClassicHttpResponse response;
- private final Closeable closeable;
+ private final ExecRuntime execRuntime;
- public static CloseableHttpResponse adapt(final ClassicHttpResponse response) {
+ static CloseableHttpResponse adapt(final ClassicHttpResponse response) {
if (response == null) {
return null;
}
@@ -60,9 +60,9 @@ public final class CloseableHttpResponse
}
}
- public CloseableHttpResponse(final ClassicHttpResponse response, final Closeable closeable) {
+ CloseableHttpResponse(final ClassicHttpResponse response, final ExecRuntime execRuntime) {
this.response = Args.notNull(response, "Response");
- this.closeable = closeable;
+ this.execRuntime = execRuntime;
}
@Override
@@ -197,12 +197,15 @@ public final class CloseableHttpResponse
@Override
public void close() throws IOException {
- try {
- response.close();
- } finally {
- if (closeable != null) {
- closeable.close();
+ if (execRuntime != null) {
+ try {
+ response.close();
+ execRuntime.disconnect();
+ } finally {
+ execRuntime.discardConnection();
}
+ } else {
+ response.close();
}
}
Modified: httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/DefaultHttpRequestRetryHandler.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/DefaultHttpRequestRetryHandler.java?rev=1793308&r1=1793307&r2=1793308&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/DefaultHttpRequestRetryHandler.java (original)
+++ httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/DefaultHttpRequestRetryHandler.java Mon May 1 11:11:09 2017
@@ -42,7 +42,7 @@ import java.util.concurrent.ConcurrentHa
import javax.net.ssl.SSLException;
import org.apache.hc.client5.http.sync.HttpRequestRetryHandler;
-import org.apache.hc.client5.http.sync.methods.HttpUriRequest;
+import org.apache.hc.client5.http.sync.methods.HttpUriRequestBase;
import org.apache.hc.core5.annotation.Contract;
import org.apache.hc.core5.annotation.ThreadingBehavior;
import org.apache.hc.core5.http.HttpRequest;
@@ -153,7 +153,7 @@ public class DefaultHttpRequestRetryHand
}
}
}
- if (request instanceof HttpUriRequest && ((HttpUriRequest)request).isAborted()) {
+ if (request instanceof HttpUriRequestBase && ((HttpUriRequestBase)request).isAborted()) {
return false;
}
if (handleAsIdempotent(request)) {
Copied: httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/ExecChainElement.java (from r1793305, httpcomponents/httpclient/trunk/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/DummyBackend.java)
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/ExecChainElement.java?p2=httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/ExecChainElement.java&p1=httpcomponents/httpclient/trunk/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/DummyBackend.java&r1=1793305&r2=1793308&rev=1793308&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/DummyBackend.java (original)
+++ httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/ExecChainElement.java Mon May 1 11:11:09 2017
@@ -24,46 +24,47 @@
* <http://www.apache.org/>.
*
*/
-package org.apache.hc.client5.http.impl.cache;
+
+package org.apache.hc.client5.http.impl.sync;
import java.io.IOException;
-import org.apache.hc.client5.http.impl.sync.ClientExecChain;
-import org.apache.hc.client5.http.protocol.HttpClientContext;
-import org.apache.hc.client5.http.sync.methods.HttpExecutionAware;
-import org.apache.hc.client5.http.impl.sync.RoutedHttpRequest;
+import org.apache.hc.client5.http.sync.ExecChain;
+import org.apache.hc.client5.http.sync.ExecChainHandler;
import org.apache.hc.core5.http.ClassicHttpRequest;
import org.apache.hc.core5.http.ClassicHttpResponse;
import org.apache.hc.core5.http.HttpException;
-import org.apache.hc.core5.http.HttpRequest;
-import org.apache.hc.core5.http.HttpStatus;
-import org.apache.hc.core5.http.message.BasicClassicHttpResponse;
-
-public class DummyBackend implements ClientExecChain {
-
- private ClassicHttpRequest request;
- private ClassicHttpResponse response = new BasicClassicHttpResponse(HttpStatus.SC_OK, "OK");
- private int executions = 0;
- public void setResponse(final ClassicHttpResponse resp) {
- response = resp;
- }
+class ExecChainElement {
+
+ private final ExecChainHandler handler;
+ private final ExecChainElement next;
- public HttpRequest getCapturedRequest() {
- return request;
+ ExecChainElement(final ExecChainHandler handler, final ExecChainElement next) {
+ this.handler = handler;
+ this.next = next;
}
- @Override
public ClassicHttpResponse execute(
- final RoutedHttpRequest request,
- final HttpClientContext clientContext,
- final HttpExecutionAware execAware) throws IOException, HttpException {
- this.request = request;
- executions++;
- return response;
+ final ClassicHttpRequest request,
+ final ExecChain.Scope scope) throws IOException, HttpException {
+ return handler.execute(request, scope, new ExecChain() {
+
+ @Override
+ public ClassicHttpResponse proceed(
+ final ClassicHttpRequest request,
+ final Scope scope) throws IOException, HttpException {
+ return next.execute(request, scope);
+ }
+
+ });
}
- public int getExecutions() {
- return executions;
+ @Override
+ public String toString() {
+ return "{" +
+ "handler=" + handler.getClass() +
+ ", next=" + (next != null ? next.handler.getClass() : "null") +
+ '}';
}
-}
+}
\ No newline at end of file
Added: httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/ExecRuntimeImpl.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/ExecRuntimeImpl.java?rev=1793308&view=auto
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/ExecRuntimeImpl.java (added)
+++ httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/ExecRuntimeImpl.java Mon May 1 11:11:09 2017
@@ -0,0 +1,250 @@
+/*
+ * ====================================================================
+ * 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.hc.client5.http.impl.sync;
+
+import java.io.IOException;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.apache.hc.client5.http.CancellableAware;
+import org.apache.hc.client5.http.HttpRoute;
+import org.apache.hc.client5.http.config.RequestConfig;
+import org.apache.hc.client5.http.io.ConnectionEndpoint;
+import org.apache.hc.client5.http.io.HttpClientConnectionManager;
+import org.apache.hc.client5.http.io.LeaseRequest;
+import org.apache.hc.client5.http.protocol.HttpClientContext;
+import org.apache.hc.client5.http.sync.ExecRuntime;
+import org.apache.hc.core5.concurrent.Cancellable;
+import org.apache.hc.core5.http.ClassicHttpRequest;
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.ConnectionRequestTimeoutException;
+import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.http.impl.io.HttpRequestExecutor;
+import org.apache.hc.core5.io.ShutdownType;
+import org.apache.hc.core5.util.TimeValue;
+import org.apache.logging.log4j.Logger;
+
+class ExecRuntimeImpl implements ExecRuntime, Cancellable {
+
+ private final Logger log;
+
+ private final HttpClientConnectionManager manager;
+ private final HttpRequestExecutor requestExecutor;
+ private final CancellableAware cancellableAware;
+ private final AtomicReference<ConnectionEndpoint> endpointRef;
+
+ private volatile boolean reusable;
+ private volatile Object state;
+ private volatile TimeValue validDuration;
+
+ ExecRuntimeImpl(
+ final Logger log,
+ final HttpClientConnectionManager manager,
+ final HttpRequestExecutor requestExecutor,
+ final CancellableAware cancellableAware) {
+ super();
+ this.log = log;
+ this.manager = manager;
+ this.requestExecutor = requestExecutor;
+ this.cancellableAware = cancellableAware;
+ this.endpointRef = new AtomicReference<>(null);
+ this.validDuration = TimeValue.NEG_ONE_MILLISECONDS;
+ }
+
+ @Override
+ public boolean isExecutionAborted() {
+ return cancellableAware != null && cancellableAware.isCancelled();
+ }
+
+ @Override
+ public boolean isConnectionAcquired() {
+ return endpointRef.get() != null;
+ }
+
+ @Override
+ public void acquireConnection(final HttpRoute route, final Object object, final HttpClientContext context) throws IOException {
+ if (endpointRef.get() == null) {
+ final LeaseRequest connRequest = manager.lease(route, object);
+ state = object;
+ if (cancellableAware != null) {
+ if (cancellableAware.isCancelled()) {
+ connRequest.cancel();
+ throw new RequestFailedException("Request aborted");
+ }
+ cancellableAware.setCancellable(connRequest);
+ }
+ try {
+ final RequestConfig requestConfig = context.getRequestConfig();
+ final TimeValue timeout = requestConfig.getConnectionRequestTimeout();
+ final ConnectionEndpoint connectionEndpoint = connRequest.get(timeout.getDuration(), timeout.getTimeUnit());
+ endpointRef.set(connectionEndpoint);
+ if (!connectionEndpoint.isConnected()) {
+ reusable = false;
+ }
+ if (cancellableAware != null) {
+ cancellableAware.setCancellable(this);
+ }
+ } catch(final TimeoutException ex) {
+ throw new ConnectionRequestTimeoutException(ex.getMessage());
+ } catch(final InterruptedException interrupted) {
+ Thread.currentThread().interrupt();
+ throw new RequestFailedException("Request aborted", interrupted);
+ } catch(final ExecutionException ex) {
+ Throwable cause = ex.getCause();
+ if (cause == null) {
+ cause = ex;
+ }
+ throw new RequestFailedException("Request execution failed", cause);
+ }
+ } else {
+ throw new IllegalStateException("Endpoint already acquired");
+ }
+ }
+
+ ConnectionEndpoint ensureValid() {
+ final ConnectionEndpoint endpoint = endpointRef.get();
+ if (endpoint == null) {
+ throw new IllegalStateException("Endpoint not acquired / already released");
+ }
+ return endpoint;
+ }
+
+ @Override
+ public boolean isConnected() {
+ final ConnectionEndpoint endpoint = endpointRef.get();
+ return endpoint != null && endpoint.isConnected();
+ }
+
+ @Override
+ public void connect(final HttpClientContext context) throws IOException {
+ final ConnectionEndpoint endpoint = ensureValid();
+ if (!endpoint.isConnected()) {
+ if (cancellableAware != null) {
+ if (cancellableAware.isCancelled()) {
+ throw new RequestFailedException("Request aborted");
+ }
+ }
+ final RequestConfig requestConfig = context.getRequestConfig();
+ final TimeValue connectTimeout = requestConfig.getConnectTimeout();
+ manager.connect(endpoint, connectTimeout, context);
+ final TimeValue socketTimeout = requestConfig.getSocketTimeout();
+ if (socketTimeout.getDuration() >= 0) {
+ endpoint.setSocketTimeout(socketTimeout.toMillisIntBound());
+ }
+ }
+ }
+
+ @Override
+ public void disconnect() throws IOException {
+ final ConnectionEndpoint endpoint = endpointRef.get();
+ if (endpoint != null) {
+ endpoint.close();
+ }
+ }
+
+ @Override
+ public void upgradeTls(final HttpClientContext context) throws IOException {
+ final ConnectionEndpoint endpoint = ensureValid();
+ manager.upgrade(endpoint, context);
+ }
+
+ @Override
+ public ClassicHttpResponse execute(final ClassicHttpRequest request, final HttpClientContext context) throws IOException, HttpException {
+ final ConnectionEndpoint endpoint = ensureValid();
+ return endpoint.execute(request, requestExecutor, context);
+ }
+
+ @Override
+ public boolean isConnectionReusable() {
+ return reusable;
+ }
+
+ @Override
+ public void markConnectionReusable() {
+ reusable = true;
+ }
+
+ @Override
+ public void markConnectionNonReusable() {
+ reusable = false;
+ }
+
+ @Override
+ public void setConnectionState(final Object state) {
+ this.state = state;
+ }
+
+ @Override
+ public void setConnectionValidFor(final TimeValue duration) {
+ validDuration = duration;
+ }
+
+ @Override
+ public void releaseConnection() {
+ final ConnectionEndpoint endpoint = endpointRef.getAndSet(null);
+ if (endpoint != null) {
+ if (reusable) {
+ manager.release(endpoint, state, validDuration);
+ } else {
+ try {
+ endpoint.close();
+ log.debug("Connection discarded");
+ } catch (final IOException ex) {
+ if (log.isDebugEnabled()) {
+ log.debug(ex.getMessage(), ex);
+ }
+ } finally {
+ manager.release(endpoint, null, TimeValue.ZERO_MILLISECONDS);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void discardConnection() {
+ final ConnectionEndpoint endpoint = endpointRef.getAndSet(null);
+ if (endpoint != null) {
+ try {
+ endpoint.shutdown(ShutdownType.IMMEDIATE);
+ log.debug("Connection discarded");
+ } finally {
+ manager.release(endpoint, null, TimeValue.ZERO_MILLISECONDS);
+ }
+ }
+ }
+
+ @Override
+ public boolean cancel() {
+ final boolean alreadyReleased = endpointRef.get() == null;
+ log.debug("Cancelling request execution");
+ discardConnection();
+ return !alreadyReleased;
+ }
+
+}
Propchange: httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/ExecRuntimeImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/ExecRuntimeImpl.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/ExecRuntimeImpl.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/FutureRequestExecutionService.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/FutureRequestExecutionService.java?rev=1793308&r1=1793307&r2=1793308&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/FutureRequestExecutionService.java (original)
+++ httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/FutureRequestExecutionService.java Mon May 1 11:11:09 2017
@@ -32,10 +32,10 @@ import java.util.concurrent.ExecutorServ
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.hc.client5.http.sync.HttpClient;
-import org.apache.hc.client5.http.sync.methods.HttpUriRequest;
import org.apache.hc.core5.annotation.Contract;
import org.apache.hc.core5.annotation.ThreadingBehavior;
import org.apache.hc.core5.concurrent.FutureCallback;
+import org.apache.hc.core5.http.ClassicHttpRequest;
import org.apache.hc.core5.http.io.ResponseHandler;
import org.apache.hc.core5.http.protocol.HttpContext;
@@ -83,7 +83,7 @@ public class FutureRequestExecutionServi
* @return HttpAsyncClientFutureTask for the scheduled request.
*/
public <T> HttpRequestFutureTask<T> execute(
- final HttpUriRequest request,
+ final ClassicHttpRequest request,
final HttpContext context,
final ResponseHandler<T> responseHandler) {
return execute(request, context, responseHandler, null);
@@ -106,7 +106,7 @@ public class FutureRequestExecutionServi
* @return HttpAsyncClientFutureTask for the scheduled request.
*/
public <T> HttpRequestFutureTask<T> execute(
- final HttpUriRequest request,
+ final ClassicHttpRequest request,
final HttpContext context,
final ResponseHandler<T> responseHandler,
final FutureCallback<T> callback) {
Modified: httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/HttpClientBuilder.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/HttpClientBuilder.java?rev=1793308&r1=1793307&r2=1793308&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/HttpClientBuilder.java (original)
+++ httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/HttpClientBuilder.java Mon May 1 11:11:09 2017
@@ -53,6 +53,7 @@ import org.apache.hc.client5.http.impl.D
import org.apache.hc.client5.http.impl.DefaultSchemePortResolver;
import org.apache.hc.client5.http.impl.DefaultUserTokenHandler;
import org.apache.hc.client5.http.impl.IdleConnectionEvictor;
+import org.apache.hc.client5.http.impl.NamedElementChain;
import org.apache.hc.client5.http.impl.NoopUserTokenHandler;
import org.apache.hc.client5.http.impl.auth.BasicSchemeFactory;
import org.apache.hc.client5.http.impl.auth.CredSspSchemeFactory;
@@ -82,8 +83,10 @@ import org.apache.hc.client5.http.protoc
import org.apache.hc.client5.http.routing.HttpRoutePlanner;
import org.apache.hc.client5.http.sync.BackoffManager;
import org.apache.hc.client5.http.sync.ConnectionBackoffStrategy;
+import org.apache.hc.client5.http.sync.ExecChainHandler;
import org.apache.hc.client5.http.sync.HttpRequestRetryHandler;
import org.apache.hc.client5.http.sync.ServiceUnavailableRetryStrategy;
+import org.apache.hc.core5.annotation.Internal;
import org.apache.hc.core5.http.ConnectionReuseStrategy;
import org.apache.hc.core5.http.Header;
import org.apache.hc.core5.http.HttpHost;
@@ -97,12 +100,12 @@ import org.apache.hc.core5.http.impl.Def
import org.apache.hc.core5.http.impl.io.HttpRequestExecutor;
import org.apache.hc.core5.http.protocol.DefaultHttpProcessor;
import org.apache.hc.core5.http.protocol.HttpContext;
-import org.apache.hc.core5.http.protocol.HttpProcessor;
import org.apache.hc.core5.http.protocol.HttpProcessorBuilder;
import org.apache.hc.core5.http.protocol.RequestContent;
import org.apache.hc.core5.http.protocol.RequestTargetHost;
import org.apache.hc.core5.http.protocol.RequestUserAgent;
import org.apache.hc.core5.pool.ConnPoolControl;
+import org.apache.hc.core5.util.Args;
import org.apache.hc.core5.util.TimeValue;
import org.apache.hc.core5.util.VersionInfo;
@@ -132,6 +135,54 @@ import org.apache.hc.core5.util.VersionI
*/
public class HttpClientBuilder {
+ private static class RequestInterceptorEntry {
+
+ enum Postion { FIRST, LAST }
+
+ final Postion postion;
+ final HttpRequestInterceptor interceptor;
+
+ private RequestInterceptorEntry(final Postion postion, final HttpRequestInterceptor interceptor) {
+ this.postion = postion;
+ this.interceptor = interceptor;
+ }
+ }
+
+ private static class ResponseInterceptorEntry {
+
+ enum Postion { FIRST, LAST }
+
+ final Postion postion;
+ final HttpResponseInterceptor interceptor;
+
+ private ResponseInterceptorEntry(final Postion postion, final HttpResponseInterceptor interceptor) {
+ this.postion = postion;
+ this.interceptor = interceptor;
+ }
+ }
+
+ private static class ExecInterceptorEntry {
+
+ enum Postion { BEFORE, AFTER, REPLACE }
+
+ final Postion postion;
+ final String name;
+ final ExecChainHandler interceptor;
+ final String existing;
+
+ private ExecInterceptorEntry(
+ final Postion postion,
+ final String name,
+ final ExecChainHandler interceptor,
+ final String existing) {
+ this.postion = postion;
+ this.name = name;
+ this.interceptor = interceptor;
+ this.existing = existing;
+ }
+
+ }
+
private HttpRequestExecutor requestExec;
private HttpClientConnectionManager connManager;
private boolean connManagerShared;
@@ -142,10 +193,9 @@ public class HttpClientBuilder {
private AuthenticationStrategy proxyAuthStrategy;
private UserTokenHandler userTokenHandler;
- private LinkedList<HttpRequestInterceptor> requestFirst;
- private LinkedList<HttpRequestInterceptor> requestLast;
- private LinkedList<HttpResponseInterceptor> responseFirst;
- private LinkedList<HttpResponseInterceptor> responseLast;
+ private LinkedList<RequestInterceptorEntry> requestInterceptors;
+ private LinkedList<ResponseInterceptorEntry> responseInterceptors;
+ private LinkedList<ExecInterceptorEntry> execInterceptors;
private HttpRequestRetryHandler retryHandler;
private HttpRoutePlanner routePlanner;
@@ -307,56 +357,89 @@ public class HttpClientBuilder {
/**
* Adds this protocol interceptor to the head of the protocol processing list.
*/
- public final HttpClientBuilder addInterceptorFirst(final HttpResponseInterceptor itcp) {
- if (itcp == null) {
- return this;
- }
- if (responseFirst == null) {
- responseFirst = new LinkedList<>();
+ public final HttpClientBuilder addRequestInterceptorFirst(final HttpResponseInterceptor interceptor) {
+ Args.notNull(interceptor, "Interceptor");
+ if (responseInterceptors == null) {
+ responseInterceptors = new LinkedList<>();
}
- responseFirst.addFirst(itcp);
+ responseInterceptors.add(new ResponseInterceptorEntry(ResponseInterceptorEntry.Postion.FIRST, interceptor));
return this;
}
/**
* Adds this protocol interceptor to the tail of the protocol processing list.
*/
- public final HttpClientBuilder addInterceptorLast(final HttpResponseInterceptor itcp) {
- if (itcp == null) {
- return this;
- }
- if (responseLast == null) {
- responseLast = new LinkedList<>();
+ public final HttpClientBuilder addResponseInterceptorLast(final HttpResponseInterceptor interceptor) {
+ Args.notNull(interceptor, "Interceptor");
+ if (responseInterceptors == null) {
+ responseInterceptors = new LinkedList<>();
}
- responseLast.addLast(itcp);
+ responseInterceptors.add(new ResponseInterceptorEntry(ResponseInterceptorEntry.Postion.LAST, interceptor));
return this;
}
/**
* Adds this protocol interceptor to the head of the protocol processing list.
*/
- public final HttpClientBuilder addInterceptorFirst(final HttpRequestInterceptor itcp) {
- if (itcp == null) {
- return this;
+ public final HttpClientBuilder addRequestInterceptorFirst(final HttpRequestInterceptor interceptor) {
+ Args.notNull(interceptor, "Interceptor");
+ if (requestInterceptors == null) {
+ requestInterceptors = new LinkedList<>();
}
- if (requestFirst == null) {
- requestFirst = new LinkedList<>();
- }
- requestFirst.addFirst(itcp);
+ requestInterceptors.add(new RequestInterceptorEntry(RequestInterceptorEntry.Postion.FIRST, interceptor));
return this;
}
/**
* Adds this protocol interceptor to the tail of the protocol processing list.
*/
- public final HttpClientBuilder addInterceptorLast(final HttpRequestInterceptor itcp) {
- if (itcp == null) {
- return this;
+ public final HttpClientBuilder addResponseInterceptorLast(final HttpRequestInterceptor interceptor) {
+ Args.notNull(interceptor, "Interceptor");
+ if (requestInterceptors == null) {
+ requestInterceptors = new LinkedList<>();
+ }
+ requestInterceptors.add(new RequestInterceptorEntry(RequestInterceptorEntry.Postion.LAST, interceptor));
+ return this;
+ }
+
+ /**
+ * Adds this execution interceptor before an existing interceptor.
+ */
+ public final HttpClientBuilder addExecInterceptorBefore(final String existing, final String name, final ExecChainHandler interceptor) {
+ Args.notBlank(existing, "Existing");
+ Args.notBlank(name, "Name");
+ Args.notNull(interceptor, "Interceptor");
+ if (execInterceptors == null) {
+ execInterceptors = new LinkedList<>();
}
- if (requestLast == null) {
- requestLast = new LinkedList<>();
+ execInterceptors.add(new ExecInterceptorEntry(ExecInterceptorEntry.Postion.BEFORE, name, interceptor, existing));
+ return this;
+ }
+
+ /**
+ * Adds this execution interceptor after interceptor with the given name.
+ */
+ public final HttpClientBuilder addExecInterceptorAfter(final String existing, final String name, final ExecChainHandler interceptor) {
+ Args.notBlank(existing, "Existing");
+ Args.notBlank(name, "Name");
+ Args.notNull(interceptor, "Interceptor");
+ if (execInterceptors == null) {
+ execInterceptors = new LinkedList<>();
+ }
+ execInterceptors.add(new ExecInterceptorEntry(ExecInterceptorEntry.Postion.AFTER, name, interceptor, existing));
+ return this;
+ }
+
+ /**
+ * Replace an existing interceptor with the given name with new interceptor.
+ */
+ public final HttpClientBuilder replaceExecInterceptor(final String existing, final ExecChainHandler interceptor) {
+ Args.notBlank(existing, "Existing");
+ Args.notNull(interceptor, "Interceptor");
+ if (execInterceptors == null) {
+ execInterceptors = new LinkedList<>();
}
- requestLast.addLast(itcp);
+ execInterceptors.add(new ExecInterceptorEntry(ExecInterceptorEntry.Postion.REPLACE, existing, interceptor, existing));
return this;
}
@@ -589,54 +672,20 @@ public class HttpClientBuilder {
}
/**
- * Produces an instance of {@link ClientExecChain} to be used as a main exec.
- * <p>
- * Default implementation produces an instance of {@link MainClientExec}
- * </p>
+ * Request exec chain customization and extension.
* <p>
* For internal use.
- * </p>
- *
- * @since 4.4
- */
- protected ClientExecChain createMainExec(
- final HttpRequestExecutor requestExec,
- final HttpClientConnectionManager connManager,
- final ConnectionReuseStrategy reuseStrategy,
- final ConnectionKeepAliveStrategy keepAliveStrategy,
- final HttpProcessor proxyHttpProcessor,
- final AuthenticationStrategy targetAuthStrategy,
- final AuthenticationStrategy proxyAuthStrategy,
- final UserTokenHandler userTokenHandler)
- {
- return new MainClientExec(
- requestExec,
- connManager,
- reuseStrategy,
- keepAliveStrategy,
- proxyHttpProcessor,
- targetAuthStrategy,
- proxyAuthStrategy,
- userTokenHandler);
- }
-
- /**
- * For internal use.
- */
- protected ClientExecChain decorateMainExec(final ClientExecChain mainExec) {
- return mainExec;
- }
-
- /**
- * For internal use.
*/
- protected ClientExecChain decorateProtocolExec(final ClientExecChain protocolExec) {
- return protocolExec;
+ @Internal
+ protected void customizeExecChain(final NamedElementChain<ExecChainHandler> execChainDefinition) {
}
/**
+ * Adds to the list of {@link Closeable} resources to be managed by the client.
+ * <p>
* For internal use.
*/
+ @Internal
protected void addCloseable(final Closeable closeable) {
if (closeable == null) {
return;
@@ -709,27 +758,30 @@ public class HttpClientBuilder {
}
}
- ClientExecChain execChain = createMainExec(
- requestExecCopy,
- connManagerCopy,
- reuseStrategyCopy,
- keepAliveStrategyCopy,
- new DefaultHttpProcessor(new RequestTargetHost(), new RequestUserAgent(userAgentCopy)),
- targetAuthStrategyCopy,
- proxyAuthStrategyCopy,
- userTokenHandlerCopy);
-
- execChain = decorateMainExec(execChain);
+ final NamedElementChain<ExecChainHandler> execChainDefinition = new NamedElementChain<>();
+ execChainDefinition.addLast(
+ new MainClientExec(
+ reuseStrategyCopy,
+ keepAliveStrategyCopy,
+ new DefaultHttpProcessor(new RequestTargetHost(), new RequestUserAgent(userAgentCopy)),
+ targetAuthStrategyCopy,
+ proxyAuthStrategyCopy,
+ userTokenHandlerCopy),
+ ChainElements.MAIN_TRANSPORT.name());
final HttpProcessorBuilder b = HttpProcessorBuilder.create();
- if (requestFirst != null) {
- for (final HttpRequestInterceptor i: requestFirst) {
- b.addFirst(i);
+ if (requestInterceptors != null) {
+ for (final RequestInterceptorEntry entry: requestInterceptors) {
+ if (entry.postion == RequestInterceptorEntry.Postion.FIRST) {
+ b.addFirst(entry.interceptor);
+ }
}
}
- if (responseFirst != null) {
- for (final HttpResponseInterceptor i: responseFirst) {
- b.addFirst(i);
+ if (responseInterceptors != null) {
+ for (final ResponseInterceptorEntry entry: responseInterceptors) {
+ if (entry.postion == ResponseInterceptorEntry.Postion.FIRST) {
+ b.addFirst(entry.interceptor);
+ }
}
}
b.addAll(
@@ -768,19 +820,23 @@ public class HttpClientBuilder {
b.add(new ResponseContentEncoding());
}
}
- if (requestLast != null) {
- for (final HttpRequestInterceptor i: requestLast) {
- b.addLast(i);
+ if (requestInterceptors != null) {
+ for (final RequestInterceptorEntry entry: requestInterceptors) {
+ if (entry.postion == RequestInterceptorEntry.Postion.LAST) {
+ b.addFirst(entry.interceptor);
+ }
}
}
- if (responseLast != null) {
- for (final HttpResponseInterceptor i: responseLast) {
- b.addLast(i);
+ if (responseInterceptors != null) {
+ for (final ResponseInterceptorEntry entry: responseInterceptors) {
+ if (entry.postion == ResponseInterceptorEntry.Postion.LAST) {
+ b.addFirst(entry.interceptor);
+ }
}
}
- execChain = new ProtocolExec(execChain, b.build());
-
- execChain = decorateProtocolExec(execChain);
+ execChainDefinition.addFirst(
+ new ProtocolExec(b.build()),
+ ChainElements.PROTOCOL.name());
// Add request retry executor, if not disabled
if (!automaticRetriesDisabled) {
@@ -788,7 +844,9 @@ public class HttpClientBuilder {
if (retryHandlerCopy == null) {
retryHandlerCopy = DefaultHttpRequestRetryHandler.INSTANCE;
}
- execChain = new RetryExec(execChain, retryHandlerCopy);
+ execChainDefinition.addFirst(
+ new RetryExec(retryHandlerCopy),
+ ChainElements.RETRY_IO_ERROR.name());
}
HttpRoutePlanner routePlannerCopy = this.routePlanner;
@@ -810,7 +868,9 @@ public class HttpClientBuilder {
// Optionally, add service unavailable retry executor
final ServiceUnavailableRetryStrategy serviceUnavailStrategyCopy = this.serviceUnavailStrategy;
if (serviceUnavailStrategyCopy != null) {
- execChain = new ServiceUnavailableRetryExec(execChain, serviceUnavailStrategyCopy);
+ execChainDefinition.addFirst(
+ new ServiceUnavailableRetryExec(serviceUnavailStrategyCopy),
+ ChainElements.RETRY_SERVICE_UNAVAILABLE.name());
}
// Add redirect executor, if not disabled
@@ -819,12 +879,40 @@ public class HttpClientBuilder {
if (redirectStrategyCopy == null) {
redirectStrategyCopy = DefaultRedirectStrategy.INSTANCE;
}
- execChain = new RedirectExec(execChain, routePlannerCopy, redirectStrategyCopy);
+ execChainDefinition.addFirst(
+ new RedirectExec(routePlannerCopy, redirectStrategyCopy),
+ ChainElements.REDIRECT.name());
}
// Optionally, add connection back-off executor
if (this.backoffManager != null && this.connectionBackoffStrategy != null) {
- execChain = new BackoffStrategyExec(execChain, this.connectionBackoffStrategy, this.backoffManager);
+ execChainDefinition.addFirst(new BackoffStrategyExec(this.connectionBackoffStrategy, this.backoffManager),
+ ChainElements.BACK_OFF.name());
+ }
+
+ if (execInterceptors != null) {
+ for (final ExecInterceptorEntry entry: execInterceptors) {
+ switch (entry.postion) {
+ case AFTER:
+ execChainDefinition.addAfter(entry.existing, entry.interceptor, entry.name);
+ break;
+ case BEFORE:
+ execChainDefinition.addBefore(entry.existing, entry.interceptor, entry.name);
+ break;
+ case REPLACE:
+ execChainDefinition.replace(entry.existing, entry.interceptor);
+ break;
+ }
+ }
+ }
+
+ customizeExecChain(execChainDefinition);
+
+ NamedElementChain<ExecChainHandler>.Node current = execChainDefinition.getLast();
+ ExecChainElement execChain = null;
+ while (current != null) {
+ execChain = new ExecChainElement(current.getValue(), execChain);
+ current = current.getPrevious();
}
Lookup<AuthSchemeProvider> authSchemeRegistryCopy = this.authSchemeRegistry;
@@ -886,6 +974,8 @@ public class HttpClientBuilder {
}
return new InternalHttpClient(
+ connManagerCopy,
+ requestExecCopy,
execChain,
routePlannerCopy,
cookieSpecRegistryCopy,
Modified: httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/HttpClients.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/HttpClients.java?rev=1793308&r1=1793307&r2=1793308&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/HttpClients.java (original)
+++ httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/HttpClients.java Mon May 1 11:11:09 2017
@@ -68,7 +68,7 @@ public class HttpClients {
* Creates {@link CloseableHttpClient} instance that implements
* the most basic HTTP protocol support.
*/
- public static CloseableHttpClient createMinimal() {
+ public static MinimalHttpClient createMinimal() {
return new MinimalHttpClient(new PoolingHttpClientConnectionManager());
}
@@ -76,7 +76,7 @@ public class HttpClients {
* Creates {@link CloseableHttpClient} instance that implements
* the most basic HTTP protocol support.
*/
- public static CloseableHttpClient createMinimal(final HttpClientConnectionManager connManager) {
+ public static MinimalHttpClient createMinimal(final HttpClientConnectionManager connManager) {
return new MinimalHttpClient(connManager);
}
Modified: httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/HttpRequestFutureTask.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/HttpRequestFutureTask.java?rev=1793308&r1=1793307&r2=1793308&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/HttpRequestFutureTask.java (original)
+++ httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/HttpRequestFutureTask.java Mon May 1 11:11:09 2017
@@ -28,7 +28,8 @@ package org.apache.hc.client5.http.impl.
import java.util.concurrent.FutureTask;
-import org.apache.hc.client5.http.sync.methods.HttpUriRequest;
+import org.apache.hc.core5.concurrent.Cancellable;
+import org.apache.hc.core5.http.ClassicHttpRequest;
/**
* FutureTask implementation that wraps a HttpAsyncClientCallable and exposes various task
@@ -38,11 +39,11 @@ import org.apache.hc.client5.http.sync.m
*/
public class HttpRequestFutureTask<V> extends FutureTask<V> {
- private final HttpUriRequest request;
+ private final ClassicHttpRequest request;
private final HttpRequestTaskCallable<V> callable;
public HttpRequestFutureTask(
- final HttpUriRequest request,
+ final ClassicHttpRequest request,
final HttpRequestTaskCallable<V> httpCallable) {
super(httpCallable);
this.request = request;
@@ -56,8 +57,8 @@ public class HttpRequestFutureTask<V> ex
@Override
public boolean cancel(final boolean mayInterruptIfRunning) {
callable.cancel();
- if (mayInterruptIfRunning) {
- request.abort();
+ if (mayInterruptIfRunning && request instanceof Cancellable) {
+ ((Cancellable) request).cancel();
}
return super.cancel(mayInterruptIfRunning);
}
Modified: httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/HttpRequestTaskCallable.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/HttpRequestTaskCallable.java?rev=1793308&r1=1793307&r2=1793308&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/HttpRequestTaskCallable.java (original)
+++ httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/HttpRequestTaskCallable.java Mon May 1 11:11:09 2017
@@ -30,14 +30,14 @@ import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.hc.client5.http.sync.HttpClient;
-import org.apache.hc.client5.http.sync.methods.HttpUriRequest;
import org.apache.hc.core5.concurrent.FutureCallback;
+import org.apache.hc.core5.http.ClassicHttpRequest;
import org.apache.hc.core5.http.io.ResponseHandler;
import org.apache.hc.core5.http.protocol.HttpContext;
class HttpRequestTaskCallable<V> implements Callable<V> {
- private final HttpUriRequest request;
+ private final ClassicHttpRequest request;
private final HttpClient httpclient;
private final AtomicBoolean cancelled = new AtomicBoolean(false);
@@ -53,7 +53,7 @@ class HttpRequestTaskCallable<V> impleme
HttpRequestTaskCallable(
final HttpClient httpClient,
- final HttpUriRequest request,
+ final ClassicHttpRequest request,
final HttpContext context,
final ResponseHandler<V> responseHandler,
final FutureCallback<V> callback,
Modified: httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/InternalHttpClient.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/InternalHttpClient.java?rev=1793308&r1=1793307&r2=1793308&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/InternalHttpClient.java (original)
+++ httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/InternalHttpClient.java Mon May 1 11:11:09 2017
@@ -31,6 +31,7 @@ import java.io.Closeable;
import java.io.IOException;
import java.util.List;
+import org.apache.hc.client5.http.CancellableAware;
import org.apache.hc.client5.http.HttpRoute;
import org.apache.hc.client5.http.auth.AuthSchemeProvider;
import org.apache.hc.client5.http.auth.CredentialsProvider;
@@ -38,10 +39,13 @@ import org.apache.hc.client5.http.config
import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.cookie.CookieSpecProvider;
import org.apache.hc.client5.http.cookie.CookieStore;
+import org.apache.hc.client5.http.impl.ExecSupport;
+import org.apache.hc.client5.http.io.HttpClientConnectionManager;
import org.apache.hc.client5.http.protocol.ClientProtocolException;
import org.apache.hc.client5.http.protocol.HttpClientContext;
import org.apache.hc.client5.http.routing.HttpRoutePlanner;
-import org.apache.hc.client5.http.sync.methods.HttpExecutionAware;
+import org.apache.hc.client5.http.sync.ExecChain;
+import org.apache.hc.client5.http.sync.ExecRuntime;
import org.apache.hc.core5.annotation.Contract;
import org.apache.hc.core5.annotation.ThreadingBehavior;
import org.apache.hc.core5.http.ClassicHttpRequest;
@@ -50,6 +54,7 @@ import org.apache.hc.core5.http.HttpExce
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.HttpRequest;
import org.apache.hc.core5.http.config.Lookup;
+import org.apache.hc.core5.http.impl.io.HttpRequestExecutor;
import org.apache.hc.core5.http.protocol.BasicHttpContext;
import org.apache.hc.core5.http.protocol.HttpContext;
import org.apache.hc.core5.net.URIAuthority;
@@ -67,7 +72,9 @@ class InternalHttpClient extends Closeab
private final Logger log = LogManager.getLogger(getClass());
- private final ClientExecChain execChain;
+ private final HttpClientConnectionManager connManager;
+ private final HttpRequestExecutor requestExecutor;
+ private final ExecChainElement execChain;
private final HttpRoutePlanner routePlanner;
private final Lookup<CookieSpecProvider> cookieSpecRegistry;
private final Lookup<AuthSchemeProvider> authSchemeRegistry;
@@ -77,7 +84,9 @@ class InternalHttpClient extends Closeab
private final List<Closeable> closeables;
public InternalHttpClient(
- final ClientExecChain execChain,
+ final HttpClientConnectionManager connManager,
+ final HttpRequestExecutor requestExecutor,
+ final ExecChainElement execChain,
final HttpRoutePlanner routePlanner,
final Lookup<CookieSpecProvider> cookieSpecRegistry,
final Lookup<AuthSchemeProvider> authSchemeRegistry,
@@ -86,10 +95,10 @@ class InternalHttpClient extends Closeab
final RequestConfig defaultConfig,
final List<Closeable> closeables) {
super();
- Args.notNull(execChain, "HTTP client exec chain");
- Args.notNull(routePlanner, "HTTP route planner");
- this.execChain = execChain;
- this.routePlanner = routePlanner;
+ this.connManager = Args.notNull(connManager, "Connection manager");
+ this.requestExecutor = Args.notNull(requestExecutor, "Request executor");
+ this.execChain = Args.notNull(execChain, "Execution chain");
+ this.routePlanner = Args.notNull(routePlanner, "Route planner");
this.cookieSpecRegistry = cookieSpecRegistry;
this.authSchemeRegistry = authSchemeRegistry;
this.cookieStore = cookieStore;
@@ -130,10 +139,6 @@ class InternalHttpClient extends Closeab
final ClassicHttpRequest request,
final HttpContext context) throws IOException {
Args.notNull(request, "HTTP request");
- HttpExecutionAware execAware = null;
- if (request instanceof HttpExecutionAware) {
- execAware = (HttpExecutionAware) request;
- }
try {
if (request.getScheme() == null && target != null) {
request.setScheme(target.getSchemeName());
@@ -152,8 +157,10 @@ class InternalHttpClient extends Closeab
}
setupContext(localcontext);
final HttpRoute route = determineRoute(target, request, localcontext);
- final ClassicHttpResponse response = this.execChain.execute(
- RoutedHttpRequest.adapt(request, route), localcontext, execAware);
+ final ExecRuntime execRuntime = new ExecRuntimeImpl(log, connManager, requestExecutor,
+ request instanceof CancellableAware ? (CancellableAware) request : null);
+ final ExecChain.Scope scope = new ExecChain.Scope(route, request, execRuntime, localcontext);
+ final ClassicHttpResponse response = this.execChain.execute(ExecSupport.copy(request), scope);
return CloseableHttpResponse.adapt(response);
} catch (final HttpException httpException) {
throw new ClientProtocolException(httpException.getMessage(), httpException);
Modified: httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/MainClientExec.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/MainClientExec.java?rev=1793308&r1=1793307&r2=1793308&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/MainClientExec.java (original)
+++ httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/MainClientExec.java Mon May 1 11:11:09 2017
@@ -29,8 +29,6 @@ package org.apache.hc.client5.http.impl.
import java.io.IOException;
import java.io.InterruptedIOException;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeoutException;
import org.apache.hc.client5.http.ConnectionKeepAliveStrategy;
import org.apache.hc.client5.http.HttpRoute;
@@ -41,20 +39,18 @@ import org.apache.hc.client5.http.config
import org.apache.hc.client5.http.impl.ConnectionShutdownException;
import org.apache.hc.client5.http.impl.auth.HttpAuthenticator;
import org.apache.hc.client5.http.impl.routing.BasicRouteDirector;
-import org.apache.hc.client5.http.io.ConnectionEndpoint;
-import org.apache.hc.client5.http.io.HttpClientConnectionManager;
-import org.apache.hc.client5.http.io.LeaseRequest;
import org.apache.hc.client5.http.protocol.AuthenticationStrategy;
import org.apache.hc.client5.http.protocol.HttpClientContext;
import org.apache.hc.client5.http.protocol.NonRepeatableRequestException;
import org.apache.hc.client5.http.protocol.UserTokenHandler;
import org.apache.hc.client5.http.routing.HttpRouteDirector;
-import org.apache.hc.client5.http.sync.methods.HttpExecutionAware;
+import org.apache.hc.client5.http.sync.ExecChain;
+import org.apache.hc.client5.http.sync.ExecChainHandler;
+import org.apache.hc.client5.http.sync.ExecRuntime;
import org.apache.hc.core5.annotation.Contract;
import org.apache.hc.core5.annotation.ThreadingBehavior;
import org.apache.hc.core5.http.ClassicHttpRequest;
import org.apache.hc.core5.http.ClassicHttpResponse;
-import org.apache.hc.core5.http.ConnectionRequestTimeoutException;
import org.apache.hc.core5.http.ConnectionReuseStrategy;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.HttpException;
@@ -64,7 +60,6 @@ import org.apache.hc.core5.http.HttpRequ
import org.apache.hc.core5.http.HttpResponse;
import org.apache.hc.core5.http.HttpStatus;
import org.apache.hc.core5.http.HttpVersion;
-import org.apache.hc.core5.http.impl.io.HttpRequestExecutor;
import org.apache.hc.core5.http.io.entity.BufferedHttpEntity;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.message.BasicClassicHttpRequest;
@@ -73,6 +68,7 @@ import org.apache.hc.core5.http.message.
import org.apache.hc.core5.http.protocol.DefaultHttpProcessor;
import org.apache.hc.core5.http.protocol.HttpProcessor;
import org.apache.hc.core5.http.protocol.RequestTargetHost;
+import org.apache.hc.core5.net.URIAuthority;
import org.apache.hc.core5.util.Args;
import org.apache.hc.core5.util.TimeValue;
import org.apache.logging.log4j.LogManager;
@@ -89,12 +85,10 @@ import org.apache.logging.log4j.Logger;
* @since 4.3
*/
@Contract(threading = ThreadingBehavior.IMMUTABLE_CONDITIONAL)
-public class MainClientExec implements ClientExecChain {
+final class MainClientExec implements ExecChainHandler {
private final Logger log = LogManager.getLogger(getClass());
- private final HttpRequestExecutor requestExecutor;
- private final HttpClientConnectionManager connManager;
private final ConnectionReuseStrategy reuseStrategy;
private final ConnectionKeepAliveStrategy keepAliveStrategy;
private final HttpProcessor proxyHttpProcessor;
@@ -108,16 +102,12 @@ public class MainClientExec implements C
* @since 4.4
*/
public MainClientExec(
- final HttpRequestExecutor requestExecutor,
- final HttpClientConnectionManager connManager,
final ConnectionReuseStrategy reuseStrategy,
final ConnectionKeepAliveStrategy keepAliveStrategy,
final HttpProcessor proxyHttpProcessor,
final AuthenticationStrategy targetAuthStrategy,
final AuthenticationStrategy proxyAuthStrategy,
final UserTokenHandler userTokenHandler) {
- Args.notNull(requestExecutor, "HTTP request executor");
- Args.notNull(connManager, "Client connection manager");
Args.notNull(reuseStrategy, "Connection reuse strategy");
Args.notNull(keepAliveStrategy, "Connection keep alive strategy");
Args.notNull(proxyHttpProcessor, "Proxy HTTP processor");
@@ -126,8 +116,6 @@ public class MainClientExec implements C
Args.notNull(userTokenHandler, "User token handler");
this.authenticator = new HttpAuthenticator();
this.routeDirector = new BasicRouteDirector();
- this.requestExecutor = requestExecutor;
- this.connManager = connManager;
this.reuseStrategy = reuseStrategy;
this.keepAliveStrategy = keepAliveStrategy;
this.proxyHttpProcessor = proxyHttpProcessor;
@@ -137,66 +125,34 @@ public class MainClientExec implements C
}
public MainClientExec(
- final HttpRequestExecutor requestExecutor,
- final HttpClientConnectionManager connManager,
final ConnectionReuseStrategy reuseStrategy,
final ConnectionKeepAliveStrategy keepAliveStrategy,
final AuthenticationStrategy targetAuthStrategy,
final AuthenticationStrategy proxyAuthStrategy,
final UserTokenHandler userTokenHandler) {
- this(requestExecutor, connManager, reuseStrategy, keepAliveStrategy,
+ this(reuseStrategy, keepAliveStrategy,
new DefaultHttpProcessor(new RequestTargetHost()),
targetAuthStrategy, proxyAuthStrategy, userTokenHandler);
}
@Override
public ClassicHttpResponse execute(
- final RoutedHttpRequest request,
- final HttpClientContext context,
- final HttpExecutionAware execAware) throws IOException, HttpException {
+ final ClassicHttpRequest request,
+ final ExecChain.Scope scope,
+ final ExecChain chain) throws IOException, HttpException {
Args.notNull(request, "HTTP request");
- Args.notNull(context, "HTTP context");
- final HttpRoute route = request.getRoute();
+ Args.notNull(scope, "Scope");
+ final HttpRoute route = scope.route;
+ final HttpClientContext context = scope.clientContext;
+ final ExecRuntime execRuntime = scope.execRuntime;
RequestEntityProxy.enhance(request);
Object userToken = context.getUserToken();
-
- final LeaseRequest leaseRequest = connManager.lease(route, userToken);
- if (execAware != null) {
- if (execAware.isAborted()) {
- leaseRequest.cancel();
- throw new RequestAbortedException("Request aborted");
- } else {
- execAware.setCancellable(leaseRequest);
- }
- }
-
- final RequestConfig config = context.getRequestConfig();
-
- final ConnectionEndpoint endpoint;
- try {
- final TimeValue timeout = config.getConnectionRequestTimeout();
- endpoint = leaseRequest.get(timeout.getDuration(), timeout.getTimeUnit());
- } catch(final TimeoutException ex) {
- throw new ConnectionRequestTimeoutException(ex.getMessage());
- } catch(final InterruptedException interrupted) {
- Thread.currentThread().interrupt();
- throw new RequestAbortedException("Request aborted", interrupted);
- } catch(final ExecutionException ex) {
- Throwable cause = ex.getCause();
- if (cause == null) {
- cause = ex;
- }
- throw new RequestAbortedException("Request execution failed", cause);
+ if (!execRuntime.isConnectionAcquired()) {
+ execRuntime.acquireConnection(route, userToken, context);
}
-
- final EndpointHolder endpointHolder = new EndpointHolder(this.log, this.connManager, endpoint);
try {
- if (execAware != null) {
- execAware.setCancellable(endpointHolder);
- }
-
final AuthExchange targetAuthExchange = context.getAuthExchange(route.getTargetHost());
final AuthExchange proxyAuthExchange = route.getProxyHost() != null ?
context.getAuthExchange(route.getProxyHost()) : new AuthExchange();
@@ -209,16 +165,10 @@ public class MainClientExec implements C
"with a non-repeatable request entity.");
}
- if (execAware != null && execAware.isAborted()) {
- throw new RequestAbortedException("Request aborted");
- }
-
- if (!endpoint.isConnected()) {
- endpointHolder.markNonReusable();
+ if (!execRuntime.isConnected()) {
this.log.debug("Opening connection " + route);
try {
- establishRoute(endpoint, route, request, context);
- endpointHolder.markReusable();
+ establishRoute(route, request, execRuntime, context);
} catch (final TunnelRefusedException ex) {
if (this.log.isDebugEnabled()) {
this.log.debug(ex.getMessage());
@@ -227,15 +177,6 @@ public class MainClientExec implements C
break;
}
}
- final TimeValue timeout = config.getSocketTimeout();
- if (TimeValue.isPositive(timeout)) {
- endpoint.setSocketTimeout(timeout.toMillisIntBound());
- }
-
- if (execAware != null && execAware.isAborted()) {
- throw new RequestAbortedException("Request aborted");
- }
-
if (this.log.isDebugEnabled()) {
this.log.debug("Executing request " + new RequestLine(request));
}
@@ -255,7 +196,7 @@ public class MainClientExec implements C
route.getProxyHost(), ChallengeType.PROXY, request, proxyAuthExchange, context);
}
- response = endpoint.execute(request, requestExecutor, context);
+ response = execRuntime.execute(request, context);
// The connection is in or can be brought to a re-usable state.
if (reuseStrategy.keepAlive(request, response, context)) {
@@ -270,10 +211,10 @@ public class MainClientExec implements C
}
this.log.debug("Connection can be kept alive " + s);
}
- endpointHolder.setValidFor(duration);
- endpointHolder.markReusable();
+ execRuntime.setConnectionValidFor(duration);
+ execRuntime.markConnectionReusable();
} else {
- endpointHolder.markNonReusable();
+ execRuntime.markConnectionNonReusable();
}
if (request.getMethod().equalsIgnoreCase("TRACE")) {
@@ -285,10 +226,10 @@ public class MainClientExec implements C
targetAuthExchange, proxyAuthExchange, route, request, response, context)) {
// Make sure the response body is fully consumed, if present
final HttpEntity entity = response.getEntity();
- if (endpointHolder.isReusable()) {
+ if (execRuntime.isConnectionReusable()) {
EntityUtils.consume(entity);
} else {
- endpoint.close();
+ execRuntime.disconnect();
if (proxyAuthExchange.getState() == AuthExchange.State.SUCCESS
&& proxyAuthExchange.getAuthScheme() != null
&& proxyAuthExchange.getAuthScheme().isConnectionBased()) {
@@ -303,7 +244,7 @@ public class MainClientExec implements C
}
}
// discard previous auth headers
- final HttpRequest original = request.getOriginal();
+ final HttpRequest original = scope.originalRequest;
if (!original.containsHeader(HttpHeaders.AUTHORIZATION)) {
request.removeHeaders(HttpHeaders.AUTHORIZATION);
}
@@ -320,26 +261,27 @@ public class MainClientExec implements C
context.setAttribute(HttpClientContext.USER_TOKEN, userToken);
}
if (userToken != null) {
- endpointHolder.setState(userToken);
+ execRuntime.setConnectionState(userToken);
}
// check for entity, release connection if possible
final HttpEntity entity = response.getEntity();
if (entity == null || !entity.isStreaming()) {
// connection not needed and (assumed to be) in re-usable state
- endpointHolder.releaseConnection();
+ execRuntime.releaseConnection();
return new CloseableHttpResponse(response, null);
} else {
- ResponseEntityProxy.enchance(response, endpointHolder);
- return new CloseableHttpResponse(response, endpointHolder);
+ ResponseEntityProxy.enchance(response, execRuntime);
+ return new CloseableHttpResponse(response, execRuntime);
}
} catch (final ConnectionShutdownException ex) {
final InterruptedIOException ioex = new InterruptedIOException(
"Connection has been shut down");
ioex.initCause(ex);
+ execRuntime.discardConnection();
throw ioex;
} catch (final HttpException | RuntimeException | IOException ex) {
- endpointHolder.abortConnection();
+ execRuntime.discardConnection();
throw ex;
}
}
@@ -348,12 +290,10 @@ public class MainClientExec implements C
* Establishes the target route.
*/
void establishRoute(
- final ConnectionEndpoint endpoint,
final HttpRoute route,
final HttpRequest request,
+ final ExecRuntime execRuntime,
final HttpClientContext context) throws HttpException, IOException {
- final RequestConfig config = context.getRequestConfig();
- final TimeValue timeout = config.getConnectTimeout();
final RouteTracker tracker = new RouteTracker(route);
int step;
do {
@@ -363,16 +303,16 @@ public class MainClientExec implements C
switch (step) {
case HttpRouteDirector.CONNECT_TARGET:
- this.connManager.connect(endpoint, timeout, context);
+ execRuntime.connect(context);
tracker.connectTarget(route.isSecure());
break;
case HttpRouteDirector.CONNECT_PROXY:
- this.connManager.connect(endpoint, timeout, context);
+ execRuntime.connect(context);
final HttpHost proxy = route.getProxyHost();
tracker.connectProxy(proxy, false);
break;
case HttpRouteDirector.TUNNEL_TARGET: {
- final boolean secure = createTunnelToTarget(endpoint, route, request, context);
+ final boolean secure = createTunnelToTarget(route, request, execRuntime, context);
this.log.debug("Tunnel to target created.");
tracker.tunnelTarget(secure);
} break;
@@ -389,7 +329,7 @@ public class MainClientExec implements C
} break;
case HttpRouteDirector.LAYER_PROTOCOL:
- this.connManager.upgrade(endpoint, context);
+ execRuntime.upgradeTls(context);
tracker.layerProtocol(route.isSecure());
break;
@@ -415,9 +355,9 @@ public class MainClientExec implements C
* information about the tunnel, that is left to the caller.
*/
private boolean createTunnelToTarget(
- final ConnectionEndpoint endpoint,
final HttpRoute route,
final HttpRequest request,
+ final ExecRuntime execRuntime,
final HttpClientContext context) throws HttpException, IOException {
final RequestConfig config = context.getRequestConfig();
@@ -431,17 +371,17 @@ public class MainClientExec implements C
final ClassicHttpRequest connect = new BasicClassicHttpRequest("CONNECT", target, authority);
connect.setVersion(HttpVersion.HTTP_1_1);
- this.requestExecutor.preProcess(connect, this.proxyHttpProcessor, context);
+ this.proxyHttpProcessor.process(connect, null, context);
while (response == null) {
- if (!endpoint.isConnected()) {
- this.connManager.connect(endpoint, config.getConnectTimeout(), context);
+ if (!execRuntime.isConnected()) {
+ execRuntime.connect(context);
}
connect.removeHeaders(HttpHeaders.PROXY_AUTHORIZATION);
this.authenticator.addAuthResponse(proxy, ChallengeType.PROXY, connect, proxyAuthExchange, context);
- response = endpoint.execute(connect, this.requestExecutor, context);
+ response = execRuntime.execute(connect, context);
final int status = response.getCode();
if (status < HttpStatus.SC_SUCCESS) {
@@ -460,7 +400,7 @@ public class MainClientExec implements C
final HttpEntity entity = response.getEntity();
EntityUtils.consume(entity);
} else {
- endpoint.close();
+ execRuntime.disconnect();
}
response = null;
}
@@ -477,7 +417,8 @@ public class MainClientExec implements C
response.setEntity(new BufferedHttpEntity(entity));
}
- endpoint.close();
+ execRuntime.disconnect();
+ execRuntime.discardConnection();
throw new TunnelRefusedException("CONNECT refused by proxy: " +
new StatusLine(response), response);
}
@@ -515,12 +456,14 @@ public class MainClientExec implements C
final AuthExchange targetAuthExchange,
final AuthExchange proxyAuthExchange,
final HttpRoute route,
- final RoutedHttpRequest request,
+ final ClassicHttpRequest request,
final HttpResponse response,
final HttpClientContext context) {
final RequestConfig config = context.getRequestConfig();
if (config.isAuthenticationEnabled()) {
- HttpHost target = request.getTargetHost();
+ final URIAuthority authority = request.getAuthority();
+ final String scheme = request.getScheme();
+ HttpHost target = authority != null ? new HttpHost(authority, scheme) : route.getTargetHost();;
if (target.getPort() < 0) {
target = new HttpHost(
target.getHostName(),
Modified: httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/MinimalClientExec.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/MinimalClientExec.java?rev=1793308&r1=1793307&r2=1793308&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/MinimalClientExec.java (original)
+++ httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/MinimalClientExec.java Mon May 1 11:11:09 2017
@@ -29,29 +29,24 @@ package org.apache.hc.client5.http.impl.
import java.io.IOException;
import java.io.InterruptedIOException;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeoutException;
import org.apache.hc.client5.http.ConnectionKeepAliveStrategy;
import org.apache.hc.client5.http.HttpRoute;
-import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.impl.ConnectionShutdownException;
import org.apache.hc.client5.http.impl.DefaultConnectionKeepAliveStrategy;
-import org.apache.hc.client5.http.io.ConnectionEndpoint;
-import org.apache.hc.client5.http.io.HttpClientConnectionManager;
-import org.apache.hc.client5.http.io.LeaseRequest;
import org.apache.hc.client5.http.protocol.HttpClientContext;
import org.apache.hc.client5.http.protocol.RequestClientConnControl;
-import org.apache.hc.client5.http.sync.methods.HttpExecutionAware;
+import org.apache.hc.client5.http.sync.ExecChain;
+import org.apache.hc.client5.http.sync.ExecChainHandler;
+import org.apache.hc.client5.http.sync.ExecRuntime;
import org.apache.hc.core5.annotation.Contract;
import org.apache.hc.core5.annotation.ThreadingBehavior;
+import org.apache.hc.core5.http.ClassicHttpRequest;
import org.apache.hc.core5.http.ClassicHttpResponse;
-import org.apache.hc.core5.http.ConnectionRequestTimeoutException;
import org.apache.hc.core5.http.ConnectionReuseStrategy;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.HttpException;
import org.apache.hc.core5.http.impl.DefaultConnectionReuseStrategy;
-import org.apache.hc.core5.http.impl.io.HttpRequestExecutor;
import org.apache.hc.core5.http.protocol.DefaultHttpProcessor;
import org.apache.hc.core5.http.protocol.HttpCoreContext;
import org.apache.hc.core5.http.protocol.HttpProcessor;
@@ -74,23 +69,17 @@ import org.apache.logging.log4j.Logger;
* @since 4.3
*/
@Contract(threading = ThreadingBehavior.IMMUTABLE)
-public class MinimalClientExec implements ClientExecChain {
+final class MinimalClientExec implements ExecChainHandler {
private final Logger log = LogManager.getLogger(getClass());
- private final HttpRequestExecutor requestExecutor;
- private final HttpClientConnectionManager connManager;
private final ConnectionReuseStrategy reuseStrategy;
private final ConnectionKeepAliveStrategy keepAliveStrategy;
private final HttpProcessor httpProcessor;
public MinimalClientExec(
- final HttpRequestExecutor requestExecutor,
- final HttpClientConnectionManager connManager,
final ConnectionReuseStrategy reuseStrategy,
final ConnectionKeepAliveStrategy keepAliveStrategy) {
- this.requestExecutor = Args.notNull(requestExecutor, "Request executor");
- this.connManager = Args.notNull(connManager, "Connection manager");
this.reuseStrategy = reuseStrategy != null ? reuseStrategy : DefaultConnectionReuseStrategy.INSTANCE;
this.keepAliveStrategy = keepAliveStrategy != null ? keepAliveStrategy : DefaultConnectionKeepAliveStrategy.INSTANCE;
this.httpProcessor = new DefaultHttpProcessor(
@@ -103,92 +92,56 @@ public class MinimalClientExec implement
@Override
public ClassicHttpResponse execute(
- final RoutedHttpRequest request,
- final HttpClientContext context,
- final HttpExecutionAware execAware) throws IOException, HttpException {
+ final ClassicHttpRequest request,
+ final ExecChain.Scope scope,
+ final ExecChain chain) throws IOException, HttpException {
Args.notNull(request, "HTTP request");
- Args.notNull(context, "HTTP context");
-
- final HttpRoute route = request.getRoute();
- final LeaseRequest connRequest = connManager.lease(route, null);
- if (execAware != null) {
- if (execAware.isAborted()) {
- connRequest.cancel();
- throw new RequestAbortedException("Request aborted");
- }
- execAware.setCancellable(connRequest);
- }
-
- final RequestConfig config = context.getRequestConfig();
-
- final ConnectionEndpoint endpoint;
- try {
- final TimeValue timeout = config.getConnectionRequestTimeout();
- endpoint = connRequest.get(timeout.getDuration(), timeout.getTimeUnit());
- } catch(final TimeoutException ex) {
- throw new ConnectionRequestTimeoutException(ex.getMessage());
- } catch(final InterruptedException interrupted) {
- Thread.currentThread().interrupt();
- throw new RequestAbortedException("Request aborted", interrupted);
- } catch(final ExecutionException ex) {
- Throwable cause = ex.getCause();
- if (cause == null) {
- cause = ex;
- }
- throw new RequestAbortedException("Request execution failed", cause);
+ Args.notNull(scope, "Scope");
+ final HttpRoute route = scope.route;
+ final HttpClientContext context = scope.clientContext;
+ final ExecRuntime execRuntime = scope.execRuntime;
+ if (!execRuntime.isConnectionAcquired()) {
+ execRuntime.acquireConnection(route, null, context);
}
-
- final EndpointHolder endpointHolder = new EndpointHolder(log, connManager, endpoint);
try {
- if (execAware != null) {
- if (execAware.isAborted()) {
- endpointHolder.close();
- throw new RequestAbortedException("Request aborted");
- }
- execAware.setCancellable(endpointHolder);
- }
- if (!endpoint.isConnected()) {
- this.connManager.connect(endpoint, config.getConnectTimeout(), context);
- }
- final TimeValue timeout = config.getSocketTimeout();
- if (TimeValue.isNonNegative(timeout)) {
- endpoint.setSocketTimeout(timeout.toMillisIntBound());
+ if (!execRuntime.isConnected()) {
+ execRuntime.connect(context);
}
context.setAttribute(HttpCoreContext.HTTP_REQUEST, request);
context.setAttribute(HttpClientContext.HTTP_ROUTE, route);
httpProcessor.process(request, request.getEntity(), context);
- final ClassicHttpResponse response = endpoint.execute(request, requestExecutor, context);
+ final ClassicHttpResponse response = execRuntime.execute(request, context);
httpProcessor.process(response, response.getEntity(), context);
// The connection is in or can be brought to a re-usable state.
if (reuseStrategy.keepAlive(request, response, context)) {
// Set the idle duration of this connection
final TimeValue duration = keepAliveStrategy.getKeepAliveDuration(response, context);
- endpointHolder.setValidFor(duration);
- endpointHolder.markReusable();
+ execRuntime.setConnectionValidFor(duration);
+ execRuntime.markConnectionReusable();
} else {
- endpointHolder.markNonReusable();
+ execRuntime.markConnectionNonReusable();
}
// check for entity, release connection if possible
final HttpEntity entity = response.getEntity();
if (entity == null || !entity.isStreaming()) {
// connection not needed and (assumed to be) in re-usable state
- endpointHolder.releaseConnection();
+ execRuntime.releaseConnection();
return new CloseableHttpResponse(response, null);
} else {
- ResponseEntityProxy.enchance(response, endpointHolder);
- return new CloseableHttpResponse(response, endpointHolder);
+ ResponseEntityProxy.enchance(response, execRuntime);
+ return new CloseableHttpResponse(response, execRuntime);
}
} catch (final ConnectionShutdownException ex) {
- final InterruptedIOException ioex = new InterruptedIOException(
- "Connection has been shut down");
+ final InterruptedIOException ioex = new InterruptedIOException("Connection has been shut down");
ioex.initCause(ex);
+ execRuntime.discardConnection();
throw ioex;
} catch (final HttpException | RuntimeException | IOException ex) {
- endpointHolder.abortConnection();
+ execRuntime.discardConnection();
throw ex;
}
}
Modified: httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/MinimalHttpClient.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/MinimalHttpClient.java?rev=1793308&r1=1793307&r2=1793308&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/MinimalHttpClient.java (original)
+++ httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/MinimalHttpClient.java Mon May 1 11:11:09 2017
@@ -29,14 +29,17 @@ package org.apache.hc.client5.http.impl.
import java.io.IOException;
+import org.apache.hc.client5.http.CancellableAware;
import org.apache.hc.client5.http.HttpRoute;
import org.apache.hc.client5.http.config.Configurable;
import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.impl.DefaultConnectionKeepAliveStrategy;
+import org.apache.hc.client5.http.impl.ExecSupport;
import org.apache.hc.client5.http.io.HttpClientConnectionManager;
import org.apache.hc.client5.http.protocol.ClientProtocolException;
import org.apache.hc.client5.http.protocol.HttpClientContext;
-import org.apache.hc.client5.http.sync.methods.HttpExecutionAware;
+import org.apache.hc.client5.http.sync.ExecChain;
+import org.apache.hc.client5.http.sync.ExecRuntime;
import org.apache.hc.core5.annotation.Contract;
import org.apache.hc.core5.annotation.ThreadingBehavior;
import org.apache.hc.core5.http.ClassicHttpRequest;
@@ -49,6 +52,8 @@ import org.apache.hc.core5.http.protocol
import org.apache.hc.core5.http.protocol.HttpContext;
import org.apache.hc.core5.net.URIAuthority;
import org.apache.hc.core5.util.Args;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
/**
* Internal class.
@@ -56,20 +61,21 @@ import org.apache.hc.core5.util.Args;
* @since 4.3
*/
@Contract(threading = ThreadingBehavior.SAFE)
-class MinimalHttpClient extends CloseableHttpClient {
+public class MinimalHttpClient extends CloseableHttpClient {
+
+ private final Logger log = LogManager.getLogger(getClass());
private final HttpClientConnectionManager connManager;
- private final MinimalClientExec requestExecutor;
+ private final MinimalClientExec execChain;
+ private final HttpRequestExecutor requestExecutor;
- public MinimalHttpClient(
- final HttpClientConnectionManager connManager) {
+ MinimalHttpClient(final HttpClientConnectionManager connManager) {
super();
this.connManager = Args.notNull(connManager, "HTTP connection manager");
- this.requestExecutor = new MinimalClientExec(
- new HttpRequestExecutor(),
- connManager,
+ this.execChain = new MinimalClientExec(
DefaultConnectionReuseStrategy.INSTANCE,
DefaultConnectionKeepAliveStrategy.INSTANCE);
+ this.requestExecutor = new HttpRequestExecutor(DefaultConnectionReuseStrategy.INSTANCE);
}
@Override
@@ -79,10 +85,6 @@ class MinimalHttpClient extends Closeabl
final HttpContext context) throws IOException {
Args.notNull(target, "Target host");
Args.notNull(request, "HTTP request");
- HttpExecutionAware execAware = null;
- if (request instanceof HttpExecutionAware) {
- execAware = (HttpExecutionAware) request;
- }
try {
if (request.getScheme() == null) {
request.setScheme(target.getSchemeName());
@@ -99,9 +101,10 @@ class MinimalHttpClient extends Closeabl
if (config != null) {
localcontext.setRequestConfig(config);
}
- final HttpRoute route = new HttpRoute(target);
- final ClassicHttpResponse response = this.requestExecutor.execute(
- RoutedHttpRequest.adapt(request, route), localcontext, execAware);
+ final ExecRuntime execRuntime = new ExecRuntimeImpl(log, connManager, requestExecutor,
+ request instanceof CancellableAware ? (CancellableAware) request : null);
+ final ExecChain.Scope scope = new ExecChain.Scope(new HttpRoute(target), request, execRuntime, localcontext);
+ final ClassicHttpResponse response = this.execChain.execute(ExecSupport.copy(request), scope, null);
return CloseableHttpResponse.adapt(response);
} catch (final HttpException httpException) {
throw new ClientProtocolException(httpException);