public ClassicHttpResponse execute()

in httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/HttpRequestRetryExec.java [99:196]


    public ClassicHttpResponse execute(
            final ClassicHttpRequest request,
            final Scope scope,
            final ExecChain chain) throws IOException, HttpException {
        Args.notNull(request, "request");
        Args.notNull(scope, "scope");
        final String exchangeId = scope.exchangeId;
        final HttpRoute route = scope.route;
        final HttpClientContext context = scope.clientContext;
        ClassicHttpRequest currentRequest = request;

        for (int execCount = 1;; execCount++) {
            final ClassicHttpResponse response;
            try {
                 response = chain.proceed(currentRequest, scope);
            } catch (final IOException ex) {
                if (scope.execRuntime.isExecutionAborted()) {
                    throw new RequestFailedException("Request aborted");
                }
                final HttpEntity requestEntity = request.getEntity();
                if (requestEntity != null && !requestEntity.isRepeatable()) {
                    if (LOG.isDebugEnabled()) {
                        LOG.debug("{} cannot retry non-repeatable request", exchangeId);
                    }
                    throw ex;
                }
                if (retryStrategy.retryRequest(request, ex, execCount, context)) {
                    if (LOG.isDebugEnabled()) {
                        LOG.debug("{} {}", exchangeId, ex.getMessage(), ex);
                    }
                    if (LOG.isInfoEnabled()) {
                        LOG.info("Recoverable I/O exception ({}) caught when processing request to {}",
                                ex.getClass().getName(), route);
                    }
                    final TimeValue nextInterval = retryStrategy.getRetryInterval(request, ex, execCount, context);
                    if (TimeValue.isPositive(nextInterval)) {
                        try {
                            if (LOG.isDebugEnabled()) {
                                LOG.debug("{} wait for {}", exchangeId, nextInterval);
                            }
                            nextInterval.sleep();
                        } catch (final InterruptedException e) {
                            Thread.currentThread().interrupt();
                            throw new InterruptedIOException();
                        }
                    }
                    currentRequest = ClassicRequestBuilder.copy(scope.originalRequest).build();
                    continue;
                }
                if (ex instanceof NoHttpResponseException) {
                    final NoHttpResponseException updatedex = new NoHttpResponseException(
                            route.getTargetHost().toHostString() + " failed to respond");
                    updatedex.setStackTrace(ex.getStackTrace());
                    throw updatedex;
                }
                throw ex;
            }

            try {
                final HttpEntity entity = request.getEntity();
                if (entity != null && !entity.isRepeatable()) {
                    if (LOG.isDebugEnabled()) {
                        LOG.debug("{} cannot retry non-repeatable request", exchangeId);
                    }
                    return response;
                }
                if (retryStrategy.retryRequest(response, execCount, context)) {
                    final TimeValue nextInterval = retryStrategy.getRetryInterval(response, execCount, context);
                    // Make sure the retry interval does not exceed the response timeout
                    if (TimeValue.isPositive(nextInterval)) {
                        final RequestConfig requestConfig = context.getRequestConfigOrDefault();
                        final Timeout responseTimeout = requestConfig.getResponseTimeout();
                        if (responseTimeout != null && nextInterval.compareTo(responseTimeout) > 0) {
                            return response;
                        }
                    }
                    response.close();
                    if (TimeValue.isPositive(nextInterval)) {
                        try {
                            if (LOG.isDebugEnabled()) {
                                LOG.debug("{} wait for {}", exchangeId, nextInterval);
                            }
                            nextInterval.sleep();
                        } catch (final InterruptedException e) {
                            Thread.currentThread().interrupt();
                            throw new InterruptedIOException();
                        }
                    }
                    currentRequest = ClassicRequestBuilder.copy(scope.originalRequest).build();
                } else {
                    return response;
                }
            } catch (final RuntimeException ex) {
                response.close();
                throw ex;
            }
        }
    }