diff --git a/services/src/main/java/org/keycloak/connections/httpclient/DefaultHttpClientFactory.java b/services/src/main/java/org/keycloak/connections/httpclient/DefaultHttpClientFactory.java index 3a2675af2f0..f98111a26db 100755 --- a/services/src/main/java/org/keycloak/connections/httpclient/DefaultHttpClientFactory.java +++ b/services/src/main/java/org/keycloak/connections/httpclient/DefaultHttpClientFactory.java @@ -61,6 +61,7 @@ import org.apache.http.util.EntityUtils; public class DefaultHttpClientFactory implements HttpClientFactory { private static final Logger logger = Logger.getLogger(DefaultHttpClientFactory.class); + private static final String configScope = "keycloak.connectionsHttpClient.default."; private volatile CloseableHttpClient httpClient; private Config.Scope config; @@ -146,7 +147,10 @@ public class DefaultHttpClientFactory implements HttpClientFactory { String clientPrivateKeyPassword = config.get("client-key-password"); String[] proxyMappings = config.getArray("proxy-mappings"); boolean disableTrustManager = config.getBoolean("disable-trust-manager", false); - + + boolean expectContinueEnabled = getBooleanConfigWithSysPropFallback("expect-continue-enabled", false); + boolean resuseConnections = getBooleanConfigWithSysPropFallback("reuse-connections", true); + HttpClientBuilder builder = new HttpClientBuilder(); builder.socketTimeout(socketTimeout, TimeUnit.MILLISECONDS) @@ -157,7 +161,9 @@ public class DefaultHttpClientFactory implements HttpClientFactory { .connectionTTL(connectionTTL, TimeUnit.MILLISECONDS) .maxConnectionIdleTime(maxConnectionIdleTime, TimeUnit.MILLISECONDS) .disableCookies(disableCookies) - .proxyMappings(ProxyMappings.valueOf(proxyMappings)); + .proxyMappings(ProxyMappings.valueOf(proxyMappings)) + .expectContinueEnabled(expectContinueEnabled) + .reuseConnections(resuseConnections); TruststoreProvider truststoreProvider = session.getProvider(TruststoreProvider.class); boolean disableTruststoreProvider = truststoreProvider == null || truststoreProvider.getTruststore() == null; @@ -198,6 +204,15 @@ public class DefaultHttpClientFactory implements HttpClientFactory { } - + private boolean getBooleanConfigWithSysPropFallback(String key, boolean defaultValue) { + Boolean value = config.getBoolean(key); + if (value == null) { + String s = System.getProperty(configScope + key); + if (s != null) { + value = Boolean.parseBoolean(s); + } + } + return value != null ? value : defaultValue; + } } diff --git a/services/src/main/java/org/keycloak/connections/httpclient/HttpClientBuilder.java b/services/src/main/java/org/keycloak/connections/httpclient/HttpClientBuilder.java index 23acc2a9d3f..40cc6c3150c 100755 --- a/services/src/main/java/org/keycloak/connections/httpclient/HttpClientBuilder.java +++ b/services/src/main/java/org/keycloak/connections/httpclient/HttpClientBuilder.java @@ -107,6 +107,7 @@ public class HttpClientBuilder { protected TimeUnit establishConnectionTimeoutUnits = TimeUnit.MILLISECONDS; protected boolean disableCookies = false; protected ProxyMappings proxyMappings; + protected boolean expectContinueEnabled = false; /** * Socket inactivity timeout @@ -220,6 +221,10 @@ public class HttpClientBuilder { return this; } + public HttpClientBuilder expectContinueEnabled(boolean expectContinueEnabled) { + this.expectContinueEnabled = expectContinueEnabled; + return this; + } static class VerifierWrapper implements X509HostnameVerifier { protected HostnameVerifier verifier; @@ -287,7 +292,8 @@ public class HttpClientBuilder { RequestConfig requestConfig = RequestConfig.custom() .setConnectTimeout((int) establishConnectionTimeout) - .setSocketTimeout((int) socketTimeout).build(); + .setSocketTimeout((int) socketTimeout) + .setExpectContinueEnabled(expectContinueEnabled).build(); org.apache.http.impl.client.HttpClientBuilder builder = HttpClients.custom() .setDefaultRequestConfig(requestConfig) @@ -310,6 +316,11 @@ public class HttpClientBuilder { } if (disableCookies) builder.disableCookieManagement(); + + if (!reuseConnections) { + builder.setConnectionReuseStrategy(new NoConnectionReuseStrategy()); + } + return builder.build(); } catch (Exception e) { throw new RuntimeException(e);