11package com .clickhouse .client .api .internal ;
22
33import com .clickhouse .client .ClickHouseNode ;
4+ import com .clickhouse .client .ClickHouseSslContextProvider ;
45import com .clickhouse .client .api .Client ;
56import com .clickhouse .client .api .ClientException ;
67import com .clickhouse .client .api .ClientMisconfigurationException ;
78import com .clickhouse .client .api .ServerException ;
89import com .clickhouse .client .api .enums .ProxyType ;
910import com .clickhouse .client .config .ClickHouseClientOption ;
11+ import com .clickhouse .client .config .ClickHouseDefaults ;
1012import com .clickhouse .client .http .ApacheHttpConnectionImpl ;
1113import com .clickhouse .client .http .ClickHouseHttpProto ;
1214import com .clickhouse .client .http .config .ClickHouseHttpOption ;
3436import org .apache .hc .core5 .http .io .entity .EntityTemplate ;
3537import org .apache .hc .core5 .io .IOCallback ;
3638import org .apache .hc .core5 .net .URIBuilder ;
39+ import org .apache .hc .core5 .ssl .SSLContexts ;
3740import org .slf4j .Logger ;
3841import org .slf4j .LoggerFactory ;
3942
4043import javax .net .ssl .HostnameVerifier ;
4144import javax .net .ssl .SSLContext ;
45+ import javax .net .ssl .SSLException ;
4246import javax .net .ssl .SSLSocketFactory ;
4347import java .io .ByteArrayOutputStream ;
48+ import java .io .FileInputStream ;
4449import java .io .IOException ;
50+ import java .io .InputStream ;
4551import java .io .OutputStream ;
4652import java .net .ConnectException ;
4753import java .net .InetSocketAddress ;
4854import java .net .NoRouteToHostException ;
4955import java .net .URI ;
5056import java .net .URISyntaxException ;
57+ import java .net .URL ;
5158import java .net .UnknownHostException ;
59+ import java .security .KeyStore ;
60+ import java .security .cert .Certificate ;
61+ import java .security .cert .CertificateFactory ;
5262import java .util .Base64 ;
5363import java .util .EnumSet ;
5464import java .util .Map ;
@@ -80,27 +90,67 @@ public HttpAPIClientHelper(Map<String, String> configuration) {
8090 }
8191
8292 public CloseableHttpClient createHttpClient () {
93+
94+ // Top Level builders
8395 HttpClientBuilder clientBuilder = HttpClientBuilder .create ();
84- CredentialsProviderBuilder credProviderBuilder = CredentialsProviderBuilder .create ();
85- SocketConfig .Builder soCfgBuilder = SocketConfig .custom ();
86- PoolingHttpClientConnectionManagerBuilder connMgrBuilder = PoolingHttpClientConnectionManagerBuilder .create ();
8796
8897
98+ // Socket configuration
99+ SocketConfig .Builder soCfgBuilder = SocketConfig .custom ();
89100 MapUtils .applyInt (chConfiguration , ClickHouseClientOption .SOCKET_TIMEOUT .getKey (),
90101 (t ) -> soCfgBuilder .setSoTimeout (t , TimeUnit .MILLISECONDS ));
91102 MapUtils .applyInt (chConfiguration , ClickHouseClientOption .SOCKET_RCVBUF .getKey (),
92103 soCfgBuilder ::setRcvBufSize );
93104 MapUtils .applyInt (chConfiguration , ClickHouseClientOption .SOCKET_SNDBUF .getKey (),
94105 soCfgBuilder ::setSndBufSize );
95106
107+
108+ // Connection manager
109+ PoolingHttpClientConnectionManagerBuilder connMgrBuilder = PoolingHttpClientConnectionManagerBuilder .create ();
110+
111+ ClickHouseSslContextProvider sslContextProvider = ClickHouseSslContextProvider .getProvider ();
112+
113+ String trustStorePath = chConfiguration .get (ClickHouseClientOption .TRUST_STORE .getKey ());
114+ SSLContext sslContext = null ;
115+ if (trustStorePath != null ) {
116+ try {
117+ sslContext = sslContextProvider .getSslContextFromKeyStore (
118+ trustStorePath ,
119+ chConfiguration .get (ClickHouseClientOption .KEY_STORE_PASSWORD .getKey ()),
120+ chConfiguration .get (ClickHouseClientOption .KEY_STORE_TYPE .getKey ())
121+ );
122+ } catch (SSLException e ) {
123+ throw new ClientMisconfigurationException ("Failed to create SSL context from a keystore" , e );
124+ }
125+ } else if (chConfiguration .get (ClickHouseClientOption .SSL_ROOT_CERTIFICATE .getKey ()) != null ||
126+ chConfiguration .get (ClickHouseClientOption .SSL_CERTIFICATE .getKey ()) != null ||
127+ chConfiguration .get (ClickHouseClientOption .SSL_KEY .getKey ()) != null ) {
128+
129+ try {
130+ sslContext = sslContextProvider .getSslContextFromCerts (
131+ chConfiguration .get (ClickHouseClientOption .SSL_CERTIFICATE .getKey ()),
132+ chConfiguration .get (ClickHouseClientOption .SSL_KEY .getKey ()),
133+ chConfiguration .get (ClickHouseClientOption .SSL_ROOT_CERTIFICATE .getKey ())
134+ );
135+ } catch (SSLException e ) {
136+ throw new ClientMisconfigurationException ("Failed to create SSL context from certificates" , e );
137+ }
138+ }
139+ if (sslContext !=null ) {
140+ connMgrBuilder .setSSLSocketFactory (new SSLConnectionSocketFactory (sslContext ));
141+ }
142+
143+ connMgrBuilder .setDefaultSocketConfig (soCfgBuilder .build ());
144+ clientBuilder .setConnectionManager (connMgrBuilder .build ());
145+
146+ // Proxy
96147 String proxyHost = chConfiguration .get (ClickHouseClientOption .PROXY_HOST .getKey ());
97148 String proxyPort = chConfiguration .get (ClickHouseClientOption .PROXY_PORT .getKey ());
98149 HttpHost proxy = null ;
99150 if (proxyHost != null && proxyPort != null ) {
100151 proxy = new HttpHost (proxyHost , Integer .parseInt (proxyPort ));
101152 }
102153
103-
104154 String proxyTypeVal = chConfiguration .get (ClickHouseClientOption .PROXY_TYPE .getKey ());
105155 ProxyType proxyType = proxyTypeVal == null ? null : ProxyType .valueOf (proxyTypeVal );
106156 if (proxyType == ProxyType .HTTP ) {
@@ -117,10 +167,7 @@ public CloseableHttpClient createHttpClient() {
117167 .equalsIgnoreCase ("false" )) {
118168 clientBuilder .disableCookieManagement ();
119169 }
120- clientBuilder .setDefaultCredentialsProvider (credProviderBuilder .build ());
121170
122- connMgrBuilder .setDefaultSocketConfig (soCfgBuilder .build ());
123- clientBuilder .setConnectionManager (connMgrBuilder .build ());
124171 return clientBuilder .build ();
125172 }
126173
@@ -211,6 +258,8 @@ private void addHeaders(HttpPost req, Map<String, String> chConfig, Map<String,
211258 }
212259 }
213260 req .addHeader (ClickHouseHttpProto .HEADER_DATABASE , chConfig .get (ClickHouseClientOption .DATABASE .getKey ()));
261+ req .addHeader (ClickHouseHttpProto .HEADER_DB_USER , chConfig .get (ClickHouseDefaults .USER .getKey ()));
262+ req .addHeader (ClickHouseHttpProto .HEADER_DB_PASSWORD , chConfig .get (ClickHouseDefaults .PASSWORD .getKey ()));
214263
215264 if (proxyAuthHeaderValue != null ) {
216265 req .addHeader (HttpHeaders .PROXY_AUTHORIZATION , proxyAuthHeaderValue );
0 commit comments