Provide a mechanism for easily configuring global client HTTP request factory settings
We use ClientHttpRequestFactorySettings when creating RestTemplateBuilder, RestClient.Builder, and indirectly TestRestTemplate. It would be useful to have a mechanism for changing the settings for each of these three usages in a single place, perhaps by using configuration properties. In addition to those settings, it should also be possible specify the type of ClientHttpRequestFactory to use. This would be useful when you want to override the class path-based auto-detection.
We think that the ability to easily specify the ClientHttpRequestFactory is a prerequisite for adding the new JdkClientHttpRequestFactory to the auto-detection due to it always being available yet behaving differently to SimpleClientHttpRequestFactory.
Hi @wilkinsona, possible first-timer contribution here! Do you mind I pick this issue up?
Also, would it be better for the auto-configuration to provide a bean for the ClientHttpRequestFactorySettings with the added field to define the ClientHttpRequestFactory to use or to provide the ClientHttpRequestFactory itself and maintain the ClientHttpRequestFactorySettings structure as is?
Thanks for the offer, @be0x74a, but we're not exactly sure what we want to do here just yet. I probably should have labelled the issue as pending design work when I opened it. I've done that now.
Ah alright, thanks for letting me know @wilkinsona! Will keep an eye on it, for when it gets decided
I did something similar to this in the new Spring Cloud Gateway MVC Server
GatewayMvcProperties.HttpClient properties = gatewayMvcProperties.getHttpClient();
SslBundle sslBundle = null;
if (StringUtils.hasText(properties.getSslBundle())) {
sslBundle = sslBundles.getBundle(properties.getSslBundle());
}
ClientHttpRequestFactorySettings settings = new ClientHttpRequestFactorySettings(properties.getConnectTimeout(),
properties.getReadTimeout(), sslBundle);
if (properties.getType() == GatewayMvcProperties.HttpClientType.JDK) {
// TODO: customize restricted headers
String restrictedHeaders = System.getProperty("jdk.httpclient.allowRestrictedHeaders");
if (!StringUtils.hasText(restrictedHeaders)) {
System.setProperty("jdk.httpclient.allowRestrictedHeaders", "host");
}
else if (StringUtils.hasText(restrictedHeaders) && !restrictedHeaders.contains("host")) {
System.setProperty("jdk.httpclient.allowRestrictedHeaders", restrictedHeaders + ",host");
}
return ClientHttpRequestFactories.get(JdkClientHttpRequestFactory.class, settings);
}
// Autodetect
return ClientHttpRequestFactories.get(settings);
https://github.com/spring-cloud/spring-cloud-gateway/blob/5202c773fd796e7f5efbeea461854bfb91e561f6/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/GatewayServerMvcAutoConfiguration.java#L73-L96
I stumbled upon this issue because I was wondering why ClientHttpRequestFactories.get(ClientHttpRequestFactorySettings) still returns SimpleClientHttpRequestFactory instead of JdkClientHttpRequestFactory by default. And I just wanted to mention that ClientHttpRequestFactories is also used in HttpWebServiceMessageSenderBuilder.