in httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/ConnectExec.java [216:304]
private ClassicHttpResponse createTunnelToTarget(
final String exchangeId,
final HttpRoute route,
final HttpRequest request,
final ExecRuntime execRuntime,
final HttpClientContext context) throws HttpException, IOException {
final RequestConfig config = context.getRequestConfigOrDefault();
final HttpHost target = route.getTargetHost();
final HttpHost proxy = route.getProxyHost();
final AuthExchange proxyAuthExchange = context.getAuthExchange(proxy);
if (authCacheKeeper != null) {
authCacheKeeper.loadPreemptively(proxy, null, proxyAuthExchange, context);
}
ClassicHttpResponse response = null;
final String authority = target.toHostString();
final ClassicHttpRequest connect = new BasicClassicHttpRequest(Method.CONNECT, target, authority);
connect.setVersion(HttpVersion.HTTP_1_1);
this.proxyHttpProcessor.process(connect, null, context);
while (response == null) {
connect.removeHeaders(HttpHeaders.PROXY_AUTHORIZATION);
this.authenticator.addAuthResponse(proxy, ChallengeType.PROXY, connect, proxyAuthExchange, context);
response = execRuntime.execute(exchangeId, connect, context);
this.proxyHttpProcessor.process(response, response.getEntity(), context);
final int status = response.getCode();
if (status < HttpStatus.SC_SUCCESS) {
throw new HttpException("Unexpected response to CONNECT request: " + new StatusLine(response));
}
if (config.isAuthenticationEnabled()) {
final boolean proxyAuthRequested = authenticator.isChallenged(proxy, ChallengeType.PROXY, response, proxyAuthExchange, context);
final boolean proxyMutualAuthRequired = authenticator.isChallengeExpected(proxyAuthExchange);
if (authCacheKeeper != null) {
if (proxyAuthRequested) {
authCacheKeeper.updateOnChallenge(proxy, null, proxyAuthExchange, context);
} else {
authCacheKeeper.updateOnNoChallenge(proxy, null, proxyAuthExchange, context);
}
}
if (proxyAuthRequested || proxyMutualAuthRequired) {
final boolean updated = authenticator.handleResponse(proxy, ChallengeType.PROXY, response,
proxyAuthStrategy, proxyAuthExchange, context);
if (authCacheKeeper != null) {
authCacheKeeper.updateOnResponse(proxy, null, proxyAuthExchange, context);
}
if (updated) {
// Retry request
if (this.reuseStrategy.keepAlive(connect, response, context)) {
if (LOG.isDebugEnabled()) {
LOG.debug("{} connection kept alive", exchangeId);
}
// Consume response content
final HttpEntity entity = response.getEntity();
EntityUtils.consume(entity);
} else {
execRuntime.disconnectEndpoint();
}
response = null;
}
}
}
}
final int status = response.getCode();
if (status == HttpStatus.SC_OK) {
context.setProtocolVersion(null);
} else {
final HttpEntity entity = response.getEntity();
if (entity != null) {
response.setEntity(new ByteArrayEntity(
EntityUtils.toByteArray(entity, 4096),
ContentType.parseLenient(entity.getContentType())));
execRuntime.discardEndpoint();
}
return response;
}
return null;
}