final HttpRoute route = new HttpRoute(
host,
this.requestConfig.getLocalAddress(),
proxy, false, TunnelType.TUNNELLED, LayerType.PLAIN);
final ManagedHttpClientConnection conn = this.connFactory.create(
route, this.connectionConfig);
final HttpContext context = new BasicHttpContext();
HttpResponse response;
final HttpRequest connect = new BasicHttpRequest(
"CONNECT", host.toHostString(), HttpVersion.HTTP_1_1);
final BasicCredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(new AuthScope(proxy), credentials);
// Populate the execution context
context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, target);
context.setAttribute(HttpCoreContext.HTTP_CONNECTION, conn);
context.setAttribute(HttpCoreContext.HTTP_REQUEST, connect);
context.setAttribute(HttpClientContext.HTTP_ROUTE, route);
context.setAttribute(HttpClientContext.PROXY_AUTH_STATE, this.proxyAuthState);
context.setAttribute(HttpClientContext.CREDS_PROVIDER, credsProvider);
context.setAttribute(HttpClientContext.AUTHSCHEME_REGISTRY, this.authSchemeRegistry);
context.setAttribute(HttpClientContext.REQUEST_CONFIG, this.requestConfig);
this.requestExec.preProcess(connect, this.httpProcessor, context);
for (;;) {
if (!conn.isOpen()) {
final Socket socket = new Socket(proxy.getHostName(), proxy.getPort());
conn.bind(socket);
}
this.authenticator.generateAuthResponse(connect, this.proxyAuthState, context);
response = this.requestExec.execute(connect, conn, context);
final int status = response.getStatusLine().getStatusCode();
if (status < 200) {
throw new HttpException("Unexpected response to CONNECT request: " +
response.getStatusLine());
}
if (this.authenticator.isAuthenticationRequested(proxy, response,
this.proxyAuthStrategy, this.proxyAuthState, context)) {
if (this.authenticator.handleAuthChallenge(proxy, response,
this.proxyAuthStrategy, this.proxyAuthState, context)) {
// Retry request
if (this.reuseStrategy.keepAlive(response, context)) {
// Consume response content
final HttpEntity entity = response.getEntity();
EntityUtils.consume(entity);
} else {
conn.close();
}
// discard previous auth header
connect.removeHeaders(AUTH.PROXY_AUTH_RESP);
} else {
break;
}
} else {
break;
}
}
final int status = response.getStatusLine().getStatusCode();
if (status > 299) {
// Buffer response content
final HttpEntity entity = response.getEntity();
if (entity != null) {
response.setEntity(new BufferedHttpEntity(entity));
}
conn.close();
throw new TunnelRefusedException("CONNECT refused by proxy: " +
response.getStatusLine(), response);
}
return conn.getSocket();
}