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 060bef8dde28..1e7068263d73 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 @@ public URI getURI() { @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 @@ else if (cause instanceof IOException ioEx) { 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) { @@ -224,6 +228,7 @@ public ByteBuffer map(byte[] b, int off, int len) { private static final class TimeoutHandler { private final CompletableFuture timeoutFuture; + private boolean isTimeout=false; private TimeoutHandler(CompletableFuture> future, Duration timeout) { @@ -232,6 +237,7 @@ private TimeoutHandler(CompletableFuture> future, Dura this.timeoutFuture.thenRun(() -> { if (future.cancel(true) || future.isCompletedExceptionally() || !future.isDone()) { + this.isTimeout = true; return; } try {