From ef96a8166a4050f0f2738dc221d150f5ed6dfacc Mon Sep 17 00:00:00 2001 From: Gunther Klein <10827472+gb-klein@users.noreply.github.com> Date: Wed, 23 Dec 2020 02:35:17 +0100 Subject: [PATCH] Java11client connect timeout (#1307) * Set connect timeout from feign Option on java11 HttpClient * added a constructor to Http2Client which takes Options argument Co-authored-by: Gunther Klein Co-authored-by: Kevin Davis --- .../java/feign/http2client/Http2Client.java | 42 ++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/java11/src/main/java/feign/http2client/Http2Client.java b/java11/src/main/java/feign/http2client/Http2Client.java index 18488c19..3057f724 100644 --- a/java11/src/main/java/feign/http2client/Http2Client.java +++ b/java11/src/main/java/feign/http2client/Http2Client.java @@ -47,6 +47,12 @@ public class Http2Client implements Client { .build()); } + public Http2Client(Options options) { + this(newClientBuilder(options) + .version(Version.HTTP_2) + .build()); + } + public Http2Client(HttpClient client) { this.client = Util.checkNotNull(client, "HttpClient must not be null"); } @@ -54,10 +60,11 @@ public class Http2Client implements Client { @Override public Response execute(Request request, Options options) throws IOException { final HttpRequest httpRequest = newRequestBuilder(request, options).build(); + HttpClient clientForRequest = getOrCreateClient(options); HttpResponse httpResponse; try { - httpResponse = client.send(httpRequest, BodyHandlers.ofByteArray()); + httpResponse = clientForRequest.send(httpRequest, BodyHandlers.ofByteArray()); } catch (final InterruptedException e) { Thread.currentThread().interrupt(); throw new IOException("Invalid uri " + request.url(), e); @@ -76,6 +83,39 @@ public class Http2Client implements Client { return response; } + private HttpClient getOrCreateClient(Options options) { + if (doesClientConfigurationDiffer(options)) { + // create a new client from the existing one - but with connectTimeout and followRedirect + // settings from options + java.net.http.HttpClient.Builder builder = newClientBuilder(options) + .sslContext(client.sslContext()) + .sslParameters(client.sslParameters()) + .version(client.version()); + client.authenticator().ifPresent(builder::authenticator); + client.cookieHandler().ifPresent(builder::cookieHandler); + client.executor().ifPresent(builder::executor); + client.proxy().ifPresent(builder::proxy); + return builder.build(); + } + return client; + } + + private boolean doesClientConfigurationDiffer(Options options) { + if ((client.followRedirects() == Redirect.ALWAYS) != options.isFollowRedirects()) { + return true; + } + return client.connectTimeout() + .map(timeout -> timeout.toMillis() != options.connectTimeoutMillis()) + .orElse(true); + } + + private static java.net.http.HttpClient.Builder newClientBuilder(Options options) { + return HttpClient + .newBuilder() + .followRedirects(options.isFollowRedirects() ? Redirect.ALWAYS : Redirect.NEVER) + .connectTimeout(Duration.ofMillis(options.connectTimeoutMillis())); + } + private Builder newRequestBuilder(Request request, Options options) throws IOException { URI uri; try {