package org.ovirt.engine.core.uutils.net; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.nio.file.Paths; import java.security.GeneralSecurityException; import java.security.KeyStore; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509TrustManager; import org.apache.commons.lang.StringUtils; public class HttpURLConnectionBuilder { private Boolean verifyHost = true; private Boolean verifyChain = true; private String httpsProtocol = "TLSv1"; private String trustManagerAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); private String trustStore; private String trustStoreType = KeyStore.getDefaultType(); private String trustStorePassword = "changeit"; private Integer connectTimeout; private Integer readTimeout; private URL url; public HttpURLConnectionBuilder() { } public HttpURLConnectionBuilder(URL url) { setURL(url); } public HttpURLConnectionBuilder(String url) { setURL(url); } public HttpURLConnectionBuilder setURL(URL url) { if (url != null && !url.getProtocol().equalsIgnoreCase("http") && !url.getProtocol().equalsIgnoreCase("https")) { throw new IllegalArgumentException(String.format("The URL %1$s does not denote to an HTTP or HTTPS URL", url)); } this.url = url; return this; } public HttpURLConnectionBuilder setURL(String url) { try { setURL(url != null ? new URL(url) : null); } catch (MalformedURLException e) { throw new IllegalArgumentException(String.format("%1$s is not a valid URL", url)); } return this; } public HttpURLConnectionBuilder setVerifyHost(Boolean verifyHost) { this.verifyHost = verifyHost; return this; } public HttpURLConnectionBuilder setVerifyChain(Boolean verifyChain) { this.verifyChain = verifyChain; return this; } public HttpURLConnectionBuilder setHttpsProtocol(String httpsProtocol) { this.httpsProtocol = httpsProtocol; return this; } public HttpURLConnectionBuilder setTrustManagerAlgorithm(String trustManagerAlgorithm) { this.trustManagerAlgorithm = trustManagerAlgorithm; return this; } public HttpURLConnectionBuilder setTrustStore(String trustStore) { this.trustStore = trustStore; return this; } public HttpURLConnectionBuilder setTrustStoreType(String trustStoreType) { this.trustStoreType = trustStoreType; return this; } public HttpURLConnectionBuilder setTrustStorePassword(String trustStorePassword) { this.trustStorePassword = trustStorePassword; return this; } public HttpURLConnectionBuilder setConnectTimeout(Integer connectTimeout) { this.connectTimeout = connectTimeout; return this; } public HttpURLConnectionBuilder setReadTimeout(Integer readTimeout) { this.readTimeout = readTimeout; return this; } public HttpURLConnectionBuilder appendRelativePath(URL url, String relativePath) throws MalformedURLException { this.url = new URL(url.getProtocol(), url.getHost(), url.getPort() == -1 ? url.getDefaultPort() : url.getPort(), Paths.get(url.getPath(), relativePath).toString()); return this; } public HttpURLConnection create() throws IOException, GeneralSecurityException { URLConnection connection = url.openConnection(); connection.setAllowUserInteraction(false); connection.setUseCaches(false); if (connectTimeout != null) { connection.setConnectTimeout(connectTimeout); } if (readTimeout != null) { connection.setReadTimeout(readTimeout); } if (connection instanceof HttpsURLConnection) { HttpsURLConnection httpsConnection = (HttpsURLConnection) connection; TrustManager[] tm = null; if (verifyChain) { if (trustStore != null) { try (InputStream is = new FileInputStream(trustStore)) { KeyStore ks = KeyStore.getInstance(trustStoreType); ks.load(is, StringUtils.isEmpty(trustStorePassword) ? null : trustStorePassword.toCharArray()); TrustManagerFactory tmf = TrustManagerFactory.getInstance(trustManagerAlgorithm); tmf.init(ks); tm = tmf.getTrustManagers(); } } } else { tm = new TrustManager[] { new X509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return new java.security.cert.X509Certificate[] {}; } public void checkClientTrusted( java.security.cert.X509Certificate[] certs, String authType) { } public void checkServerTrusted( java.security.cert.X509Certificate[] certs, String authType) { } } }; } SSLContext sslContext = SSLContext.getInstance(httpsProtocol); sslContext.init(null, tm, null); httpsConnection.setSSLSocketFactory(sslContext.getSocketFactory()); if (!verifyHost) { httpsConnection.setHostnameVerifier( (hostname, session) -> true ); } } return (HttpURLConnection) connection; } }