@Override
    protected CloseableHttpResponse doExecute(
            final HttpHost target,
            final ClassicHttpRequest request,
            final HttpContext context) throws IOException {
        Args.notNull(target, "Target host");
        Args.notNull(request, "HTTP request");
        if (request.getScheme() == null) {
            request.setScheme(target.getSchemeName());
        }
        if (request.getAuthority() == null) {
            request.setAuthority(new URIAuthority(target));
        }
        final HttpClientContext clientContext = HttpClientContext.castOrCreate(context);
        RequestConfig config = null;
        if (request instanceof Configurable) {
            config = ((Configurable) request).getConfig();
        }
        if (config != null) {
            clientContext.setRequestConfig(config);
        }

        final HttpRoute route = new HttpRoute(RoutingSupport.normalize(target, schemePortResolver));
        final String exchangeId = ExecSupport.getNextExchangeId();
        clientContext.setExchangeId(exchangeId);
        final ExecRuntime execRuntime = new InternalExecRuntime(LOG, connManager, requestExecutor,
                request instanceof CancellableDependency ? (CancellableDependency) request : null);
        try {
            if (!execRuntime.isEndpointAcquired()) {
                execRuntime.acquireEndpoint(exchangeId, route, null, clientContext);
            }
            if (!execRuntime.isEndpointConnected()) {
                execRuntime.connectEndpoint(clientContext);
            }

            clientContext.setRequest(request);
            clientContext.setRoute(route);

            httpProcessor.process(request, request.getEntity(), clientContext);
            final ClassicHttpResponse response = execRuntime.execute(exchangeId, request, clientContext);
            httpProcessor.process(response, response.getEntity(), clientContext);

            if (reuseStrategy.keepAlive(request, response, clientContext)) {
                execRuntime.markConnectionReusable(null, TimeValue.NEG_ONE_MILLISECOND);
            } else {
                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
                execRuntime.releaseEndpoint();
                return new CloseableHttpResponse(response);
            }
            ResponseEntityProxy.enhance(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.discardEndpoint();
            throw ioex;
        } catch (final HttpException httpException) {
            execRuntime.discardEndpoint();
            throw new ClientProtocolException(httpException);
        } catch (final RuntimeException | IOException ex) {
            execRuntime.discardEndpoint();
            throw ex;
        } catch (final Error error) {
            connManager.close(CloseMode.IMMEDIATE);
            throw error;
        }
    }
Minimal implementation of {@link CloseableHttpClient}. This client is
optimized for HTTP/1.1 message transport and does not support advanced
HTTP protocol functionality such as request execution via a proxy, state
management, authentication and request redirects.
<p>
Concurrent message exchanges executed by this client will get assigned to
separate connections leased from the connection pool.
</p>

@since 4.3
httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/MinimalHttpClient.java