Skip to content

Commit 8ca8ab1

Browse files
committed
Add withRequestFactorySettings method and restore previous defaults
Update `TestRestTemplate` with a `withRequestFactorySettings` method that can be used to change defaults such as `Redirects`. This commit also restores the previous redirect defaults for HTTP components where redirects would only be followed when the `HttpClientOption.ENABLE_REDIRECTS` was specified. Closes gh-43258
1 parent efee347 commit 8ca8ab1

File tree

2 files changed

+67
-19
lines changed

2 files changed

+67
-19
lines changed

spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/TestRestTemplate.java

Lines changed: 45 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@
2222
import java.security.NoSuchAlgorithmException;
2323
import java.security.cert.X509Certificate;
2424
import java.time.Duration;
25-
import java.util.Arrays;
26-
import java.util.HashSet;
2725
import java.util.Map;
2826
import java.util.Set;
2927
import java.util.concurrent.TimeUnit;
@@ -60,6 +58,7 @@
6058
import org.springframework.http.client.ClientHttpRequestFactory;
6159
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
6260
import org.springframework.util.Assert;
61+
import org.springframework.util.ObjectUtils;
6362
import org.springframework.web.client.NoOpResponseErrorHandler;
6463
import org.springframework.web.client.RequestCallback;
6564
import org.springframework.web.client.ResponseExtractor;
@@ -100,8 +99,6 @@ public class TestRestTemplate {
10099

101100
private final RestTemplateBuilder builder;
102101

103-
private final HttpClientOption[] httpClientOptions;
104-
105102
private final RestTemplate restTemplate;
106103

107104
/**
@@ -142,21 +139,34 @@ public TestRestTemplate(String username, String password, HttpClientOption... ht
142139
*/
143140
public TestRestTemplate(RestTemplateBuilder builder, String username, String password,
144141
HttpClientOption... httpClientOptions) {
145-
Assert.notNull(builder, "Builder must not be null");
142+
this(createInitialBuilder(builder, username, password, httpClientOptions), null);
143+
}
144+
145+
private TestRestTemplate(RestTemplateBuilder builder, UriTemplateHandler uriTemplateHandler) {
146146
this.builder = builder;
147-
this.httpClientOptions = httpClientOptions;
147+
this.restTemplate = builder.build();
148+
if (uriTemplateHandler != null) {
149+
this.restTemplate.setUriTemplateHandler(uriTemplateHandler);
150+
}
151+
this.restTemplate.setErrorHandler(new NoOpResponseErrorHandler());
152+
}
153+
154+
private static RestTemplateBuilder createInitialBuilder(RestTemplateBuilder builder, String username,
155+
String password, HttpClientOption... httpClientOptions) {
156+
Assert.notNull(builder, "Builder must not be null");
148157
if (httpClientOptions != null) {
149158
ClientHttpRequestFactory requestFactory = builder.buildRequestFactory();
150159
if (requestFactory instanceof HttpComponentsClientHttpRequestFactory) {
160+
builder = builder.redirects(HttpClientOption.ENABLE_REDIRECTS.isPresent(httpClientOptions)
161+
? Redirects.FOLLOW : Redirects.DONT_FOLLOW);
151162
builder = builder.requestFactoryBuilder(
152163
(settings) -> new CustomHttpComponentsClientHttpRequestFactory(httpClientOptions, settings));
153164
}
154165
}
155166
if (username != null || password != null) {
156167
builder = builder.basicAuthentication(username, password);
157168
}
158-
this.restTemplate = builder.build();
159-
this.restTemplate.setErrorHandler(new NoOpResponseErrorHandler());
169+
return builder;
160170
}
161171

162172
/**
@@ -943,9 +953,25 @@ public RestTemplate getRestTemplate() {
943953
* @since 1.4.1
944954
*/
945955
public TestRestTemplate withBasicAuth(String username, String password) {
946-
TestRestTemplate template = new TestRestTemplate(this.builder, username, password, this.httpClientOptions);
947-
template.setUriTemplateHandler(getRestTemplate().getUriTemplateHandler());
948-
return template;
956+
if (username == null && password == null) {
957+
return this;
958+
}
959+
return new TestRestTemplate(this.builder.basicAuthentication(username, password),
960+
this.restTemplate.getUriTemplateHandler());
961+
}
962+
963+
/**
964+
* Creates a new {@code TestRestTemplate} with the same configuration as this one,
965+
* except that it will apply the given {@link ClientHttpRequestFactorySettings}. The
966+
* request factory used is a new instance of the underlying {@link RestTemplate}'s
967+
* request factory type (when possible).
968+
* @param requestFactorySettings the new request factory settings
969+
* @return the new template
970+
* @since 3.4.1
971+
*/
972+
public TestRestTemplate withRequestFactorySettings(ClientHttpRequestFactorySettings requestFactorySettings) {
973+
return new TestRestTemplate(this.builder.requestFactorySettings(requestFactorySettings),
974+
this.restTemplate.getUriTemplateHandler());
949975
}
950976

951977
@SuppressWarnings({ "rawtypes", "unchecked" })
@@ -996,7 +1022,11 @@ public enum HttpClientOption {
9961022
/**
9971023
* Use a {@link TlsSocketStrategy} that trusts self-signed certificates.
9981024
*/
999-
SSL
1025+
SSL;
1026+
1027+
boolean isPresent(HttpClientOption[] options) {
1028+
return ObjectUtils.containsElement(options, this);
1029+
}
10001030

10011031
}
10021032

@@ -1031,12 +1061,10 @@ public CustomHttpComponentsClientHttpRequestFactory(HttpClientOption[] httpClien
10311061
*/
10321062
public CustomHttpComponentsClientHttpRequestFactory(HttpClientOption[] httpClientOptions,
10331063
ClientHttpRequestFactorySettings settings) {
1034-
Set<HttpClientOption> options = new HashSet<>(Arrays.asList(httpClientOptions));
1035-
this.cookieSpec = (options.contains(HttpClientOption.ENABLE_COOKIES) ? StandardCookieSpec.STRICT
1064+
this.cookieSpec = (HttpClientOption.ENABLE_COOKIES.isPresent(httpClientOptions) ? StandardCookieSpec.STRICT
10361065
: StandardCookieSpec.IGNORE);
1037-
this.enableRedirects = options.contains(HttpClientOption.ENABLE_REDIRECTS)
1038-
|| settings.redirects() != Redirects.DONT_FOLLOW;
1039-
boolean ssl = options.contains(HttpClientOption.SSL);
1066+
this.enableRedirects = settings.redirects() != Redirects.DONT_FOLLOW;
1067+
boolean ssl = HttpClientOption.SSL.isPresent(httpClientOptions);
10401068
if (settings.readTimeout() != null || ssl) {
10411069
setHttpClient(createHttpClient(settings.readTimeout(), ssl));
10421070
}

spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/TestRestTemplateTests.java

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.junit.jupiter.api.Test;
3030

3131
import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder;
32+
import org.springframework.boot.http.client.ClientHttpRequestFactorySettings;
3233
import org.springframework.boot.http.client.ClientHttpRequestFactorySettings.Redirects;
3334
import org.springframework.boot.test.web.client.TestRestTemplate.CustomHttpComponentsClientHttpRequestFactory;
3435
import org.springframework.boot.test.web.client.TestRestTemplate.HttpClientOption;
@@ -157,15 +158,34 @@ void jdkBuilderCanBeSpecifiedWithSpecificRedirects() {
157158
void httpComponentsAreBuildConsideringSettingsInRestTemplateBuilder() {
158159
RestTemplateBuilder builder = new RestTemplateBuilder()
159160
.requestFactoryBuilder(ClientHttpRequestFactoryBuilder.httpComponents());
160-
assertThat(getRequestConfig((RestTemplateBuilder) null).isRedirectsEnabled()).isTrue();
161+
assertThat(getRequestConfig((RestTemplateBuilder) null).isRedirectsEnabled()).isFalse();
161162
assertThat(getRequestConfig(null, HttpClientOption.ENABLE_REDIRECTS).isRedirectsEnabled()).isTrue();
162-
assertThat(getRequestConfig(builder).isRedirectsEnabled()).isTrue();
163+
assertThat(getRequestConfig(builder).isRedirectsEnabled()).isFalse();
163164
assertThat(getRequestConfig(builder, HttpClientOption.ENABLE_REDIRECTS).isRedirectsEnabled()).isTrue();
164165
assertThat(getRequestConfig(builder.redirects(Redirects.DONT_FOLLOW)).isRedirectsEnabled()).isFalse();
165166
assertThat(getRequestConfig(builder.redirects(Redirects.DONT_FOLLOW), HttpClientOption.ENABLE_REDIRECTS)
166167
.isRedirectsEnabled()).isTrue();
167168
}
168169

170+
@Test
171+
void withSettingsUpdatesRedirectsForHttpComponents() {
172+
TestRestTemplate template = new TestRestTemplate();
173+
assertThat(getRequestConfig(template).isRedirectsEnabled()).isFalse();
174+
assertThat(getRequestConfig(template
175+
.withRequestFactorySettings(ClientHttpRequestFactorySettings.defaults().withRedirects(Redirects.FOLLOW)))
176+
.isRedirectsEnabled()).isTrue();
177+
}
178+
179+
@Test
180+
void withSettingsUpdatesRedirectsForJdk() {
181+
TestRestTemplate template = new TestRestTemplate(
182+
new RestTemplateBuilder().requestFactoryBuilder(ClientHttpRequestFactoryBuilder.jdk()));
183+
assertThat(getJdkHttpClient(template).followRedirects()).isEqualTo(Redirect.NORMAL);
184+
assertThat(getJdkHttpClient(template.withRequestFactorySettings(
185+
ClientHttpRequestFactorySettings.defaults().withRedirects(Redirects.DONT_FOLLOW)))
186+
.followRedirects()).isEqualTo(Redirect.NEVER);
187+
}
188+
169189
private RequestConfig getRequestConfig(RestTemplateBuilder builder, HttpClientOption... httpClientOptions) {
170190
builder = (builder != null) ? builder : new RestTemplateBuilder();
171191
TestRestTemplate template = new TestRestTemplate(builder, null, null, httpClientOptions);

0 commit comments

Comments
 (0)