From 8f844461a06503d09e1f2dae4907bb56a8071edc Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Fri, 28 Oct 2016 14:18:46 +0200 Subject: [PATCH] Make HttpComponentsAsyncClientHttpRequest abortable This commit aborts the HttpComponentsAsyncClientHttpRequest whenever the returned Future is canceled. Issue: SPR-14845 --- .../client/HttpComponentsAsyncClientHttpRequest.java | 11 ++++++++++- .../AbstractAsyncHttpRequestFactoryTestCase.java | 12 +++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/http/client/HttpComponentsAsyncClientHttpRequest.java b/spring-web/src/main/java/org/springframework/http/client/HttpComponentsAsyncClientHttpRequest.java index de022125f7b..22313ed59e2 100644 --- a/spring-web/src/main/java/org/springframework/http/client/HttpComponentsAsyncClientHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/client/HttpComponentsAsyncClientHttpRequest.java @@ -92,7 +92,7 @@ final class HttpComponentsAsyncClientHttpRequest extends AbstractBufferingAsyncC entityEnclosingRequest.setEntity(requestEntity); } - final HttpResponseFutureCallback callback = new HttpResponseFutureCallback(); + final HttpResponseFutureCallback callback = new HttpResponseFutureCallback(this.httpRequest); final Future futureResponse = this.httpClient.execute(this.httpRequest, this.httpContext, callback); return new ClientHttpResponseFuture(futureResponse, callback); @@ -104,6 +104,14 @@ final class HttpComponentsAsyncClientHttpRequest extends AbstractBufferingAsyncC private final ListenableFutureCallbackRegistry callbacks = new ListenableFutureCallbackRegistry<>(); + private final HttpUriRequest httpRequest; + + + public HttpResponseFutureCallback(HttpUriRequest httpRequest) { + this.httpRequest = httpRequest; + } + + public void addCallback(ListenableFutureCallback callback) { this.callbacks.addCallback(callback); } @@ -128,6 +136,7 @@ final class HttpComponentsAsyncClientHttpRequest extends AbstractBufferingAsyncC @Override public void cancelled() { + this.httpRequest.abort(); } } diff --git a/spring-web/src/test/java/org/springframework/http/client/AbstractAsyncHttpRequestFactoryTestCase.java b/spring-web/src/test/java/org/springframework/http/client/AbstractAsyncHttpRequestFactoryTestCase.java index ccbb4894492..a40a42d89a8 100644 --- a/spring-web/src/test/java/org/springframework/http/client/AbstractAsyncHttpRequestFactoryTestCase.java +++ b/spring-web/src/test/java/org/springframework/http/client/AbstractAsyncHttpRequestFactoryTestCase.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2016 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. @@ -222,4 +222,14 @@ public abstract class AbstractAsyncHttpRequestFactoryTestCase extends AbstractJe } } + @Test + public void cancel() throws Exception { + URI uri = new URI(baseUrl + "/status/notfound"); + AsyncClientHttpRequest request = this.factory.createAsyncRequest(uri, HttpMethod.GET); + Future futureResponse = request.executeAsync(); + futureResponse.cancel(true); + assertTrue(futureResponse.isCancelled()); + } + + }