diff --git a/spring-web/src/main/java/org/springframework/http/client/JdkClientHttpRequest.java b/spring-web/src/main/java/org/springframework/http/client/JdkClientHttpRequest.java index d8f536e0be..376a8f48f9 100644 --- a/spring-web/src/main/java/org/springframework/http/client/JdkClientHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/client/JdkClientHttpRequest.java @@ -96,12 +96,13 @@ class JdkClientHttpRequest extends AbstractStreamingClientHttpRequest { @Override protected ClientHttpResponse executeInternal(HttpHeaders headers, @Nullable Body body) throws IOException { CompletableFuture> responseFuture = null; + TimeoutHandler timeoutHandler = null; try { HttpRequest request = buildRequest(headers, body); responseFuture = this.httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofInputStream()); if (this.timeout != null) { - TimeoutHandler timeoutHandler = new TimeoutHandler(responseFuture, this.timeout); + timeoutHandler = new TimeoutHandler(responseFuture, this.timeout); HttpResponse response = responseFuture.get(); InputStream inputStream = timeoutHandler.wrapInputStream(response); return new JdkClientHttpResponse(response, inputStream); @@ -136,6 +137,9 @@ class JdkClientHttpRequest extends AbstractStreamingClientHttpRequest { throw (message == null ? new IOException(cause) : new IOException(message, cause)); } } + catch (CancellationException ex) { + throw new HttpTimeoutException("Request timed out"); + } } private HttpRequest buildRequest(HttpHeaders headers, @Nullable Body body) { @@ -233,6 +237,7 @@ class JdkClientHttpRequest extends AbstractStreamingClientHttpRequest { private static final class TimeoutHandler { private final CompletableFuture timeoutFuture; + private boolean isTimeout=false; private TimeoutHandler(CompletableFuture> future, Duration timeout) { @@ -241,6 +246,7 @@ class JdkClientHttpRequest extends AbstractStreamingClientHttpRequest { this.timeoutFuture.thenRun(() -> { if (future.cancel(true) || future.isCompletedExceptionally() || !future.isDone()) { + this.isTimeout = true; return; } try {