Use timeout for JdkClientHttpRequest response retrieval

This commit ensures that, in JdkClientHttpRequest, the response is
obtained  using a timeout, instead of blocking indefinitely.

Closes gh-31911
This commit is contained in:
Arjen Poutsma 2024-01-10 09:53:02 +01:00
parent c4405104a8
commit 49d3ec58fc
1 changed files with 32 additions and 4 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -28,8 +28,11 @@ import java.time.Duration;
import java.util.Collections;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.Flow;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
@ -90,8 +93,14 @@ class JdkClientHttpRequest extends AbstractStreamingClientHttpRequest {
protected ClientHttpResponse executeInternal(HttpHeaders headers, @Nullable Body body) throws IOException {
try {
HttpRequest request = buildRequest(headers, body);
HttpResponse<InputStream> response =
this.httpClient.send(request, HttpResponse.BodyHandlers.ofInputStream());
HttpResponse<InputStream> response;
if (this.timeout != null) {
response = this.httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofInputStream())
.get(this.timeout.toMillis(), TimeUnit.MILLISECONDS);
}
else {
response = this.httpClient.send(request, HttpResponse.BodyHandlers.ofInputStream());
}
return new JdkClientHttpResponse(response);
}
catch (UncheckedIOException ex) {
@ -99,7 +108,26 @@ class JdkClientHttpRequest extends AbstractStreamingClientHttpRequest {
}
catch (InterruptedException ex) {
Thread.currentThread().interrupt();
throw new IOException("Could not send request: " + ex.getMessage(), ex);
throw new IOException("Request was interrupted: " + ex.getMessage(), ex);
}
catch (ExecutionException ex) {
Throwable cause = ex.getCause();
if (cause instanceof UncheckedIOException uioEx) {
throw uioEx.getCause();
}
if (cause instanceof RuntimeException rtEx) {
throw rtEx;
}
else if (cause instanceof IOException ioEx) {
throw ioEx;
}
else {
throw new IOException(cause.getMessage(), cause);
}
}
catch (TimeoutException ex) {
throw new IOException("Request timed out: " + ex.getMessage(), ex);
}
}