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/09/02 15:28:11 UTC
[11/17] httpcomponents-client git commit: Moved classes and renamed
packages (no functional changes)
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/ServiceUnavailableRetryExec.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/ServiceUnavailableRetryExec.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/ServiceUnavailableRetryExec.java
new file mode 100644
index 0000000..970f968
--- /dev/null
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/ServiceUnavailableRetryExec.java
@@ -0,0 +1,115 @@
+/*
+ * ====================================================================
+ * 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.classic;
+
+import java.io.IOException;
+import java.io.InterruptedIOException;
+
+import org.apache.hc.client5.http.ServiceUnavailableRetryStrategy;
+import org.apache.hc.client5.http.classic.ExecChain;
+import org.apache.hc.client5.http.classic.ExecChainHandler;
+import org.apache.hc.client5.http.impl.ExecSupport;
+import org.apache.hc.client5.http.protocol.HttpClientContext;
+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.HttpEntity;
+import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.util.Args;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+/**
+ * Request executor in the request execution chain that is responsible
+ * for making a decision whether a request that received a non-2xx response
+ * from the target server should be re-executed.
+ * <p>
+ * Further responsibilities such as communication with the opposite
+ * endpoint is delegated to the next executor in the request execution
+ * chain.
+ * </p>
+ *
+ * @since 4.3
+ */
+@Contract(threading = ThreadingBehavior.IMMUTABLE_CONDITIONAL)
+final class ServiceUnavailableRetryExec implements ExecChainHandler {
+
+ private final Logger log = LogManager.getLogger(getClass());
+
+ private final ServiceUnavailableRetryStrategy retryStrategy;
+
+ public ServiceUnavailableRetryExec(
+ final ServiceUnavailableRetryStrategy retryStrategy) {
+ super();
+ Args.notNull(retryStrategy, "Retry strategy");
+ this.retryStrategy = retryStrategy;
+ }
+
+ @Override
+ public ClassicHttpResponse execute(
+ final ClassicHttpRequest request,
+ final ExecChain.Scope scope,
+ final ExecChain chain) throws IOException, HttpException {
+ Args.notNull(request, "HTTP request");
+ Args.notNull(scope, "Scope");
+ final HttpClientContext context = scope.clientContext;
+ ClassicHttpRequest currentRequest = request;
+ for (int c = 1;; c++) {
+ final ClassicHttpResponse response = chain.proceed(currentRequest, scope);
+ try {
+ final HttpEntity entity = request.getEntity();
+ if (entity != null && !entity.isRepeatable()) {
+ return response;
+ }
+ if (this.retryStrategy.retryRequest(response, c, context)) {
+ response.close();
+ final long nextInterval = this.retryStrategy.getRetryInterval(response, context);
+ if (nextInterval > 0) {
+ try {
+ if (this.log.isDebugEnabled()) {
+ this.log.debug("Wait for " + ((double) nextInterval / 1000) + " seconds" );
+ }
+ Thread.sleep(nextInterval);
+ } catch (final InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new InterruptedIOException();
+ }
+ }
+ currentRequest = ExecSupport.copy(scope.originalRequest);
+ } else {
+ return response;
+ }
+ } catch (final RuntimeException ex) {
+ response.close();
+ throw ex;
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/SystemClock.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/SystemClock.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/SystemClock.java
new file mode 100644
index 0000000..0ec51d7
--- /dev/null
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/SystemClock.java
@@ -0,0 +1,41 @@
+/*
+ * ====================================================================
+ * 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.classic;
+
+/**
+ * The actual system clock.
+ *
+ * @since 4.2
+ */
+class SystemClock implements Clock {
+
+ @Override
+ public long getCurrentTime() {
+ return System.currentTimeMillis();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/package-info.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/package-info.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/package-info.java
new file mode 100644
index 0000000..20c017d
--- /dev/null
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/package-info.java
@@ -0,0 +1,52 @@
+/*
+ * ====================================================================
+ * 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/>.
+ *
+ */
+
+/**
+ * Default HTTP client implementation.
+ * <p>
+ * The usual execution flow can be demonstrated by the code snippet below:
+ * </p>
+ * <pre>
+ * CloseableHttpClient httpclient = HttpClients.createDefault();
+ * try {
+ * HttpGet httpGet = new HttpGet("http://targethost/homepage");
+ * CloseableHttpResponse response = httpclient.execute(httpGet);
+ * try {
+ * System.out.println(response.getStatusLine());
+ * HttpEntity entity = response.getEntity();
+ * // do something useful with the response body
+ * // and ensure it is fully consumed
+ * EntityUtils.consume(entity);
+ * } finally {
+ * response.close();
+ * }
+ * } finally {
+ * httpclient.close();
+ * }
+ * </pre>
+ */
+package org.apache.hc.client5.http.impl.classic;
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/protocol/DefaultAuthenticationStrategy.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/protocol/DefaultAuthenticationStrategy.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/protocol/DefaultAuthenticationStrategy.java
deleted file mode 100644
index 9193b5a..0000000
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/protocol/DefaultAuthenticationStrategy.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * ====================================================================
- * 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.protocol;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-
-import org.apache.hc.client5.http.auth.AuthChallenge;
-import org.apache.hc.client5.http.auth.AuthScheme;
-import org.apache.hc.client5.http.auth.AuthSchemeProvider;
-import org.apache.hc.client5.http.auth.ChallengeType;
-import org.apache.hc.client5.http.config.AuthSchemes;
-import org.apache.hc.client5.http.config.RequestConfig;
-import org.apache.hc.client5.http.protocol.AuthenticationStrategy;
-import org.apache.hc.client5.http.protocol.HttpClientContext;
-import org.apache.hc.core5.annotation.Contract;
-import org.apache.hc.core5.annotation.ThreadingBehavior;
-import org.apache.hc.core5.http.config.Lookup;
-import org.apache.hc.core5.http.protocol.HttpContext;
-import org.apache.hc.core5.util.Args;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-
-/**
- * Default implementation of {@link AuthenticationStrategy}
- *
- * @since 5.0
- */
-@Contract(threading = ThreadingBehavior.IMMUTABLE)
-public class DefaultAuthenticationStrategy implements AuthenticationStrategy {
-
- private final Logger log = LogManager.getLogger(getClass());
-
- public static final DefaultAuthenticationStrategy INSTANCE = new DefaultAuthenticationStrategy();
-
- private static final List<String> DEFAULT_SCHEME_PRIORITY =
- Collections.unmodifiableList(Arrays.asList(
- AuthSchemes.SPNEGO,
- AuthSchemes.KERBEROS,
- AuthSchemes.NTLM,
- AuthSchemes.CREDSSP,
- AuthSchemes.DIGEST,
- AuthSchemes.BASIC));
-
- @Override
- public List<AuthScheme> select(
- final ChallengeType challengeType,
- final Map<String, AuthChallenge> challenges,
- final HttpContext context) {
- Args.notNull(challengeType, "ChallengeType");
- Args.notNull(challenges, "Map of auth challenges");
- Args.notNull(context, "HTTP context");
- final HttpClientContext clientContext = HttpClientContext.adapt(context);
-
- final List<AuthScheme> options = new ArrayList<>();
- final Lookup<AuthSchemeProvider> registry = clientContext.getAuthSchemeRegistry();
- if (registry == null) {
- this.log.debug("Auth scheme registry not set in the context");
- return options;
- }
- final RequestConfig config = clientContext.getRequestConfig();
- Collection<String> authPrefs = challengeType == ChallengeType.TARGET ?
- config.getTargetPreferredAuthSchemes() : config.getProxyPreferredAuthSchemes();
- if (authPrefs == null) {
- authPrefs = DEFAULT_SCHEME_PRIORITY;
- }
- if (this.log.isDebugEnabled()) {
- this.log.debug("Authentication schemes in the order of preference: " + authPrefs);
- }
-
- for (final String id: authPrefs) {
- final AuthChallenge challenge = challenges.get(id.toLowerCase(Locale.ROOT));
- if (challenge != null) {
- final AuthSchemeProvider authSchemeProvider = registry.lookup(id);
- if (authSchemeProvider == null) {
- if (this.log.isWarnEnabled()) {
- this.log.warn("Authentication scheme " + id + " not supported");
- // Try again
- }
- continue;
- }
- final AuthScheme authScheme = authSchemeProvider.create(context);
- options.add(authScheme);
- } else {
- if (this.log.isDebugEnabled()) {
- this.log.debug("Challenge for " + id + " authentication scheme not available");
- }
- }
- }
- return options;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/protocol/DefaultRedirectStrategy.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/protocol/DefaultRedirectStrategy.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/protocol/DefaultRedirectStrategy.java
deleted file mode 100644
index e94a21c..0000000
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/protocol/DefaultRedirectStrategy.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * ====================================================================
- * 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.protocol;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.Locale;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-import org.apache.hc.client5.http.config.RequestConfig;
-import org.apache.hc.client5.http.protocol.CircularRedirectException;
-import org.apache.hc.client5.http.protocol.HttpClientContext;
-import org.apache.hc.client5.http.protocol.RedirectLocations;
-import org.apache.hc.client5.http.protocol.RedirectStrategy;
-import org.apache.hc.client5.http.utils.URIUtils;
-import org.apache.hc.core5.annotation.Contract;
-import org.apache.hc.core5.annotation.ThreadingBehavior;
-import org.apache.hc.core5.http.Header;
-import org.apache.hc.core5.http.HttpException;
-import org.apache.hc.core5.http.HttpHeaders;
-import org.apache.hc.core5.http.HttpRequest;
-import org.apache.hc.core5.http.HttpResponse;
-import org.apache.hc.core5.http.HttpStatus;
-import org.apache.hc.core5.http.ProtocolException;
-import org.apache.hc.core5.http.protocol.HttpContext;
-import org.apache.hc.core5.net.URIBuilder;
-import org.apache.hc.core5.util.Args;
-import org.apache.hc.core5.util.TextUtils;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-
-/**
- * Default implementation of {@link RedirectStrategy}. This strategy honors the restrictions
- * on automatic redirection of unsafe methods such as POST, PUT and DELETE imposed by
- * the HTTP specification. Non safe methods will be redirected as GET in response to
- * status code {@link HttpStatus#SC_MOVED_PERMANENTLY}, {@link HttpStatus#SC_MOVED_TEMPORARILY}
- * and {@link HttpStatus#SC_SEE_OTHER}.
- *
- * @since 4.1
- */
-@Contract(threading = ThreadingBehavior.IMMUTABLE)
-public class DefaultRedirectStrategy implements RedirectStrategy {
-
- private final Logger log = LogManager.getLogger(getClass());
-
- public static final DefaultRedirectStrategy INSTANCE = new DefaultRedirectStrategy();
-
- private final ConcurrentMap<String, Boolean> safeMethods;
-
- public DefaultRedirectStrategy(final String... safeMethods) {
- super();
- this.safeMethods = new ConcurrentHashMap<>();
- for (final String safeMethod: safeMethods) {
- this.safeMethods.put(safeMethod.toUpperCase(Locale.ROOT), Boolean.TRUE);
- }
- }
-
- public DefaultRedirectStrategy() {
- this("GET", "HEAD", "OPTIONS", "TRACE");
- }
-
- @Override
- public boolean isRedirected(
- final HttpRequest request,
- final HttpResponse response,
- final HttpContext context) throws ProtocolException {
- Args.notNull(request, "HTTP request");
- Args.notNull(response, "HTTP response");
-
- if (!response.containsHeader(HttpHeaders.LOCATION)) {
- return false;
- }
- final int statusCode = response.getCode();
- switch (statusCode) {
- case HttpStatus.SC_MOVED_PERMANENTLY:
- case HttpStatus.SC_MOVED_TEMPORARILY:
- case HttpStatus.SC_SEE_OTHER:
- case HttpStatus.SC_TEMPORARY_REDIRECT:
- return true;
- default:
- return false;
- }
- }
-
- @Override
- public URI getLocationURI(
- final HttpRequest request,
- final HttpResponse response,
- final HttpContext context) throws HttpException {
- Args.notNull(request, "HTTP request");
- Args.notNull(response, "HTTP response");
- Args.notNull(context, "HTTP context");
-
- final HttpClientContext clientContext = HttpClientContext.adapt(context);
-
- //get the location header to find out where to redirect to
- final Header locationHeader = response.getFirstHeader("location");
- if (locationHeader == null) {
- throw new HttpException("Redirect location is missing");
- }
- final String location = locationHeader.getValue();
- if (this.log.isDebugEnabled()) {
- this.log.debug("Redirect requested to location '" + location + "'");
- }
-
- final RequestConfig config = clientContext.getRequestConfig();
-
- URI uri = createLocationURI(location);
- try {
- if (!uri.isAbsolute()) {
- // Resolve location URI
- uri = URIUtils.resolve(request.getUri(), uri);
- }
- } catch (final URISyntaxException ex) {
- throw new ProtocolException(ex.getMessage(), ex);
- }
-
- RedirectLocations redirectLocations = (RedirectLocations) clientContext.getAttribute(
- HttpClientContext.REDIRECT_LOCATIONS);
- if (redirectLocations == null) {
- redirectLocations = new RedirectLocations();
- context.setAttribute(HttpClientContext.REDIRECT_LOCATIONS, redirectLocations);
- }
- if (!config.isCircularRedirectsAllowed()) {
- if (redirectLocations.contains(uri)) {
- throw new CircularRedirectException("Circular redirect to '" + uri + "'");
- }
- }
- redirectLocations.add(uri);
- return uri;
- }
-
- /**
- * @since 4.1
- */
- protected URI createLocationURI(final String location) throws ProtocolException {
- try {
- final URIBuilder b = new URIBuilder(new URI(location).normalize());
- final String host = b.getHost();
- if (host != null) {
- b.setHost(host.toLowerCase(Locale.ROOT));
- }
- final String path = b.getPath();
- if (TextUtils.isEmpty(path)) {
- b.setPath("/");
- }
- return b.build();
- } catch (final URISyntaxException ex) {
- throw new ProtocolException("Invalid redirect URI: " + location, ex);
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/AIMDBackoffManager.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/AIMDBackoffManager.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/AIMDBackoffManager.java
deleted file mode 100644
index 9e2f84b..0000000
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/AIMDBackoffManager.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * ====================================================================
- * 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.util.HashMap;
-import java.util.Map;
-
-import org.apache.hc.client5.http.HttpRoute;
-import org.apache.hc.client5.http.sync.BackoffManager;
-import org.apache.hc.core5.pool.ConnPoolControl;
-import org.apache.hc.core5.util.Args;
-
-/**
- * <p>The {@code AIMDBackoffManager} applies an additive increase,
- * multiplicative decrease (AIMD) to managing a dynamic limit to
- * the number of connections allowed to a given host. You may want
- * to experiment with the settings for the cooldown periods and the
- * backoff factor to get the adaptive behavior you want.</p>
- *
- * <p>Generally speaking, shorter cooldowns will lead to more steady-state
- * variability but faster reaction times, while longer cooldowns
- * will lead to more stable equilibrium behavior but slower reaction
- * times.</p>
- *
- * <p>Similarly, higher backoff factors promote greater
- * utilization of available capacity at the expense of fairness
- * among clients. Lower backoff factors allow equal distribution of
- * capacity among clients (fairness) to happen faster, at the
- * expense of having more server capacity unused in the short term.</p>
- *
- * @since 4.2
- */
-public class AIMDBackoffManager implements BackoffManager {
-
- private final ConnPoolControl<HttpRoute> connPerRoute;
- private final Clock clock;
- private final Map<HttpRoute,Long> lastRouteProbes;
- private final Map<HttpRoute,Long> lastRouteBackoffs;
- private long coolDown = 5 * 1000L;
- private double backoffFactor = 0.5;
- private int cap = 2; // Per RFC 2616 sec 8.1.4
-
- /**
- * Creates an {@code AIMDBackoffManager} to manage
- * per-host connection pool sizes represented by the
- * given {@link ConnPoolControl}.
- * @param connPerRoute per-host routing maximums to
- * be managed
- */
- public AIMDBackoffManager(final ConnPoolControl<HttpRoute> connPerRoute) {
- this(connPerRoute, new SystemClock());
- }
-
- AIMDBackoffManager(final ConnPoolControl<HttpRoute> connPerRoute, final Clock clock) {
- this.clock = clock;
- this.connPerRoute = connPerRoute;
- this.lastRouteProbes = new HashMap<>();
- this.lastRouteBackoffs = new HashMap<>();
- }
-
- @Override
- public void backOff(final HttpRoute route) {
- synchronized(connPerRoute) {
- final int curr = connPerRoute.getMaxPerRoute(route);
- final Long lastUpdate = getLastUpdate(lastRouteBackoffs, route);
- final long now = clock.getCurrentTime();
- if (now - lastUpdate.longValue() < coolDown) {
- return;
- }
- connPerRoute.setMaxPerRoute(route, getBackedOffPoolSize(curr));
- lastRouteBackoffs.put(route, Long.valueOf(now));
- }
- }
-
- private int getBackedOffPoolSize(final int curr) {
- if (curr <= 1) {
- return 1;
- }
- return (int)(Math.floor(backoffFactor * curr));
- }
-
- @Override
- public void probe(final HttpRoute route) {
- synchronized(connPerRoute) {
- final int curr = connPerRoute.getMaxPerRoute(route);
- final int max = (curr >= cap) ? cap : curr + 1;
- final Long lastProbe = getLastUpdate(lastRouteProbes, route);
- final Long lastBackoff = getLastUpdate(lastRouteBackoffs, route);
- final long now = clock.getCurrentTime();
- if (now - lastProbe.longValue() < coolDown || now - lastBackoff.longValue() < coolDown) {
- return;
- }
- connPerRoute.setMaxPerRoute(route, max);
- lastRouteProbes.put(route, Long.valueOf(now));
- }
- }
-
- private Long getLastUpdate(final Map<HttpRoute,Long> updates, final HttpRoute route) {
- Long lastUpdate = updates.get(route);
- if (lastUpdate == null) {
- lastUpdate = Long.valueOf(0L);
- }
- return lastUpdate;
- }
-
- /**
- * Sets the factor to use when backing off; the new
- * per-host limit will be roughly the current max times
- * this factor. {@code Math.floor} is applied in the
- * case of non-integer outcomes to ensure we actually
- * decrease the pool size. Pool sizes are never decreased
- * below 1, however. Defaults to 0.5.
- * @param d must be between 0.0 and 1.0, exclusive.
- */
- public void setBackoffFactor(final double d) {
- Args.check(d > 0.0 && d < 1.0, "Backoff factor must be 0.0 < f < 1.0");
- backoffFactor = d;
- }
-
- /**
- * Sets the amount of time, in milliseconds, to wait between
- * adjustments in pool sizes for a given host, to allow
- * enough time for the adjustments to take effect. Defaults
- * to 5000L (5 seconds).
- * @param l must be positive
- */
- public void setCooldownMillis(final long l) {
- Args.positive(coolDown, "Cool down");
- coolDown = l;
- }
-
- /**
- * Sets the absolute maximum per-host connection pool size to
- * probe up to; defaults to 2 (the default per-host max).
- * @param cap must be >= 1
- */
- public void setPerHostConnectionCap(final int cap) {
- Args.positive(cap, "Per host connection cap");
- this.cap = cap;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/AbstractHttpClientResponseHandler.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/AbstractHttpClientResponseHandler.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/AbstractHttpClientResponseHandler.java
deleted file mode 100644
index 8bceb6d..0000000
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/AbstractHttpClientResponseHandler.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * ====================================================================
- * 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 org.apache.hc.client5.http.protocol.HttpResponseException;
-import org.apache.hc.core5.annotation.Contract;
-import org.apache.hc.core5.annotation.ThreadingBehavior;
-import org.apache.hc.core5.http.ClassicHttpResponse;
-import org.apache.hc.core5.http.HttpEntity;
-import org.apache.hc.core5.http.HttpStatus;
-import org.apache.hc.core5.http.io.HttpClientResponseHandler;
-import org.apache.hc.core5.http.io.entity.EntityUtils;
-
-/**
- * A generic {@link HttpClientResponseHandler} that works with the response entity
- * for successful (2xx) responses. If the response code was >= 300, the response
- * body is consumed and an {@link HttpResponseException} is thrown.
- * <p>
- * If this is used with
- * {@link org.apache.hc.client5.http.sync.HttpClient#execute(org.apache.hc.core5.http.ClassicHttpRequest,
- * HttpClientResponseHandler)},
- * HttpClient may handle redirects (3xx responses) internally.
- * </p>
- *
- * @since 4.4
- */
-@Contract(threading = ThreadingBehavior.IMMUTABLE)
-public abstract class AbstractHttpClientResponseHandler<T> implements HttpClientResponseHandler<T> {
-
- /**
- * Read the entity from the response body and pass it to the entity handler
- * method if the response was successful (a 2xx status code). If no response
- * body exists, this returns null. If the response was unsuccessful (>= 300
- * status code), throws an {@link HttpResponseException}.
- */
- @Override
- public T handleResponse(final ClassicHttpResponse response) throws IOException {
- final HttpEntity entity = response.getEntity();
- if (response.getCode() >= HttpStatus.SC_REDIRECTION) {
- EntityUtils.consume(entity);
- throw new HttpResponseException(response.getCode(), response.getReasonPhrase());
- }
- return entity == null ? null : handleEntity(entity);
- }
-
- /**
- * Handle the response entity and transform it into the actual response
- * object.
- */
- public abstract T handleEntity(HttpEntity entity) throws IOException;
-
-}
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/BackoffStrategyExec.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/BackoffStrategyExec.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/BackoffStrategyExec.java
deleted file mode 100644
index 231c31e..0000000
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/BackoffStrategyExec.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * ====================================================================
- * 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 org.apache.hc.client5.http.HttpRoute;
-import org.apache.hc.client5.http.sync.BackoffManager;
-import org.apache.hc.client5.http.sync.ConnectionBackoffStrategy;
-import org.apache.hc.client5.http.sync.ExecChain;
-import org.apache.hc.client5.http.sync.ExecChainHandler;
-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.HttpException;
-import org.apache.hc.core5.util.Args;
-
-/**
- * @since 4.3
- */
-@Contract(threading = ThreadingBehavior.IMMUTABLE)
-final class BackoffStrategyExec implements ExecChainHandler {
-
- private final ConnectionBackoffStrategy connectionBackoffStrategy;
- private final BackoffManager backoffManager;
-
- public BackoffStrategyExec(
- final ConnectionBackoffStrategy connectionBackoffStrategy,
- final BackoffManager backoffManager) {
- super();
- Args.notNull(connectionBackoffStrategy, "Connection backoff strategy");
- Args.notNull(backoffManager, "Backoff manager");
- this.connectionBackoffStrategy = connectionBackoffStrategy;
- this.backoffManager = backoffManager;
- }
-
- @Override
- public ClassicHttpResponse execute(
- final ClassicHttpRequest request,
- final ExecChain.Scope scope,
- final ExecChain chain) throws IOException, HttpException {
- Args.notNull(request, "HTTP request");
- Args.notNull(scope, "Scope");
- final HttpRoute route = scope.route;
-
- final ClassicHttpResponse response;
- try {
- response = chain.proceed(request, scope);
- } catch (final IOException | HttpException ex) {
- if (this.connectionBackoffStrategy.shouldBackoff(ex)) {
- this.backoffManager.backOff(route);
- }
- throw ex;
- }
- if (this.connectionBackoffStrategy.shouldBackoff(response)) {
- this.backoffManager.backOff(route);
- } else {
- this.backoffManager.probe(route);
- }
- return response;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/BasicCredentialsProvider.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/BasicCredentialsProvider.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/BasicCredentialsProvider.java
deleted file mode 100644
index 9466be8..0000000
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/BasicCredentialsProvider.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * ====================================================================
- * 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.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.apache.hc.client5.http.auth.AuthScope;
-import org.apache.hc.client5.http.auth.Credentials;
-import org.apache.hc.client5.http.auth.CredentialsStore;
-import org.apache.hc.core5.annotation.Contract;
-import org.apache.hc.core5.annotation.ThreadingBehavior;
-import org.apache.hc.core5.http.protocol.HttpContext;
-import org.apache.hc.core5.util.Args;
-
-/**
- * Default implementation of {@link CredentialsStore}.
- *
- * @since 4.0
- */
-@Contract(threading = ThreadingBehavior.SAFE)
-public class BasicCredentialsProvider implements CredentialsStore {
-
- private final ConcurrentHashMap<AuthScope, Credentials> credMap;
-
- /**
- * Default constructor.
- */
- public BasicCredentialsProvider() {
- super();
- this.credMap = new ConcurrentHashMap<>();
- }
-
- @Override
- public void setCredentials(
- final AuthScope authscope,
- final Credentials credentials) {
- Args.notNull(authscope, "Authentication scope");
- credMap.put(authscope, credentials);
- }
-
- /**
- * Find matching {@link Credentials credentials} for the given authentication scope.
- *
- * @param map the credentials hash map
- * @param authscope the {@link AuthScope authentication scope}
- * @return the credentials
- *
- */
- private static Credentials matchCredentials(
- final Map<AuthScope, Credentials> map,
- final AuthScope authscope) {
- // see if we get a direct hit
- Credentials creds = map.get(authscope);
- if (creds == null) {
- // Nope.
- // Do a full scan
- int bestMatchFactor = -1;
- AuthScope bestMatch = null;
- for (final AuthScope current: map.keySet()) {
- final int factor = authscope.match(current);
- if (factor > bestMatchFactor) {
- bestMatchFactor = factor;
- bestMatch = current;
- }
- }
- if (bestMatch != null) {
- creds = map.get(bestMatch);
- }
- }
- return creds;
- }
-
- @Override
- public Credentials getCredentials(final AuthScope authscope,
- final HttpContext httpContext) {
- Args.notNull(authscope, "Authentication scope");
- return matchCredentials(this.credMap, authscope);
- }
-
- @Override
- public void clear() {
- this.credMap.clear();
- }
-
- @Override
- public String toString() {
- return credMap.toString();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/BasicHttpClientResponseHandler.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/BasicHttpClientResponseHandler.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/BasicHttpClientResponseHandler.java
deleted file mode 100644
index f411006..0000000
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/BasicHttpClientResponseHandler.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * ====================================================================
- * 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 org.apache.hc.client5.http.protocol.ClientProtocolException;
-import org.apache.hc.core5.annotation.Contract;
-import org.apache.hc.core5.annotation.ThreadingBehavior;
-import org.apache.hc.core5.http.ClassicHttpResponse;
-import org.apache.hc.core5.http.HttpEntity;
-import org.apache.hc.core5.http.ParseException;
-import org.apache.hc.core5.http.io.entity.EntityUtils;
-
-/**
- * A {@link org.apache.hc.core5.http.io.HttpClientResponseHandler} that returns the response body as a String
- * for successful (2xx) responses. If the response code was >= 300, the response
- * body is consumed and an {@link org.apache.hc.client5.http.protocol.HttpResponseException} is thrown.
- * <p>
- * If this is used with
- * {@link org.apache.hc.client5.http.sync.HttpClient#execute(
- * org.apache.hc.core5.http.ClassicHttpRequest, org.apache.hc.core5.http.io.HttpClientResponseHandler)},
- * HttpClient may handle redirects (3xx responses) internally.
- * </p>
- *
- * @since 4.0
- */
-@Contract(threading = ThreadingBehavior.IMMUTABLE)
-public class BasicHttpClientResponseHandler extends AbstractHttpClientResponseHandler<String> {
-
- /**
- * Returns the entity as a body as a String.
- */
- @Override
- public String handleEntity(final HttpEntity entity) throws IOException {
- try {
- return EntityUtils.toString(entity);
- } catch (final ParseException ex) {
- throw new ClientProtocolException(ex);
- }
- }
-
- @Override
- public String handleResponse(final ClassicHttpResponse response) throws IOException {
- return super.handleResponse(response);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/ChainElements.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/ChainElements.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/ChainElements.java
deleted file mode 100644
index 743db74..0000000
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/ChainElements.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * ====================================================================
- * 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;
-
-public enum ChainElements {
-
- REDIRECT, BACK_OFF, RETRY_SERVICE_UNAVAILABLE, RETRY_IO_ERROR, PROTOCOL, CONNECT, MAIN_TRANSPORT
-
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/Clock.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/Clock.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/Clock.java
deleted file mode 100644
index e370f6f..0000000
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/Clock.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * ====================================================================
- * 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;
-
-/**
- * Interface used to enable easier testing of time-related behavior.
- *
- * @since 4.2
- *
- */
-interface Clock {
-
- /**
- * Returns the current time, expressed as the number of
- * milliseconds since the epoch.
- * @return current time
- */
- long getCurrentTime();
-}
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/CloseableHttpClient.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/CloseableHttpClient.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/CloseableHttpClient.java
deleted file mode 100644
index 17f4777..0000000
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/CloseableHttpClient.java
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * ====================================================================
- * 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.Closeable;
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-
-import org.apache.hc.client5.http.protocol.ClientProtocolException;
-import org.apache.hc.client5.http.sync.HttpClient;
-import org.apache.hc.client5.http.utils.URIUtils;
-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.HttpEntity;
-import org.apache.hc.core5.http.HttpException;
-import org.apache.hc.core5.http.HttpHost;
-import org.apache.hc.core5.http.io.HttpClientResponseHandler;
-import org.apache.hc.core5.http.io.entity.EntityUtils;
-import org.apache.hc.core5.http.protocol.HttpContext;
-import org.apache.hc.core5.util.Args;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-
-/**
- * Base implementation of {@link HttpClient} that also implements {@link Closeable}.
- *
- * @since 4.3
- */
-@Contract(threading = ThreadingBehavior.SAFE)
-public abstract class CloseableHttpClient implements HttpClient, Closeable {
-
- private final Logger log = LogManager.getLogger(getClass());
-
- protected abstract CloseableHttpResponse doExecute(HttpHost target, ClassicHttpRequest request,
- HttpContext context) throws IOException;
-
- /**
- * {@inheritDoc}
- */
- @Override
- public CloseableHttpResponse execute(
- final HttpHost target,
- final ClassicHttpRequest request,
- final HttpContext context) throws IOException {
- return doExecute(target, request, context);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public CloseableHttpResponse execute(
- final ClassicHttpRequest request,
- final HttpContext context) throws IOException {
- Args.notNull(request, "HTTP request");
- return doExecute(determineTarget(request), request, context);
- }
-
- private static HttpHost determineTarget(final ClassicHttpRequest request) throws ClientProtocolException {
- // A null target may be acceptable if there is a default target.
- // Otherwise, the null target is detected in the director.
- HttpHost target = null;
- URI requestURI = null;
- try {
- requestURI = request.getUri();
- } catch (final URISyntaxException ignore) {
- }
- if (requestURI != null && requestURI.isAbsolute()) {
- target = URIUtils.extractHost(requestURI);
- if (target == null) {
- throw new ClientProtocolException("URI does not specify a valid host name: "
- + requestURI);
- }
- }
- return target;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public CloseableHttpResponse execute(
- final ClassicHttpRequest request) throws IOException {
- return execute(request, (HttpContext) null);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public CloseableHttpResponse execute(
- final HttpHost target,
- final ClassicHttpRequest request) throws IOException {
- return doExecute(target, request, null);
- }
-
- /**
- * Executes a request using the default context and processes the
- * response using the given response handler. The content entity associated
- * with the response is fully consumed and the underlying connection is
- * released back to the connection manager automatically in all cases
- * relieving individual {@link HttpClientResponseHandler}s from having to manage
- * resource deallocation internally.
- *
- * @param request the request to execute
- * @param HttpClientResponseHandler the response handler
- *
- * @return the response object as generated by the response handler.
- * @throws IOException in case of a problem or the connection was aborted
- * @throws ClientProtocolException in case of an http protocol error
- */
- @Override
- public <T> T execute(final ClassicHttpRequest request,
- final HttpClientResponseHandler<? extends T> HttpClientResponseHandler) throws IOException {
- return execute(request, HttpClientResponseHandler, null);
- }
-
- /**
- * Executes a request using the default context and processes the
- * response using the given response handler. The content entity associated
- * with the response is fully consumed and the underlying connection is
- * released back to the connection manager automatically in all cases
- * relieving individual {@link HttpClientResponseHandler}s from having to manage
- * resource deallocation internally.
- *
- * @param request the request to execute
- * @param HttpClientResponseHandler the response handler
- * @param context the context to use for the execution, or
- * {@code null} to use the default context
- *
- * @return the response object as generated by the response handler.
- * @throws IOException in case of a problem or the connection was aborted
- * @throws ClientProtocolException in case of an http protocol error
- */
- @Override
- public <T> T execute(final ClassicHttpRequest request,
- final HttpClientResponseHandler<? extends T> HttpClientResponseHandler, final HttpContext context)
- throws IOException {
- final HttpHost target = determineTarget(request);
- return execute(target, request, HttpClientResponseHandler, context);
- }
-
- /**
- * Executes a request using the default context and processes the
- * response using the given response handler. The content entity associated
- * with the response is fully consumed and the underlying connection is
- * released back to the connection manager automatically in all cases
- * relieving individual {@link HttpClientResponseHandler}s from having to manage
- * resource deallocation internally.
- *
- * @param target the target host for the request.
- * Implementations may accept {@code null}
- * if they can still determine a route, for example
- * to a default target or by inspecting the request.
- * @param request the request to execute
- * @param HttpClientResponseHandler the response handler
- *
- * @return the response object as generated by the response handler.
- * @throws IOException in case of a problem or the connection was aborted
- * @throws ClientProtocolException in case of an http protocol error
- */
- @Override
- public <T> T execute(final HttpHost target, final ClassicHttpRequest request,
- final HttpClientResponseHandler<? extends T> HttpClientResponseHandler) throws IOException {
- return execute(target, request, HttpClientResponseHandler, null);
- }
-
- /**
- * Executes a request using the default context and processes the
- * response using the given response handler. The content entity associated
- * with the response is fully consumed and the underlying connection is
- * released back to the connection manager automatically in all cases
- * relieving individual {@link HttpClientResponseHandler}s from having to manage
- * resource deallocation internally.
- *
- * @param target the target host for the request.
- * Implementations may accept {@code null}
- * if they can still determine a route, for example
- * to a default target or by inspecting the request.
- * @param request the request to execute
- * @param HttpClientResponseHandler the response handler
- * @param context the context to use for the execution, or
- * {@code null} to use the default context
- *
- * @return the response object as generated by the response handler.
- * @throws IOException in case of a problem or the connection was aborted
- * @throws ClientProtocolException in case of an http protocol error
- */
- @Override
- public <T> T execute(final HttpHost target, final ClassicHttpRequest request,
- final HttpClientResponseHandler<? extends T> HttpClientResponseHandler, final HttpContext context) throws IOException {
- Args.notNull(HttpClientResponseHandler, "Response handler");
-
- try (final CloseableHttpResponse response = execute(target, request, context)) {
- try {
- final T result = HttpClientResponseHandler.handleResponse(response);
- final HttpEntity entity = response.getEntity();
- EntityUtils.consume(entity);
- return result;
- } catch (final HttpException t) {
- // Try to salvage the underlying connection in case of a protocol exception
- final HttpEntity entity = response.getEntity();
- try {
- EntityUtils.consume(entity);
- } catch (final Exception t2) {
- // Log this exception. The original exception is more
- // important and will be thrown to the caller.
- this.log.warn("Error consuming content after an exception.", t2);
- }
- throw new ClientProtocolException(t);
- }
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/CloseableHttpResponse.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/CloseableHttpResponse.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/CloseableHttpResponse.java
deleted file mode 100644
index fd9e0f1..0000000
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/CloseableHttpResponse.java
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * ====================================================================
- * 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.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;
-import org.apache.hc.core5.http.ProtocolException;
-import org.apache.hc.core5.http.ProtocolVersion;
-import org.apache.hc.core5.util.Args;
-
-/**
- * Backward compatibility with HttpClient 4.x.
- *
- * @since 4.3
- */
-public final class CloseableHttpResponse implements ClassicHttpResponse {
-
- private final ClassicHttpResponse response;
- private final ExecRuntime execRuntime;
-
- static CloseableHttpResponse adapt(final ClassicHttpResponse response) {
- if (response == null) {
- return null;
- }
- if (response instanceof CloseableHttpResponse) {
- return (CloseableHttpResponse) response;
- } else {
- return new CloseableHttpResponse(response, null);
- }
- }
-
- CloseableHttpResponse(final ClassicHttpResponse response, final ExecRuntime execRuntime) {
- this.response = Args.notNull(response, "Response");
- this.execRuntime = execRuntime;
- }
-
- @Override
- public int getCode() {
- return response.getCode();
- }
-
- @Override
- public HttpEntity getEntity() {
- return response.getEntity();
- }
-
- @Override
- public boolean containsHeader(final String name) {
- return response.containsHeader(name);
- }
-
- @Override
- public void setVersion(final ProtocolVersion version) {
- response.setVersion(version);
- }
-
- @Override
- public void setCode(final int code) {
- response.setCode(code);
- }
-
- @Override
- public String getReasonPhrase() {
- return response.getReasonPhrase();
- }
-
- @Override
- public int containsHeaders(final String name) {
- return response.containsHeaders(name);
- }
-
- @Override
- public void setEntity(final HttpEntity entity) {
- response.setEntity(entity);
- }
-
- @Override
- public ProtocolVersion getVersion() {
- return response.getVersion();
- }
-
- @Override
- public void setReasonPhrase(final String reason) {
- response.setReasonPhrase(reason);
- }
-
- @Override
- public Header[] getHeaders(final String name) {
- return response.getHeaders(name);
- }
-
- @Override
- public void addHeader(final Header header) {
- response.addHeader(header);
- }
-
- @Override
- public Locale getLocale() {
- return response.getLocale();
- }
-
- @Override
- public void addHeader(final String name, final Object value) {
- response.addHeader(name, value);
- }
-
- @Override
- public void setLocale(final Locale loc) {
- response.setLocale(loc);
- }
-
- @Override
- public Header getSingleHeader(final String name) throws ProtocolException {
- return response.getSingleHeader(name);
- }
-
- @Override
- public void setHeader(final Header header) {
- response.setHeader(header);
- }
-
- @Override
- public Header getFirstHeader(final String name) {
- return response.getFirstHeader(name);
- }
-
- @Override
- public void setHeader(final String name, final Object value) {
- response.setHeader(name, value);
- }
-
- @Override
- public void setHeaders(final Header... headers) {
- response.setHeaders(headers);
- }
-
- @Override
- public void removeHeader(final Header header) {
- response.removeHeader(header);
- }
-
- @Override
- public void removeHeaders(final String name) {
- response.removeHeaders(name);
- }
-
- @Override
- public Header getLastHeader(final String name) {
- return response.getLastHeader(name);
- }
-
- @Override
- public Header[] getAllHeaders() {
- return response.getAllHeaders();
- }
-
- @Override
- public Iterator<Header> headerIterator() {
- return response.headerIterator();
- }
-
- @Override
- public Iterator<Header> headerIterator(final String name) {
- return response.headerIterator(name);
- }
-
- @Override
- public void close() throws IOException {
- if (execRuntime != null) {
- try {
- response.close();
- execRuntime.disconnect();
- } finally {
- execRuntime.discardConnection();
- }
- } else {
- response.close();
- }
- }
-
- @Override
- public String toString() {
- return response.toString();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/ConnectExec.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/ConnectExec.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/ConnectExec.java
deleted file mode 100644
index 9836ee2..0000000
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/ConnectExec.java
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * ====================================================================
- * 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 org.apache.hc.client5.http.HttpRoute;
-import org.apache.hc.client5.http.RouteTracker;
-import org.apache.hc.client5.http.auth.AuthExchange;
-import org.apache.hc.client5.http.auth.ChallengeType;
-import org.apache.hc.client5.http.config.RequestConfig;
-import org.apache.hc.client5.http.impl.auth.HttpAuthenticator;
-import org.apache.hc.client5.http.impl.routing.BasicRouteDirector;
-import org.apache.hc.client5.http.protocol.AuthenticationStrategy;
-import org.apache.hc.client5.http.protocol.HttpClientContext;
-import org.apache.hc.client5.http.routing.HttpRouteDirector;
-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.ConnectionReuseStrategy;
-import org.apache.hc.core5.http.HttpEntity;
-import org.apache.hc.core5.http.HttpException;
-import org.apache.hc.core5.http.HttpHeaders;
-import org.apache.hc.core5.http.HttpHost;
-import org.apache.hc.core5.http.HttpRequest;
-import org.apache.hc.core5.http.HttpStatus;
-import org.apache.hc.core5.http.HttpVersion;
-import org.apache.hc.core5.http.io.entity.EntityUtils;
-import org.apache.hc.core5.http.message.BasicClassicHttpRequest;
-import org.apache.hc.core5.http.message.StatusLine;
-import org.apache.hc.core5.http.protocol.HttpProcessor;
-import org.apache.hc.core5.util.Args;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-
-/**
- * Request executor in the HTTP request execution chain
- * that is responsible for establishing connection to the target
- * origin server as specified by the current route.
- *
- * @since 5.0
- */
-@Contract(threading = ThreadingBehavior.IMMUTABLE_CONDITIONAL)
-public final class ConnectExec implements ExecChainHandler {
-
- private final Logger log = LogManager.getLogger(getClass());
-
- private final ConnectionReuseStrategy reuseStrategy;
- private final HttpProcessor proxyHttpProcessor;
- private final AuthenticationStrategy proxyAuthStrategy;
- private final HttpAuthenticator authenticator;
- private final HttpRouteDirector routeDirector;
-
- public ConnectExec(
- final ConnectionReuseStrategy reuseStrategy,
- final HttpProcessor proxyHttpProcessor,
- final AuthenticationStrategy proxyAuthStrategy) {
- Args.notNull(reuseStrategy, "Connection reuse strategy");
- Args.notNull(proxyHttpProcessor, "Proxy HTTP processor");
- Args.notNull(proxyAuthStrategy, "Proxy authentication strategy");
- this.reuseStrategy = reuseStrategy;
- this.proxyHttpProcessor = proxyHttpProcessor;
- this.proxyAuthStrategy = proxyAuthStrategy;
- this.authenticator = new HttpAuthenticator();
- this.routeDirector = new BasicRouteDirector();
- }
-
- @Override
- public ClassicHttpResponse execute(
- final ClassicHttpRequest request,
- final ExecChain.Scope scope,
- final ExecChain chain) throws IOException, HttpException {
- Args.notNull(request, "HTTP request");
- Args.notNull(scope, "Scope");
-
- final HttpRoute route = scope.route;
- final HttpClientContext context = scope.clientContext;
- final ExecRuntime execRuntime = scope.execRuntime;
-
- if (!execRuntime.isConnectionAcquired()) {
- final Object userToken = context.getUserToken();
- execRuntime.acquireConnection(route, userToken, context);
- }
- try {
- if (!execRuntime.isConnected()) {
- this.log.debug("Opening connection " + route);
-
- final RouteTracker tracker = new RouteTracker(route);
- int step;
- do {
- final HttpRoute fact = tracker.toRoute();
- step = this.routeDirector.nextStep(route, fact);
-
- switch (step) {
-
- case HttpRouteDirector.CONNECT_TARGET:
- execRuntime.connect(context);
- tracker.connectTarget(route.isSecure());
- break;
- case HttpRouteDirector.CONNECT_PROXY:
- execRuntime.connect(context);
- final HttpHost proxy = route.getProxyHost();
- tracker.connectProxy(proxy, false);
- break;
- case HttpRouteDirector.TUNNEL_TARGET: {
- final boolean secure = createTunnelToTarget(route, request, execRuntime, context);
- this.log.debug("Tunnel to target created.");
- tracker.tunnelTarget(secure);
- } break;
-
- case HttpRouteDirector.TUNNEL_PROXY: {
- // The most simple example for this case is a proxy chain
- // of two proxies, where P1 must be tunnelled to P2.
- // route: Source -> P1 -> P2 -> Target (3 hops)
- // fact: Source -> P1 -> Target (2 hops)
- final int hop = fact.getHopCount()-1; // the hop to establish
- final boolean secure = createTunnelToProxy(route, hop, context);
- this.log.debug("Tunnel to proxy created.");
- tracker.tunnelProxy(route.getHopTarget(hop), secure);
- } break;
-
- case HttpRouteDirector.LAYER_PROTOCOL:
- execRuntime.upgradeTls(context);
- tracker.layerProtocol(route.isSecure());
- break;
-
- case HttpRouteDirector.UNREACHABLE:
- throw new HttpException("Unable to establish route: " +
- "planned = " + route + "; current = " + fact);
- case HttpRouteDirector.COMPLETE:
- break;
- default:
- throw new IllegalStateException("Unknown step indicator "
- + step + " from RouteDirector.");
- }
-
- } while (step > HttpRouteDirector.COMPLETE);
- }
- return chain.proceed(request, scope);
-
- } catch (final IOException | HttpException | RuntimeException ex) {
- execRuntime.discardConnection();
- throw ex;
- }
- }
-
- /**
- * Creates a tunnel to the target server.
- * The connection must be established to the (last) proxy.
- * A CONNECT request for tunnelling through the proxy will
- * be created and sent, the response received and checked.
- * This method does <i>not</i> processChallenge the connection with
- * information about the tunnel, that is left to the caller.
- */
- private boolean createTunnelToTarget(
- final HttpRoute route,
- final HttpRequest request,
- final ExecRuntime execRuntime,
- final HttpClientContext context) throws HttpException, IOException {
-
- final RequestConfig config = context.getRequestConfig();
-
- final HttpHost target = route.getTargetHost();
- final HttpHost proxy = route.getProxyHost();
- final AuthExchange proxyAuthExchange = context.getAuthExchange(proxy);
- ClassicHttpResponse response = null;
-
- final String authority = target.toHostString();
- final ClassicHttpRequest connect = new BasicClassicHttpRequest("CONNECT", target, authority);
- connect.setVersion(HttpVersion.HTTP_1_1);
-
- this.proxyHttpProcessor.process(connect, null, context);
-
- while (response == null) {
- connect.removeHeaders(HttpHeaders.PROXY_AUTHORIZATION);
- this.authenticator.addAuthResponse(proxy, ChallengeType.PROXY, connect, proxyAuthExchange, context);
-
- response = execRuntime.execute(connect, context);
-
- final int status = response.getCode();
- if (status < HttpStatus.SC_SUCCESS) {
- throw new HttpException("Unexpected response to CONNECT request: " + new StatusLine(response));
- }
-
- if (config.isAuthenticationEnabled()) {
- if (this.authenticator.isChallenged(proxy, ChallengeType.PROXY, response,
- proxyAuthExchange, context)) {
- if (this.authenticator.prepareAuthResponse(proxy, ChallengeType.PROXY, response,
- this.proxyAuthStrategy, proxyAuthExchange, context)) {
- // Retry request
- if (this.reuseStrategy.keepAlive(request, response, context)) {
- this.log.debug("Connection kept alive");
- // Consume response content
- final HttpEntity entity = response.getEntity();
- EntityUtils.consume(entity);
- } else {
- execRuntime.disconnect();
- }
- response = null;
- }
- }
- }
- }
-
- final int status = response.getCode();
- if (status >= HttpStatus.SC_REDIRECTION) {
-
- // Buffer response content
- final HttpEntity entity = response.getEntity();
- final String responseMessage = entity != null ? EntityUtils.toString(entity) : null;
- execRuntime.disconnect();
- throw new TunnelRefusedException("CONNECT refused by proxy: " + new StatusLine(response), responseMessage);
- }
-
- // How to decide on security of the tunnelled connection?
- // The socket factory knows only about the segment to the proxy.
- // Even if that is secure, the hop to the target may be insecure.
- // Leave it to derived classes, consider insecure by default here.
- return false;
- }
-
- /**
- * Creates a tunnel to an intermediate proxy.
- * This method is <i>not</i> implemented in this class.
- * It just throws an exception here.
- */
- private boolean createTunnelToProxy(
- final HttpRoute route,
- final int hop,
- final HttpClientContext context) throws HttpException {
-
- // Have a look at createTunnelToTarget and replicate the parts
- // you need in a custom derived class. If your proxies don't require
- // authentication, it is not too hard. But for the stock version of
- // HttpClient, we cannot make such simplifying assumptions and would
- // have to include proxy authentication code. The HttpComponents team
- // is currently not in a position to support rarely used code of this
- // complexity. Feel free to submit patches that refactor the code in
- // createTunnelToTarget to facilitate re-use for proxy tunnelling.
-
- throw new HttpException("Proxy chains are not supported.");
- }
-
-}