in httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/H2AsyncClientBuilder.java [652:885]
public CloseableHttpAsyncClient build() {
AuthenticationStrategy targetAuthStrategyCopy = this.targetAuthStrategy;
if (targetAuthStrategyCopy == null) {
targetAuthStrategyCopy = DefaultAuthenticationStrategy.INSTANCE;
}
AuthenticationStrategy proxyAuthStrategyCopy = this.proxyAuthStrategy;
if (proxyAuthStrategyCopy == null) {
proxyAuthStrategyCopy = DefaultAuthenticationStrategy.INSTANCE;
}
String userAgentCopy = this.userAgent;
if (userAgentCopy == null) {
if (systemProperties) {
userAgentCopy = getProperty("http.agent", null);
}
if (userAgentCopy == null) {
userAgentCopy = VersionInfo.getSoftwareInfo("Apache-HttpAsyncClient",
"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 RequestUserAgent(userAgentCopy),
new RequestExpectContinue(),
new H2RequestContent(),
new H2RequestTargetHost(),
new H2RequestConnControl());
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<AsyncExecChainHandler> execChainDefinition = new NamedElementChain<>();
execChainDefinition.addLast(
new H2AsyncMainClientExec(httpProcessor),
ChainElement.MAIN_TRANSPORT.name());
execChainDefinition.addFirst(
new AsyncConnectExec(
new DefaultHttpProcessor(new RequestTargetHost(), new RequestUserAgent(userAgentCopy)),
proxyAuthStrategyCopy,
schemePortResolver != null ? schemePortResolver : DefaultSchemePortResolver.INSTANCE,
authCachingDisabled),
ChainElement.CONNECT.name());
execChainDefinition.addFirst(
new AsyncProtocolExec(
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 AsyncHttpRequestRetryExec(retryStrategyCopy),
ChainElement.RETRY.name());
}
HttpRoutePlanner routePlannerCopy = this.routePlanner;
if (routePlannerCopy == null) {
SchemePortResolver schemePortResolverCopy = this.schemePortResolver;
if (schemePortResolverCopy == null) {
schemePortResolverCopy = DefaultSchemePortResolver.INSTANCE;
}
routePlannerCopy = new DefaultRoutePlanner(schemePortResolverCopy);
}
// Add redirect executor, if not disabled
if (!redirectHandlingDisabled) {
RedirectStrategy redirectStrategyCopy = this.redirectStrategy;
if (redirectStrategyCopy == null) {
redirectStrategyCopy = DefaultRedirectStrategy.INSTANCE;
}
execChainDefinition.addFirst(
new AsyncRedirectExec(routePlannerCopy, redirectStrategyCopy),
ChainElement.REDIRECT.name());
}
final AsyncPushConsumerRegistry pushConsumerRegistry = new AsyncPushConsumerRegistry();
final IOEventHandlerFactory ioEventHandlerFactory = new H2AsyncClientProtocolStarter(
HttpProcessorBuilder.create().build(),
(request, context) -> pushConsumerRegistry.get(request),
h2Config != null ? h2Config : H2Config.DEFAULT,
charCodingConfig != null ? charCodingConfig : CharCodingConfig.DEFAULT);
final DefaultConnectingIOReactor ioReactor = new DefaultConnectingIOReactor(
ioEventHandlerFactory,
ioReactorConfig != null ? ioReactorConfig : IOReactorConfig.DEFAULT,
threadFactory != null ? threadFactory : new DefaultThreadFactory("httpclient-dispatch", true),
ioSessionDecorator != null ? ioSessionDecorator : LoggingIOSessionDecorator.INSTANCE,
ioReactorExceptionCallback != null ? ioReactorExceptionCallback : LoggingExceptionCallback.INSTANCE,
ioSessionListener,
ioSession -> ioSession.enqueue(new ShutdownCommand(CloseMode.GRACEFUL), Command.Priority.IMMEDIATE));
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 H2AsyncMainClientExec, 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<AsyncExecChainHandler>.Node current = execChainDefinition.getLast();
AsyncExecChainElement execChain = null;
while (current != null) {
execChain = new AsyncExecChainElement(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 cookieStoreCopy = this.cookieStore;
if (cookieStoreCopy == null) {
cookieStoreCopy = new BasicCookieStore();
}
CredentialsProvider credentialsProviderCopy = this.credentialsProvider;
if (credentialsProviderCopy == null) {
if (systemProperties) {
credentialsProviderCopy = new SystemDefaultCredentialsProvider();
} else {
credentialsProviderCopy = new BasicCredentialsProvider();
}
}
TlsStrategy tlsStrategyCopy = this.tlsStrategy;
if (tlsStrategyCopy == null) {
if (systemProperties) {
tlsStrategyCopy = DefaultClientTlsStrategy.getSystemDefault();
} else {
tlsStrategyCopy = DefaultClientTlsStrategy.getDefault();
}
}
final MultihomeConnectionInitiator connectionInitiator = new MultihomeConnectionInitiator(ioReactor, dnsResolver);
final InternalH2ConnPool connPool = new InternalH2ConnPool(connectionInitiator, host -> null, tlsStrategyCopy);
connPool.setConnectionConfigResolver(connectionConfigResolver);
List<Closeable> closeablesCopy = closeables != null ? new ArrayList<>(closeables) : null;
if (closeablesCopy == null) {
closeablesCopy = new ArrayList<>(1);
}
if (evictIdleConnections) {
final IdleConnectionEvictor connectionEvictor = new IdleConnectionEvictor(connPool,
maxIdleTime != null ? maxIdleTime : TimeValue.ofSeconds(30L));
closeablesCopy.add(connectionEvictor::shutdown);
connectionEvictor.start();
}
closeablesCopy.add(connPool);
return new InternalH2AsyncClient(
ioReactor,
execChain,
pushConsumerRegistry,
threadFactory != null ? threadFactory : new DefaultThreadFactory("httpclient-main", true),
connPool,
routePlannerCopy,
cookieSpecRegistryCopy,
authSchemeRegistryCopy,
cookieStoreCopy,
credentialsProviderCopy,
defaultRequestConfig,
closeablesCopy);
}