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;
}
}