protected void setupConnection()

in rt/transports/http/src/main/java/org/apache/cxf/transport/http/HttpClientHTTPConduit.java [310:458]


    protected void setupConnection(Message message, Address address, HTTPClientPolicy csPolicy) throws IOException {
        URI uri = address.getURI();
        message.put("http.scheme", uri.getScheme());
        // check tlsClientParameters from message header
        TLSClientParameters clientParameters = message.get(TLSClientParameters.class);
        if (clientParameters == null) {
            clientParameters = tlsClientParameters;
        }
        if (clientParameters == null) {
            clientParameters = new TLSClientParameters();
        }
        Object o = message.getContextualProperty(FORCE_URLCONNECTION_HTTP_CONDUIT);
        if (o == null) {
            o = message.get("USING_URLCONNECTION");
        }
        //o = true;
        if ("https".equals(uri.getScheme()) && clientParameters != null) {
            if (clientParameters.getSSLSocketFactory() != null) {
                //if they configured in an SSLSocketFactory, we cannot do anything
                //with it as the NIO based transport cannot use socket created from
                //the SSLSocketFactory.
                o = Boolean.TRUE;
            }
            if (clientParameters.isDisableCNCheck()) {
                if (clientParameters.getSslContext() != null) {
                    // If they specify their own SSLContext, we cannot handle the
                    // HostnameVerifier so we'll need to use the URLConnection
                    o = Boolean.TRUE;
                }
                if (clientParameters.getTrustManagers() != null
                    && JavaUtils.getJavaMajorVersion() < 14) {
                    // trustmanagers hacks don't work on Java11
                    o = Boolean.TRUE;
                }
            }
        }
        if (Boolean.TRUE.equals(o)) {
            message.put("USING_URLCONNECTION", Boolean.TRUE);
            super.setupConnection(message, address, csPolicy);
            return;
        }

        if (sslURL != null && isSslTargetDifferent(sslURL, uri)) {
            sslURL = null;
            if (clientRef != null) {
                clientRef.release();
                clientRef = null;
            }
        }
        // If the HTTP_REQUEST_METHOD is not set, the default is "POST".
        String httpRequestMethod =
            (String)message.get(Message.HTTP_REQUEST_METHOD);
        if (httpRequestMethod == null) {
            httpRequestMethod = "POST";
            message.put(Message.HTTP_REQUEST_METHOD, "POST");
        }

        RefCount<HttpClient> cl = clientRef;
        if (cl == null) {
            int ctimeout = determineConnectionTimeout(message, csPolicy);
            ProxySelector ps = new ProxyFactoryProxySelector(proxyFactory, csPolicy);

            HttpClient.Builder cb = HttpClient.newBuilder()
                .proxy(ps)
                .followRedirects(Redirect.NEVER);

            if (ctimeout > 0) {
                cb.connectTimeout(Duration.ofMillis(ctimeout));
            }

            if ("https".equals(uri.getScheme())) {
                sslURL = uri;
                try {
                    SSLContext sslContext = clientParameters.getSslContext();
                    if (sslContext == null) {
                        sslContext = SSLUtils.getSSLContext(clientParameters, true);
                        cb.sslContext(sslContext);
                    }
                    if (sslContext != null) {
                        cb.sslContext(sslContext);
                        String[] supportedCiphers =  org.apache.cxf.configuration.jsse.SSLUtils
                                .getSupportedCipherSuites(sslContext);
                        String[] cipherSuites = org.apache.cxf.configuration.jsse.SSLUtils
                                .getCiphersuitesToInclude(clientParameters.getCipherSuites(),
                                                          clientParameters.getCipherSuitesFilter(),
                                                          sslContext.getSocketFactory().getDefaultCipherSuites(),
                                                          supportedCiphers,
                                                          LOG);

                        if (clientParameters.getSecureSocketProtocol() != null) {
                            String protocol = clientParameters.getSecureSocketProtocol();
                            SSLParameters params = new SSLParameters(cipherSuites, new String[] {protocol});
                            cb.sslParameters(params);
                        } else {
                            final SSLParameters params = new SSLParameters(cipherSuites,
                                TLSClientParameters.getPreferredClientProtocols());
                            cb.sslParameters(params);
                        }
                    }
                } catch (GeneralSecurityException e) {
                    throw new IOException(e);
                }
            }
            String verc = (String)message.getContextualProperty(FORCE_HTTP_VERSION);
            if (verc == null) {
                verc = csPolicy.getVersion();
            }
            if ("1.1".equals(HTTP_VERSION) || "1.1".equals(verc)) {
                cb.version(Version.HTTP_1_1);
            }

            // make sure the conduit is not yet initialized
            initializationLock.lock();
            try {
                cl = clientRef;
                if (cl == null) {
                    final boolean shareHttpClient = MessageUtils.getContextualBoolean(message,
                        SHARE_HTTPCLIENT_CONDUIT, true);
                    cl = CLIENTS_CACHE.computeIfAbsent(shareHttpClient, csPolicy, clientParameters, () -> cb.build());

                    if (!"https".equals(uri.getScheme())
                        && !KNOWN_HTTP_VERBS_WITH_NO_CONTENT.contains(httpRequestMethod)
                        && cl.client().version() == Version.HTTP_2
                        && ("2".equals(verc) || ("auto".equals(verc) && "2".equals(HTTP_VERSION)))) {
                        try {
                            // We specifically want HTTP2, but we're using a request
                            // that won't trigger an upgrade to HTTP/2 so we'll
                            // call OPTIONS on the URI which may trigger HTTP/2 upgrade.
                            // Not needed for methods that don't have a body (GET/HEAD/etc...)
                            // or for https (negotiated at the TLS level)
                            HttpRequest.Builder rb = HttpRequest.newBuilder()
                                .uri(uri)
                                .method("OPTIONS", BodyPublishers.noBody());
                            cl.client().send(rb.build(), BodyHandlers.ofByteArray());
                        } catch (IOException | InterruptedException e) {
                            //
                        }
                    }

                    clientRef = cl;
                }
            } finally {
                initializationLock.unlock();
            }
        }
        message.put(HttpClient.class, cl.client());

        message.put(KEY_HTTP_CONNECTION_ADDRESS, address);
    }