private MutableTriple setupClient()

in src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/sampler/HTTPHC4Impl.java [1056:1182]


    private MutableTriple<CloseableHttpClient, AuthState, PoolingHttpClientConnectionManager> setupClient(HttpClientKey key, JMeterVariables jMeterVariables,
            HttpClientContext clientContext) throws GeneralSecurityException {
        Map<HttpClientKey, MutableTriple<CloseableHttpClient, AuthState, PoolingHttpClientConnectionManager>> mapHttpClientPerHttpClientKey =
                HTTPCLIENTS_CACHE_PER_THREAD_AND_HTTPCLIENTKEY.get();
        clientContext.setAttribute(CONTEXT_ATTRIBUTE_CLIENT_KEY, key);
        CloseableHttpClient httpClient = null;
        MutableTriple<CloseableHttpClient, AuthState, PoolingHttpClientConnectionManager> triple = null;
        boolean concurrentDwn = this.testElement.isConcurrentDwn();
        Map<String, Object> samplerContext = JMeterContextService.getContext().getSamplerContext();
        if(concurrentDwn) {
            triple = (MutableTriple<CloseableHttpClient, AuthState, PoolingHttpClientConnectionManager>)
                    samplerContext.get(CONTEXT_ATTRIBUTE_PARENT_SAMPLE_CLIENT_STATE);
        }
        if (triple == null) {
            triple = mapHttpClientPerHttpClientKey.get(key);
        }

        if(triple != null) {
            httpClient = triple.getLeft();
        }
        setupProxyAuthState(triple, clientContext);
        resetStateIfNeeded(triple, jMeterVariables, clientContext, mapHttpClientPerHttpClientKey);

        if (httpClient == null) { // One-time init for this client
            DnsResolver resolver = this.testElement.getDNSResolver();
            if (resolver == null) {
                resolver = SystemDefaultDnsResolver.INSTANCE;
            }
            Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory> create().
                    register("https", new LazyLayeredConnectionSocketFactory()).
                    register("http", CONNECTION_SOCKET_FACTORY).
                    build();

            // Modern browsers use more connections per host than the current httpclient default (2)
            // when using parallel download the httpclient and connection manager are shared by the downloads threads
            // to be realistic JMeter must set an higher value to DefaultMaxPerRoute
            PoolingHttpClientConnectionManager pHCCM =
                    new PoolingHttpClientConnectionManager(
                            new JMeterDefaultHttpClientConnectionOperator(registry, null, resolver),
                            null, TIME_TO_LIVE, TimeUnit.MILLISECONDS);
            pHCCM.setValidateAfterInactivity(VALIDITY_AFTER_INACTIVITY_TIMEOUT);

            if(concurrentDwn) {
                try {
                    int maxConcurrentDownloads = Integer.parseInt(this.testElement.getConcurrentPool());
                    pHCCM.setDefaultMaxPerRoute(Math.max(maxConcurrentDownloads, pHCCM.getDefaultMaxPerRoute()));
                } catch (NumberFormatException nfe) {
                   // no need to log -> will be done by the sampler
                }
            }

            CookieSpecProvider cookieSpecProvider = new IgnoreSpecProvider();
            Lookup<CookieSpecProvider> cookieSpecRegistry = RegistryBuilder.<CookieSpecProvider>create()
                    .register(CookieSpecs.IGNORE_COOKIES, cookieSpecProvider)
                    .build();

            HttpClientBuilder builder = HttpClients.custom().setConnectionManager(pHCCM).
                    setSchemePortResolver(new DefaultSchemePortResolver()).
                    setDnsResolver(resolver).
                    setRequestExecutor(REQUEST_EXECUTOR).
                    setSSLSocketFactory(new LazyLayeredConnectionSocketFactory()).
                    setDefaultCookieSpecRegistry(cookieSpecRegistry).
                    setDefaultSocketConfig(SocketConfig.DEFAULT).
                    setRedirectStrategy(new LaxRedirectStrategy()).
                    setConnectionTimeToLive(TIME_TO_LIVE, TimeUnit.MILLISECONDS).
                    setRetryHandler(new StandardHttpRequestRetryHandler(RETRY_COUNT, REQUEST_SENT_RETRY_ENABLED)).
                    setConnectionReuseStrategy(DefaultClientConnectionReuseStrategy.INSTANCE).
                    setProxyAuthenticationStrategy(getProxyAuthStrategy());
            if(DISABLE_DEFAULT_UA) {
                builder.disableDefaultUserAgent();
            }
            Lookup<AuthSchemeProvider> authSchemeRegistry =
                    RegistryBuilder.<AuthSchemeProvider>create()
                        .register(AuthSchemes.BASIC, new BasicSchemeFactory())
                        .register(AuthSchemes.DIGEST, new DigestSchemeFactory())
                        .register(AuthSchemes.NTLM, new NTLMSchemeFactory())
                        .register(AuthSchemes.SPNEGO, new DynamicSPNegoSchemeFactory(
                                AuthManager.STRIP_PORT, AuthManager.USE_CANONICAL_HOST_NAME))
                        .register(AuthSchemes.KERBEROS, new DynamicKerberosSchemeFactory(
                                AuthManager.STRIP_PORT, AuthManager.USE_CANONICAL_HOST_NAME))
                        .build();
            builder.setDefaultAuthSchemeRegistry(authSchemeRegistry);

            if (IDLE_TIMEOUT > 0) {
                builder.setKeepAliveStrategy(IDLE_STRATEGY);
            }

            // Set up proxy details
            AuthScope proxyAuthScope = null;
            NTCredentials proxyCredentials = null;
            if (key.hasProxy) {
                HttpHost proxy = new HttpHost(key.proxyHost, key.proxyPort, key.proxyScheme);
                builder.setProxy(proxy);

                CredentialsProvider credsProvider = new BasicCredentialsProvider();
                if (!key.proxyUser.isEmpty()) {
                    proxyAuthScope = new AuthScope(key.proxyHost, key.proxyPort);
                    proxyCredentials = new NTCredentials(key.proxyUser, key.proxyPass, LOCALHOST, PROXY_DOMAIN);
                    credsProvider.setCredentials(
                            proxyAuthScope,
                            proxyCredentials);
                }
                builder.setDefaultCredentialsProvider(credsProvider);
            }
            builder.disableContentCompression().addInterceptorLast(RESPONSE_CONTENT_ENCODING);
            if(BASIC_AUTH_PREEMPTIVE) {
                builder.addInterceptorFirst(PREEMPTIVE_AUTH_INTERCEPTOR);
            } else {
                builder.setDefaultCredentialsProvider(new ManagedCredentialsProvider(getAuthManager(), proxyAuthScope, proxyCredentials));
            }
            httpClient = builder.build();
            if (log.isDebugEnabled()) {
                log.debug("Created new HttpClient: @{} {}", System.identityHashCode(httpClient), key);
            }
            triple = MutableTriple.of(httpClient, null, pHCCM);
            mapHttpClientPerHttpClientKey.put(key, triple); // save the agent for next time round
        } else {
            if (log.isDebugEnabled()) {
                log.debug("Reusing the HttpClient: @{} {}", System.identityHashCode(httpClient),key);
            }
        }

        if(concurrentDwn) {
            samplerContext.put(CONTEXT_ATTRIBUTE_PARENT_SAMPLE_CLIENT_STATE, triple);
        }
        return triple;
    }