public ClassicHttpResponse execute()

in httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HttpRequester.java [295:422]


    public ClassicHttpResponse execute(
            final HttpHost targetHost,
            final ClassicHttpRequest request,
            final HttpResponseInformationCallback informationCallback,
            final Timeout connectTimeout,
            final HttpContext context) throws HttpException, IOException {
        Args.notNull(targetHost, "HTTP host");
        Args.notNull(request, "HTTP request");
        final Future<PoolEntry<HttpHost, HttpClientConnection>> leaseFuture = connPool.lease(targetHost, null, connectTimeout, null);
        final PoolEntry<HttpHost, HttpClientConnection> poolEntry;
        final Timeout timeout = Timeout.defaultsToInfinite(connectTimeout);
        try {
            poolEntry = leaseFuture.get(timeout.getDuration(), timeout.getTimeUnit());
        } catch (final InterruptedException ex) {
            Thread.currentThread().interrupt();
            throw new InterruptedIOException(ex.getMessage());
        } catch (final ExecutionException ex) {
            throw new HttpException("Unexpected failure leasing connection", ex);
        } catch (final TimeoutException ex) {
            throw new ConnectionRequestTimeoutException("Connection request timeout");
        }
        final PoolEntryHolder connectionHolder = new PoolEntryHolder(poolEntry);
        try {
            HttpClientConnection connection = poolEntry.getConnection();
            if (connection == null) {
                final Socket sock;
                if (socketConfig.getSocksProxyAddress() != null) {
                    sock = new Socket(new Proxy(Proxy.Type.SOCKS, socketConfig.getSocksProxyAddress()));
                } else {
                    sock = new Socket();
                }
                try {
                    connection = createConnection(sock, targetHost);
                    poolEntry.assignConnection(connection);
                } catch (IOException | RuntimeException ex) {
                    Closer.closeQuietly(sock);
                    throw ex;
                }
            }
            if (request.getAuthority() == null) {
                request.setAuthority(new URIAuthority(targetHost));
            }
            final ClassicHttpResponse response = execute(connection, request, informationCallback, context);
            final HttpEntity entity = response.getEntity();
            if (entity != null) {
                response.setEntity(new HttpEntityWrapper(entity) {

                    private void releaseConnection() throws IOException {
                        try {
                            final HttpClientConnection localConn = connectionHolder.getConnection();
                            if (localConn != null) {
                                if (requestExecutor.keepAlive(request, response, localConn, context)) {
                                    if (super.isStreaming()) {
                                        Closer.close(super.getContent());
                                    }
                                    connectionHolder.releaseConnection();
                                }
                            }
                        } finally {
                            connectionHolder.discardConnection();
                        }
                    }

                    private void abortConnection() {
                        connectionHolder.discardConnection();
                    }

                    @Override
                    public boolean isStreaming() {
                        return true;
                    }

                    @Override
                    public InputStream getContent() throws IOException {
                        return new EofSensorInputStream(super.getContent(), new EofSensorWatcher() {

                            @Override
                            public boolean eofDetected(final InputStream wrapped) throws IOException {
                                releaseConnection();
                                return false;
                            }

                            @Override
                            public boolean streamClosed(final InputStream wrapped) throws IOException {
                                releaseConnection();
                                return false;
                            }

                            @Override
                            public boolean streamAbort(final InputStream wrapped) throws IOException {
                                abortConnection();
                                return false;
                            }

                        });
                    }

                    @Override
                    public void writeTo(final OutputStream outStream) throws IOException {
                        try {
                            if (outStream != null) {
                                super.writeTo(outStream);
                            }
                            close();
                        } catch (final IOException | RuntimeException ex) {
                            abortConnection();
                        }
                    }

                    @Override
                    public void close() throws IOException {
                        releaseConnection();
                    }

                });
            } else {
                final HttpClientConnection localConn = connectionHolder.getConnection();
                if (!requestExecutor.keepAlive(request, response, localConn, context)) {
                    localConn.close();
                }
                connectionHolder.releaseConnection();
            }
            return response;
        } catch (final HttpException | IOException | RuntimeException ex) {
            connectionHolder.discardConnection();
            throw ex;
        }
    }