Skip to content

Commit

Permalink
Merge pull request #43258 from quaff
Browse files Browse the repository at this point in the history
* pr/43258:
  Polish 'Add `redirects(...)` method to `RestTemplateBuilder`'
  Add `redirects(...)` method to `RestTemplateBuilder`

Closes gh-43258
  • Loading branch information
philwebb committed Dec 4, 2024
2 parents 916efb6 + 8b83afd commit b7f3627
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
import org.apache.hc.core5.ssl.TrustStrategy;

import org.springframework.boot.http.client.ClientHttpRequestFactorySettings;
import org.springframework.boot.http.client.ClientHttpRequestFactorySettings.Redirects;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.boot.web.client.RootUriTemplateHandler;
import org.springframework.core.ParameterizedTypeReference;
Expand Down Expand Up @@ -92,6 +93,7 @@
* @author Andy Wilkinson
* @author Kristine Jetzke
* @author Dmytro Nosan
* @author Yanming Zhou
* @since 1.4.0
*/
public class TestRestTemplate {
Expand Down Expand Up @@ -1032,7 +1034,8 @@ public CustomHttpComponentsClientHttpRequestFactory(HttpClientOption[] httpClien
Set<HttpClientOption> options = new HashSet<>(Arrays.asList(httpClientOptions));
this.cookieSpec = (options.contains(HttpClientOption.ENABLE_COOKIES) ? StandardCookieSpec.STRICT
: StandardCookieSpec.IGNORE);
this.enableRedirects = options.contains(HttpClientOption.ENABLE_REDIRECTS);
this.enableRedirects = options.contains(HttpClientOption.ENABLE_REDIRECTS)
|| settings.redirects() != Redirects.DONT_FOLLOW;
boolean ssl = options.contains(HttpClientOption.SSL);
if (settings.readTimeout() != null || ssl) {
setHttpClient(createHttpClient(settings.readTimeout(), ssl));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,16 @@
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpClient.Redirect;
import java.util.Base64;
import java.util.stream.Stream;

import org.apache.hc.client5.http.config.RequestConfig;
import org.junit.jupiter.api.Test;

import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder;
import org.springframework.boot.http.client.ClientHttpRequestFactorySettings.Redirects;
import org.springframework.boot.test.web.client.TestRestTemplate.CustomHttpComponentsClientHttpRequestFactory;
import org.springframework.boot.test.web.client.TestRestTemplate.HttpClientOption;
import org.springframework.boot.web.client.RestTemplateBuilder;
Expand All @@ -38,6 +42,7 @@
import org.springframework.http.client.ClientHttpRequest;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.client.JdkClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.mock.env.MockEnvironment;
import org.springframework.mock.http.client.MockClientHttpRequest;
Expand Down Expand Up @@ -66,6 +71,7 @@
* @author Stephane Nicoll
* @author Andy Wilkinson
* @author Kristine Jetzke
* @author Yanming Zhou
*/
class TestRestTemplateTests {

Expand Down Expand Up @@ -131,12 +137,53 @@ void authenticated() {

@Test
void options() {
TestRestTemplate template = new TestRestTemplate(HttpClientOption.ENABLE_REDIRECTS);
RequestConfig config = getRequestConfig(
new TestRestTemplate(HttpClientOption.ENABLE_REDIRECTS, HttpClientOption.ENABLE_COOKIES));
assertThat(config.isRedirectsEnabled()).isTrue();
assertThat(config.getCookieSpec()).isEqualTo("strict");
}

@Test
void jdkBuilderCanBeSpecifiedWithSpecificRedirects() {
RestTemplateBuilder builder = new RestTemplateBuilder()
.requestFactoryBuilder(ClientHttpRequestFactoryBuilder.jdk());
TestRestTemplate templateWithRedirects = new TestRestTemplate(builder.redirects(Redirects.FOLLOW));
assertThat(getJdkHttpClient(templateWithRedirects).followRedirects()).isEqualTo(Redirect.NORMAL);
TestRestTemplate templateWithoutRedirects = new TestRestTemplate(builder.redirects(Redirects.DONT_FOLLOW));
assertThat(getJdkHttpClient(templateWithoutRedirects).followRedirects()).isEqualTo(Redirect.NEVER);
}

@Test
void httpComponentsAreBuildConsideringSettingsInRestTemplateBuilder() {
RestTemplateBuilder builder = new RestTemplateBuilder()
.requestFactoryBuilder(ClientHttpRequestFactoryBuilder.httpComponents());
assertThat(getRequestConfig((RestTemplateBuilder) null).isRedirectsEnabled()).isTrue();
assertThat(getRequestConfig(null, HttpClientOption.ENABLE_REDIRECTS).isRedirectsEnabled()).isTrue();
assertThat(getRequestConfig(builder).isRedirectsEnabled()).isTrue();
assertThat(getRequestConfig(builder, HttpClientOption.ENABLE_REDIRECTS).isRedirectsEnabled()).isTrue();
assertThat(getRequestConfig(builder.redirects(Redirects.DONT_FOLLOW)).isRedirectsEnabled()).isFalse();
assertThat(getRequestConfig(builder.redirects(Redirects.DONT_FOLLOW), HttpClientOption.ENABLE_REDIRECTS)
.isRedirectsEnabled()).isTrue();
}

private RequestConfig getRequestConfig(RestTemplateBuilder builder, HttpClientOption... httpClientOptions) {
builder = (builder != null) ? builder : new RestTemplateBuilder();
TestRestTemplate template = new TestRestTemplate(builder, null, null, httpClientOptions);
return getRequestConfig(template);
}

private RequestConfig getRequestConfig(TestRestTemplate template) {
CustomHttpComponentsClientHttpRequestFactory factory = (CustomHttpComponentsClientHttpRequestFactory) template
.getRestTemplate()
.getRequestFactory();
RequestConfig config = factory.createRequestConfig();
assertThat(config.isRedirectsEnabled()).isTrue();
return factory.createRequestConfig();
}

private HttpClient getJdkHttpClient(TestRestTemplate templateWithRedirects) {
JdkClientHttpRequestFactory requestFactory = (JdkClientHttpRequestFactory) templateWithRedirects
.getRestTemplate()
.getRequestFactory();
return (HttpClient) ReflectionTestUtils.getField(requestFactory, "httpClient");
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.springframework.beans.BeanUtils;
import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder;
import org.springframework.boot.http.client.ClientHttpRequestFactorySettings;
import org.springframework.boot.http.client.ClientHttpRequestFactorySettings.Redirects;
import org.springframework.boot.ssl.SslBundle;
import org.springframework.http.client.ClientHttpRequest;
import org.springframework.http.client.ClientHttpRequestFactory;
Expand Down Expand Up @@ -64,6 +65,7 @@
* @author Kevin Strijbos
* @author Ilya Lukyanovich
* @author Scott Frederick
* @author Yanming Zhou
* @since 1.4.0
*/
public class RestTemplateBuilder {
Expand Down Expand Up @@ -501,6 +503,19 @@ public RestTemplateBuilder readTimeout(Duration readTimeout) {
this.defaultHeaders, this.customizers, this.requestCustomizers);
}

/**
* Sets the redirect strategy on the underlying {@link ClientHttpRequestFactory}.
* @param redirects the redirect strategy
* @return a new builder instance.
* @since 3.4.1
*/
public RestTemplateBuilder redirects(Redirects redirects) {
return new RestTemplateBuilder(this.requestFactorySettings.withRedirects(redirects), this.detectRequestFactory,
this.rootUri, this.messageConverters, this.interceptors, this.requestFactoryBuilder,
this.uriTemplateHandler, this.errorHandler, this.basicAuthentication, this.defaultHeaders,
this.customizers, this.requestCustomizers);
}

/**
* Sets the SSL bundle on the underlying {@link ClientHttpRequestFactory}.
* @param sslBundle the SSL bundle
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.mockito.junit.jupiter.MockitoExtension;

import org.springframework.boot.http.client.ClientHttpRequestFactorySettings;
import org.springframework.boot.http.client.ClientHttpRequestFactorySettings.Redirects;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
Expand Down Expand Up @@ -73,6 +74,7 @@
* @author Kevin Strijbos
* @author Ilya Lukyanovich
* @author Brian Clozel
* @author Yanming Zhou
*/
@ExtendWith(MockitoExtension.class)
class RestTemplateBuilderTests {
Expand Down Expand Up @@ -486,6 +488,13 @@ void unwrappingDoesNotAffectRequestFactoryThatIsSetOnTheBuiltTemplate() {
assertThat(template.getRequestFactory()).isInstanceOf(BufferingClientHttpRequestFactory.class);
}

@Test
void configureRedirects() {
assertThat(this.builder.redirects(Redirects.DONT_FOLLOW)).extracting("requestFactorySettings")
.extracting("redirects")
.isSameAs(Redirects.DONT_FOLLOW);
}

private ClientHttpRequest createRequest(RestTemplate template) {
return ReflectionTestUtils.invokeMethod(template, "createRequest", URI.create("http://localhost"),
HttpMethod.GET);
Expand Down

0 comments on commit b7f3627

Please sign in to comment.