Merge branch '4.1.x'

Closes gh-51767
This commit is contained in:
Andy Wilkinson
2026-09-15 13:30:51 +01:00
4 changed files with 49 additions and 5 deletions
@@ -26,6 +26,7 @@ import org.apache.hc.client5.http.SystemDefaultDnsResolver;
import org.apache.hc.client5.http.async.HttpAsyncClient;
import org.apache.hc.client5.http.config.ConnectionConfig;
import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.cookie.StandardCookieSpec;
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
import org.apache.hc.client5.http.impl.async.HttpAsyncClientBuilder;
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager;
@@ -178,7 +179,7 @@ public final class HttpComponentsHttpAsyncClientBuilder {
.useSystemProperties()
.setRedirectStrategy(HttpComponentsRedirectStrategy.get(settings.redirects()))
.setConnectionManager(createConnectionManager(settings))
.setDefaultRequestConfig(createDefaultRequestConfig());
.setDefaultRequestConfig(createDefaultRequestConfig(settings));
this.customizer.accept(builder);
return builder.build();
}
@@ -211,8 +212,15 @@ public final class HttpComponentsHttpAsyncClientBuilder {
return builder.build();
}
private RequestConfig createDefaultRequestConfig() {
private RequestConfig createDefaultRequestConfig(HttpClientSettings settings) {
RequestConfig.Builder builder = RequestConfig.custom();
if (settings.cookieHandling() != null) {
String cookieSpec = switch (settings.cookieHandling()) {
case ENABLE_WHEN_POSSIBLE, ENABLE -> StandardCookieSpec.STRICT;
case DISABLE -> StandardCookieSpec.IGNORE;
};
builder.setCookieSpec(cookieSpec);
}
this.defaultRequestConfigCustomizer.accept(builder);
return builder.build();
}
@@ -23,6 +23,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration;
import org.springframework.boot.http.client.HttpClientSettings;
import org.springframework.boot.http.client.HttpCookieHandling;
import org.springframework.boot.http.client.HttpRedirects;
import org.springframework.boot.http.client.InetAddressFilter;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
@@ -52,9 +53,10 @@ class HttpClientAutoConfigurationTests {
void createsHttpClientSettingsFromProperties() {
this.contextRunner
.withPropertyValues("spring.http.clients.redirects=dont-follow", "spring.http.clients.connect-timeout=1s",
"spring.http.clients.read-timeout=2s")
.run((context) -> assertThat(context.getBean(HttpClientSettings.class)).isEqualTo(new HttpClientSettings(
null, HttpRedirects.DONT_FOLLOW, Duration.ofSeconds(1), Duration.ofSeconds(2), null)));
"spring.http.clients.read-timeout=2s", "spring.http.clients.cookie-handling=disable")
.run((context) -> assertThat(context.getBean(HttpClientSettings.class))
.isEqualTo(new HttpClientSettings(HttpCookieHandling.DISABLE, HttpRedirects.DONT_FOLLOW,
Duration.ofSeconds(1), Duration.ofSeconds(2), null)));
}
@Test
@@ -25,15 +25,19 @@ import org.apache.hc.client5.http.HttpRoute;
import org.apache.hc.client5.http.async.HttpAsyncClient;
import org.apache.hc.client5.http.config.ConnectionConfig;
import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.cookie.StandardCookieSpec;
import org.apache.hc.client5.http.impl.async.HttpAsyncClientBuilder;
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
import org.apache.hc.core5.function.Resolver;
import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;
import org.springframework.boot.http.client.HttpClientSettings;
import org.springframework.boot.http.client.HttpComponentsHttpAsyncClientBuilder;
import org.springframework.boot.http.client.HttpCookieHandling;
import org.springframework.boot.http.client.InetAddressFilter;
import org.springframework.boot.ssl.SslBundle;
import org.springframework.boot.testsupport.classpath.resources.WithPackageResources;
@@ -129,6 +133,28 @@ class HttpComponentsClientHttpConnectorBuilderTests
.isSameAs(dnsResolver);
}
@Test
void defaultCookieHandling() {
HttpComponentsClientHttpConnector connector = ClientHttpConnectorBuilder.httpComponents()
.build(HttpClientSettings.defaults());
assertThat(connector).extracting("client.defaultConfig.cookieSpec").isNull();
}
@Test
void cookieHandlingDisabled() {
HttpComponentsClientHttpConnector connector = ClientHttpConnectorBuilder.httpComponents()
.build(HttpClientSettings.defaults().withCookieHandling(HttpCookieHandling.DISABLE));
assertThat(connector).extracting("client.defaultConfig.cookieSpec").isEqualTo(StandardCookieSpec.IGNORE);
}
@ParameterizedTest
@EnumSource(names = { "ENABLE", "ENABLE_WHEN_POSSIBLE" })
void cookieHandlingEnabled(HttpCookieHandling cookieHandling) {
HttpComponentsClientHttpConnector connector = ClientHttpConnectorBuilder.httpComponents()
.build(HttpClientSettings.defaults().withCookieHandling(cookieHandling));
assertThat(connector).extracting("client.defaultConfig.cookieSpec").isEqualTo(StandardCookieSpec.STRICT);
}
@Override
protected long connectTimeout(HttpComponentsClientHttpConnector connector) {
return getConnectorConfig(connector).getConnectTimeout().toMilliseconds();