in httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/HttpClientBuilder.java [728:1006]
public CloseableHttpClient build() {
// Create main request executor
// We copy the instance fields to avoid changing them, and rename to avoid accidental use of the wrong version
HttpRequestExecutor requestExecCopy = this.requestExec;
if (requestExecCopy == null) {
requestExecCopy = new HttpRequestExecutor();
}
HttpClientConnectionManager connManagerCopy = this.connManager;
if (connManagerCopy == null) {
connManagerCopy = PoolingHttpClientConnectionManagerBuilder.create().build();
}
ConnectionReuseStrategy reuseStrategyCopy = this.reuseStrategy;
if (reuseStrategyCopy == null) {
if (systemProperties) {
final String s = System.getProperty("http.keepAlive", "true");
if ("true".equalsIgnoreCase(s)) {
reuseStrategyCopy = DefaultClientConnectionReuseStrategy.INSTANCE;
} else {
reuseStrategyCopy = (request, response, context) -> false;
}
} else {
reuseStrategyCopy = DefaultClientConnectionReuseStrategy.INSTANCE;
}
}
ConnectionKeepAliveStrategy keepAliveStrategyCopy = this.keepAliveStrategy;
if (keepAliveStrategyCopy == null) {
keepAliveStrategyCopy = DefaultConnectionKeepAliveStrategy.INSTANCE;
}
AuthenticationStrategy targetAuthStrategyCopy = this.targetAuthStrategy;
if (targetAuthStrategyCopy == null) {
targetAuthStrategyCopy = DefaultAuthenticationStrategy.INSTANCE;
}
AuthenticationStrategy proxyAuthStrategyCopy = this.proxyAuthStrategy;
if (proxyAuthStrategyCopy == null) {
proxyAuthStrategyCopy = DefaultAuthenticationStrategy.INSTANCE;
}
UserTokenHandler userTokenHandlerCopy = this.userTokenHandler;
if (userTokenHandlerCopy == null) {
if (!connectionStateDisabled) {
userTokenHandlerCopy = DefaultUserTokenHandler.INSTANCE;
} else {
userTokenHandlerCopy = NoopUserTokenHandler.INSTANCE;
}
}
String userAgentCopy = this.userAgent;
if (userAgentCopy == null) {
if (systemProperties) {
userAgentCopy = System.getProperty("http.agent");
}
if (userAgentCopy == null && !defaultUserAgentDisabled) {
userAgentCopy = VersionInfo.getSoftwareInfo("Apache-HttpClient",
"org.apache.hc.client5", getClass());
}
}
final HttpProcessorBuilder b = HttpProcessorBuilder.create();
if (requestInterceptors != null) {
for (final RequestInterceptorEntry entry: requestInterceptors) {
if (entry.position == RequestInterceptorEntry.Position.FIRST) {
b.addFirst(entry.interceptor);
}
}
}
if (responseInterceptors != null) {
for (final ResponseInterceptorEntry entry: responseInterceptors) {
if (entry.position == ResponseInterceptorEntry.Position.FIRST) {
b.addFirst(entry.interceptor);
}
}
}
b.addAll(
new RequestDefaultHeaders(defaultHeaders),
new RequestContent(),
new RequestTargetHost(),
new RequestClientConnControl(),
new RequestUserAgent(userAgentCopy),
new RequestExpectContinue());
if (!cookieManagementDisabled) {
b.add(RequestAddCookies.INSTANCE);
}
if (!cookieManagementDisabled) {
b.add(ResponseProcessCookies.INSTANCE);
}
if (requestInterceptors != null) {
for (final RequestInterceptorEntry entry: requestInterceptors) {
if (entry.position == RequestInterceptorEntry.Position.LAST) {
b.addLast(entry.interceptor);
}
}
}
if (responseInterceptors != null) {
for (final ResponseInterceptorEntry entry: responseInterceptors) {
if (entry.position == ResponseInterceptorEntry.Position.LAST) {
b.addLast(entry.interceptor);
}
}
}
final HttpProcessor httpProcessor = b.build();
final NamedElementChain<ExecChainHandler> execChainDefinition = new NamedElementChain<>();
execChainDefinition.addLast(
new MainClientExec(connManagerCopy, httpProcessor, reuseStrategyCopy, keepAliveStrategyCopy, userTokenHandlerCopy),
ChainElement.MAIN_TRANSPORT.name());
execChainDefinition.addFirst(
new ConnectExec(
reuseStrategyCopy,
new DefaultHttpProcessor(new RequestTargetHost(), new RequestUserAgent(userAgentCopy)),
proxyAuthStrategyCopy,
schemePortResolver != null ? schemePortResolver : DefaultSchemePortResolver.INSTANCE,
authCachingDisabled),
ChainElement.CONNECT.name());
execChainDefinition.addFirst(
new ProtocolExec(
targetAuthStrategyCopy,
proxyAuthStrategyCopy,
schemePortResolver != null ? schemePortResolver : DefaultSchemePortResolver.INSTANCE,
authCachingDisabled),
ChainElement.PROTOCOL.name());
// Add request retry executor, if not disabled
if (!automaticRetriesDisabled) {
HttpRequestRetryStrategy retryStrategyCopy = this.retryStrategy;
if (retryStrategyCopy == null) {
retryStrategyCopy = DefaultHttpRequestRetryStrategy.INSTANCE;
}
execChainDefinition.addFirst(
new HttpRequestRetryExec(retryStrategyCopy),
ChainElement.RETRY.name());
}
HttpRoutePlanner routePlannerCopy = this.routePlanner;
if (routePlannerCopy == null) {
SchemePortResolver schemePortResolverCopy = this.schemePortResolver;
if (schemePortResolverCopy == null) {
schemePortResolverCopy = DefaultSchemePortResolver.INSTANCE;
}
if (proxy != null) {
routePlannerCopy = new DefaultProxyRoutePlanner(proxy, schemePortResolverCopy);
} else if (systemProperties) {
routePlannerCopy = new SystemDefaultRoutePlanner(
schemePortResolverCopy, ProxySelector.getDefault());
} else {
routePlannerCopy = new DefaultRoutePlanner(schemePortResolverCopy);
}
}
if (!contentCompressionDisabled) {
if (contentDecoderMap != null) {
final List<String> encodings = new ArrayList<>(contentDecoderMap.keySet());
final RegistryBuilder<InputStreamFactory> b2 = RegistryBuilder.create();
for (final Map.Entry<String, InputStreamFactory> entry: contentDecoderMap.entrySet()) {
b2.register(entry.getKey(), entry.getValue());
}
final Registry<InputStreamFactory> decoderRegistry = b2.build();
execChainDefinition.addFirst(
new ContentCompressionExec(encodings, decoderRegistry, true),
ChainElement.COMPRESS.name());
} else {
execChainDefinition.addFirst(new ContentCompressionExec(true), ChainElement.COMPRESS.name());
}
}
// Add redirect executor, if not disabled
if (!redirectHandlingDisabled) {
RedirectStrategy redirectStrategyCopy = this.redirectStrategy;
if (redirectStrategyCopy == null) {
redirectStrategyCopy = DefaultRedirectStrategy.INSTANCE;
}
execChainDefinition.addFirst(
new RedirectExec(routePlannerCopy, redirectStrategyCopy),
ChainElement.REDIRECT.name());
}
// Optionally, add connection back-off executor
if (this.backoffManager != null && this.connectionBackoffStrategy != null) {
execChainDefinition.addFirst(new BackoffStrategyExec(this.connectionBackoffStrategy, this.backoffManager),
ChainElement.BACK_OFF.name());
}
if (execInterceptors != null) {
for (final ExecInterceptorEntry entry: execInterceptors) {
switch (entry.position) {
case AFTER:
execChainDefinition.addAfter(entry.existing, entry.interceptor, entry.name);
break;
case BEFORE:
execChainDefinition.addBefore(entry.existing, entry.interceptor, entry.name);
break;
case REPLACE:
execChainDefinition.replace(entry.existing, entry.interceptor);
break;
case FIRST:
execChainDefinition.addFirst(entry.interceptor, entry.name);
break;
case LAST:
// Don't add last, after MainClientExec, as that does not delegate to the chain
// Instead, add the interceptor just before it, making it effectively the last interceptor
execChainDefinition.addBefore(ChainElement.MAIN_TRANSPORT.name(), entry.interceptor, entry.name);
break;
}
}
}
customizeExecChain(execChainDefinition);
NamedElementChain<ExecChainHandler>.Node current = execChainDefinition.getLast();
ExecChainElement execChain = null;
while (current != null) {
execChain = new ExecChainElement(current.getValue(), execChain);
current = current.getPrevious();
}
Lookup<AuthSchemeFactory> authSchemeRegistryCopy = this.authSchemeRegistry;
if (authSchemeRegistryCopy == null) {
authSchemeRegistryCopy = RegistryBuilder.<AuthSchemeFactory>create()
.register(StandardAuthScheme.BASIC, BasicSchemeFactory.INSTANCE)
.register(StandardAuthScheme.DIGEST, DigestSchemeFactory.INSTANCE)
.register(StandardAuthScheme.NTLM, NTLMSchemeFactory.INSTANCE)
.register(StandardAuthScheme.SPNEGO, SPNegoSchemeFactory.DEFAULT)
.register(StandardAuthScheme.KERBEROS, KerberosSchemeFactory.DEFAULT)
.build();
}
Lookup<CookieSpecFactory> cookieSpecRegistryCopy = this.cookieSpecRegistry;
if (cookieSpecRegistryCopy == null) {
cookieSpecRegistryCopy = CookieSpecSupport.createDefault();
}
CookieStore defaultCookieStore = this.cookieStore;
if (defaultCookieStore == null) {
defaultCookieStore = new BasicCookieStore();
}
CredentialsProvider defaultCredentialsProvider = this.credentialsProvider;
if (defaultCredentialsProvider == null) {
if (systemProperties) {
defaultCredentialsProvider = new SystemDefaultCredentialsProvider();
} else {
defaultCredentialsProvider = new BasicCredentialsProvider();
}
}
List<Closeable> closeablesCopy = closeables != null ? new ArrayList<>(closeables) : null;
if (!this.connManagerShared) {
if (closeablesCopy == null) {
closeablesCopy = new ArrayList<>(1);
}
if (evictExpiredConnections || evictIdleConnections) {
if (connManagerCopy instanceof ConnPoolControl) {
final IdleConnectionEvictor connectionEvictor = new IdleConnectionEvictor((ConnPoolControl<?>) connManagerCopy,
maxIdleTime, maxIdleTime);
closeablesCopy.add(() -> {
connectionEvictor.shutdown();
try {
connectionEvictor.awaitTermination(Timeout.ofSeconds(1));
} catch (final InterruptedException interrupted) {
Thread.currentThread().interrupt();
}
});
connectionEvictor.start();
}
}
closeablesCopy.add(connManagerCopy);
}
return new InternalHttpClient(
connManagerCopy,
requestExecCopy,
execChain,
routePlannerCopy,
cookieSpecRegistryCopy,
authSchemeRegistryCopy,
defaultCookieStore,
defaultCredentialsProvider,
defaultRequestConfig != null ? defaultRequestConfig : RequestConfig.DEFAULT,
closeablesCopy);
}