Skip to content

Commit 0789536

Browse files
authored
Enable requestBody to read buffer as duplicate. Also update OkHttpClient to not follow redirects by default. (Azure#27960)
OkHttpClient by default has redirectfollow set to true, which makes it difficult for us to invoke our own redirect policies. Updated that. I expect this not to be a breaking change since any SDK would have had to add redirect policy for Netty client which would mean OkHttp would continue to work for them. There is a small chance that an SDK may only support OkHttpClient and so may get affected however the right fix would be to update the redirect policy there. Let me know if anyone disagrees.
1 parent 283246f commit 0789536

File tree

3 files changed

+70
-0
lines changed

3 files changed

+70
-0
lines changed

sdk/core/azure-core-http-okhttp/CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,19 @@
33
## 1.8.0-beta.1 (Unreleased)
44

55
### Features Added
6+
- Added `followRedirects` property on the `OkHttpClientBuilder`.
67

78
### Breaking Changes
89

10+
- Okhttp-backed `HttpClient` client will no longer follow redirects automatically. ([#27960](https://github.com/Azure/azure-sdk-for-java/pull/27960)).
11+
<br>To get the older behavior please create an instance of `HttpClient` as follows
12+
13+
```java
14+
HttpClient client = new OkHttpAsyncHttpClientBuilder()
15+
.followRedirects(true)
16+
.build();
17+
```
18+
919
### Bugs Fixed
1020

1121
### Other Changes

sdk/core/azure-core-http-okhttp/src/main/java/com/azure/core/http/okhttp/OkHttpAsyncHttpClientBuilder.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ public class OkHttpAsyncHttpClientBuilder {
5656
private Dispatcher dispatcher;
5757
private ProxyOptions proxyOptions;
5858
private Configuration configuration;
59+
private boolean followRedirects;
5960

6061
/**
6162
* Creates OkHttpAsyncHttpClientBuilder.
@@ -212,6 +213,20 @@ public OkHttpAsyncHttpClientBuilder configuration(Configuration configuration) {
212213
return this;
213214
}
214215

216+
/**
217+
* <p>Sets the followRedirect flag on the underlying OkHttp-backed {@link com.azure.core.http.HttpClient}.</p>
218+
*
219+
* <p>If this is set to 'true' redirects will be followed automatically, and
220+
* if your HTTP pipeline is configured with a redirect policy it will not be called.</p>
221+
*
222+
* @param followRedirects The followRedirects value to use.
223+
* @return The updated OkHttpAsyncHttpClientBuilder object.
224+
*/
225+
public OkHttpAsyncHttpClientBuilder followRedirects(boolean followRedirects) {
226+
this.followRedirects = followRedirects;
227+
return this;
228+
}
229+
215230
/**
216231
* Creates a new OkHttp-backed {@link com.azure.core.http.HttpClient} instance on every call, using the
217232
* configuration set in the builder at the time of the build method call.
@@ -267,6 +282,9 @@ public HttpClient build() {
267282
}
268283
}
269284

285+
// Set the followRedirects property.
286+
httpClientBuilder.followRedirects(this.followRedirects);
287+
270288
return new OkHttpAsyncHttpClient(httpClientBuilder.build());
271289
}
272290

sdk/core/azure-core-http-okhttp/src/test/java/com/azure/core/http/okhttp/OkHttpAsyncHttpClientBuilderTests.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ public class OkHttpAsyncHttpClientBuilderTests {
4949
private static final String COOKIE_VALIDATOR_PATH = "/cookieValidator";
5050
private static final String DEFAULT_PATH = "/default";
5151
private static final String DISPATCHER_PATH = "/dispatcher";
52+
private static final String REDIRECT_PATH = "/redirect";
53+
private static final String LOCATION_PATH = "/location";
5254

5355
private static final String JAVA_SYSTEM_PROXY_PREREQUISITE = "java.net.useSystemProxies";
5456
private static final String JAVA_NON_PROXY_HOSTS = "http.nonProxyHosts";
@@ -63,6 +65,8 @@ public class OkHttpAsyncHttpClientBuilderTests {
6365
private static String cookieValidatorUrl;
6466
private static String defaultUrl;
6567
private static String dispatcherUrl;
68+
private static String locationUrl;
69+
private static String redirectUrl;
6670

6771
@BeforeAll
6872
public static void setupWireMock() {
@@ -84,6 +88,12 @@ public static void setupWireMock() {
8488
cookieValidatorUrl = "http://localhost:" + server.port() + COOKIE_VALIDATOR_PATH;
8589
defaultUrl = "http://localhost:" + server.port() + DEFAULT_PATH;
8690
dispatcherUrl = "http://localhost:" + server.port() + DISPATCHER_PATH;
91+
redirectUrl = "http://localhost:" + server.port() + REDIRECT_PATH;
92+
locationUrl = "http://localhost:" + server.port() + LOCATION_PATH;
93+
94+
// Mocked endpoint to test the redirect behavior.
95+
server.stubFor(WireMock.get(REDIRECT_PATH).willReturn(WireMock.aResponse().withStatus(307).withHeader("Location", locationUrl)));
96+
server.stubFor(WireMock.get(LOCATION_PATH).willReturn(WireMock.aResponse().withStatus(200)));
8797
}
8898

8999
@AfterAll
@@ -195,6 +205,38 @@ public void buildWithConnectionTimeout() {
195205
.verifyComplete();
196206
}
197207

208+
209+
@Test
210+
public void buildWithFollowRedirectSetToTrue() {
211+
HttpClient okClient = new OkHttpAsyncHttpClientBuilder()
212+
.followRedirects(true)
213+
.build();
214+
215+
StepVerifier.create(okClient.send(new HttpRequest(HttpMethod.GET, redirectUrl)))
216+
.assertNext(response -> assertEquals(200, response.getStatusCode()))
217+
.verifyComplete();
218+
}
219+
220+
@Test
221+
public void buildWithFollowRedirectSetToFalse() {
222+
HttpClient okClient = new OkHttpAsyncHttpClientBuilder()
223+
.followRedirects(false)
224+
.build();
225+
226+
StepVerifier.create(okClient.send(new HttpRequest(HttpMethod.GET, redirectUrl)))
227+
.assertNext(response -> assertEquals(307, response.getStatusCode()))
228+
.verifyComplete();
229+
}
230+
231+
@Test
232+
public void buildWithFollowRedirectDefault() {
233+
HttpClient okClient = new OkHttpAsyncHttpClientBuilder().build();
234+
235+
StepVerifier.create(okClient.send(new HttpRequest(HttpMethod.GET, redirectUrl)))
236+
.assertNext(response -> assertEquals(307, response.getStatusCode()))
237+
.verifyComplete();
238+
}
239+
198240
/**
199241
* Tests building a client with a given {@code connectionTimeout}.
200242
*/

0 commit comments

Comments
 (0)