Skip to content

Commit afb9ef8

Browse files
authored
Add support for Request Timeouts to HTTP/2 Java 11 Client. (#1233)
Adds `Request.Options` to the HTTP/2 Client Request Builder.
1 parent b3d5ac7 commit afb9ef8

2 files changed

Lines changed: 37 additions & 6 deletions

File tree

java11/src/main/java/feign/http2client/Http2Client.java

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,11 @@
1313
*/
1414
package feign.http2client;
1515

16-
import feign.*;
16+
import feign.Client;
17+
import feign.Request;
1718
import feign.Request.Options;
19+
import feign.Response;
20+
import feign.Util;
1821
import java.io.ByteArrayInputStream;
1922
import java.io.IOException;
2023
import java.net.URI;
@@ -28,6 +31,7 @@
2831
import java.net.http.HttpRequest.Builder;
2932
import java.net.http.HttpResponse;
3033
import java.net.http.HttpResponse.BodyHandlers;
34+
import java.time.Duration;
3135
import java.util.*;
3236
import java.util.function.Function;
3337
import java.util.stream.Collectors;
@@ -46,12 +50,13 @@ public Http2Client(HttpClient client) {
4650

4751
@Override
4852
public Response execute(Request request, Options options) throws IOException {
49-
final HttpRequest httpRequest = newRequestBuilder(request).build();
53+
final HttpRequest httpRequest = newRequestBuilder(request, options).build();
5054

5155
HttpResponse<byte[]> httpResponse;
5256
try {
5357
httpResponse = client.send(httpRequest, BodyHandlers.ofByteArray());
5458
} catch (final InterruptedException e) {
59+
Thread.currentThread().interrupt();
5560
throw new IOException("Invalid uri " + request.url(), e);
5661
}
5762

@@ -70,7 +75,7 @@ public Response execute(Request request, Options options) throws IOException {
7075
return response;
7176
}
7277

73-
private Builder newRequestBuilder(Request request) throws IOException {
78+
private Builder newRequestBuilder(Request request, Options options) throws IOException {
7479
URI uri;
7580
try {
7681
uri = new URI(request.url());
@@ -86,7 +91,11 @@ private Builder newRequestBuilder(Request request) throws IOException {
8691
body = BodyPublishers.ofByteArray(data);
8792
}
8893

89-
final Builder requestBuilder = HttpRequest.newBuilder().uri(uri).version(Version.HTTP_2);
94+
final Builder requestBuilder =
95+
HttpRequest.newBuilder()
96+
.uri(uri)
97+
.timeout(Duration.ofMillis(options.readTimeoutMillis()))
98+
.version(Version.HTTP_2);
9099

91100
final Map<String, Collection<String>> headers = filterRestrictedHeaders(request.headers());
92101
if (!headers.isEmpty()) {
@@ -159,7 +168,6 @@ private String[] asString(Map<String, Collection<String>> headers) {
159168
entry.getValue().stream()
160169
.map(value -> Arrays.asList(entry.getKey(), value))
161170
.flatMap(List::stream))
162-
.collect(Collectors.toList())
163-
.toArray(new String[0]);
171+
.toArray(String[]::new);
164172
}
165173
}

java11/src/test/java/feign/http2client/test/Http2ClientTest.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,11 @@
1919
import feign.client.AbstractClientTest;
2020
import feign.http2client.Http2Client;
2121
import java.io.IOException;
22+
import java.net.http.HttpTimeoutException;
23+
import java.util.concurrent.TimeUnit;
2224
import okhttp3.mockwebserver.MockResponse;
2325
import org.assertj.core.api.Assertions;
26+
import org.hamcrest.CoreMatchers;
2427
import org.junit.Ignore;
2528
import org.junit.Test;
2629

@@ -36,6 +39,10 @@ public interface TestInterface {
3639
@RequestLine("PATCH /patch")
3740
@Headers({"Accept: text/plain"})
3841
String patch();
42+
43+
@RequestLine("POST /timeout")
44+
@Headers({"Accept: text/plain"})
45+
String timeout();
3946
}
4047

4148
@Override
@@ -78,6 +85,22 @@ public void testVeryLongResponseNullLength() {
7885
// client is too smart to fall for a body that is 8 bytes long
7986
}
8087

88+
@Test
89+
public void timeoutTest() {
90+
server.enqueue(new MockResponse().setBody("foo").setBodyDelay(30, TimeUnit.SECONDS));
91+
92+
final TestInterface api =
93+
newBuilder()
94+
.retryer(Retryer.NEVER_RETRY)
95+
.options(new Request.Options(1, TimeUnit.SECONDS, 1, TimeUnit.SECONDS, true))
96+
.target(TestInterface.class, server.url("/").toString());
97+
98+
thrown.expect(FeignException.class);
99+
thrown.expectCause(CoreMatchers.isA(HttpTimeoutException.class));
100+
101+
api.timeout();
102+
}
103+
81104
@Override
82105
public Feign.Builder newBuilder() {
83106
return Feign.builder().client(new Http2Client());

0 commit comments

Comments
 (0)