long timeout = ConnManagerParams.getTimeout(params);
try {
managedConn = connRequest.getConnection(timeout, TimeUnit.MILLISECONDS);
} catch(InterruptedException interrupted) {
InterruptedIOException iox = new InterruptedIOException();
iox.initCause(interrupted);
throw iox;
}
if (HttpConnectionParams.isStaleCheckingEnabled(params)) {
// validate connection
if (managedConn.isOpen()) {
this.log.debug("Stale connection check");
if (managedConn.isStale()) {
this.log.debug("Stale connection detected");
managedConn.close();
}
}
}
}
if (orig instanceof AbortableHttpRequest) {
((AbortableHttpRequest) orig).setReleaseTrigger(managedConn);
}
try {
tryConnect(roureq, context);
} catch (TunnelRefusedException ex) {
if (this.log.isDebugEnabled()) {
this.log.debug(ex.getMessage());
}
response = ex.getResponse();
break;
}
// Reset headers on the request wrapper
wrapper.resetHeaders();
// Re-write request URI if needed
rewriteRequestURI(wrapper, route);
// Use virtual host if set
target = virtualHost;
if (target == null) {
target = route.getTargetHost();
}
HttpHost proxy = route.getProxyHost();
// Populate the execution context
context.setAttribute(ExecutionContext.HTTP_TARGET_HOST,
target);
context.setAttribute(ExecutionContext.HTTP_PROXY_HOST,
proxy);
context.setAttribute(ExecutionContext.HTTP_CONNECTION,
managedConn);
context.setAttribute(ClientContext.TARGET_AUTH_STATE,
targetAuthState);
context.setAttribute(ClientContext.PROXY_AUTH_STATE,
proxyAuthState);
// Run request protocol interceptors
requestExec.preProcess(wrapper, httpProcessor, context);
response = tryExecute(roureq, context);
if (response == null) {
// Need to start over
continue;
}
// Run response protocol interceptors
response.setParams(params);
requestExec.postProcess(response, httpProcessor, context);
// The connection is in or can be brought to a re-usable state.
reuse = reuseStrategy.keepAlive(response, context);
if (reuse) {
// Set the idle duration of this connection
long duration = keepAliveStrategy.getKeepAliveDuration(response, context);
if (this.log.isDebugEnabled()) {
String s;
if (duration > 0) {
s = "for " + duration + " " + TimeUnit.MILLISECONDS;
} else {
s = "indefinitely";
}
this.log.debug("Connection can be kept alive " + s);
}
managedConn.setIdleDuration(duration, TimeUnit.MILLISECONDS);
}
RoutedRequest followup = handleResponse(roureq, response, context);
if (followup == null) {
done = true;
} else {
if (reuse) {
// Make sure the response body is fully consumed, if present
HttpEntity entity = response.getEntity();
EntityUtils.consume(entity);
// entity consumed above is not an auto-release entity,
// need to mark the connection re-usable explicitly
managedConn.markReusable();
} else {
managedConn.close();
invalidateAuthIfSuccessful(this.proxyAuthState);
invalidateAuthIfSuccessful(this.targetAuthState);
}
// check if we can use the same connection for the followup
if (!followup.getRoute().equals(roureq.getRoute())) {
releaseConnection();
}
roureq = followup;
}
if (managedConn != null && userToken == null) {
userToken = userTokenHandler.getUserToken(context);
context.setAttribute(ClientContext.USER_TOKEN, userToken);
if (userToken != null) {
managedConn.setState(userToken);
}
}
} // while not done
// check for entity, release connection if possible
if ((response == null) || (response.getEntity() == null) ||
!response.getEntity().isStreaming()) {
// connection not needed and (assumed to be) in re-usable state
if (reuse)
managedConn.markReusable();
releaseConnection();
} else {
// install an auto-release entity
HttpEntity entity = response.getEntity();
entity = new BasicManagedEntity(entity, managedConn, reuse);
response.setEntity(entity);
}
return response;
} catch (ConnectionShutdownException ex) {
InterruptedIOException ioex = new InterruptedIOException(
"Connection has been shut down");
ioex.initCause(ex);
throw ioex;
} catch (HttpException ex) {
abortConnection();
throw ex;
} catch (IOException ex) {