Add close() method on HTTP client response

Before this commit, there was no way to signal the HTTP client that we
were done consuming the response. Without that, the underlying client
library cannot know when it is safe to release the associated resources
(e.g. the HTTP connection).

This commit adds new `close()` methods on both `ClientHttpResponse`
and `ClientResponse`. This methods is non-blocking and its behavior
depends on the library, its configuration, HTTP version, etc.

At the `WebClient` level, `close()` is called automatically if we
consume the response body through the `ResponseSpec` or the
`ClientResponse` itself.

Note that it is *required* to call `close()` manually otherwise; not
doing so might create resource leaks or connection issues.

Issue: SPR-15920
This commit is contained in:
Brian Clozel
2017-09-06 14:06:56 +02:00
parent ba6b617bd5
commit 16f3f8d28f
11 changed files with 238 additions and 16 deletions

View File

@@ -16,6 +16,8 @@
package org.springframework.http.client.reactive;
import java.io.Closeable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ReactiveHttpInputMessage;
import org.springframework.http.ResponseCookie;
@@ -25,9 +27,10 @@ import org.springframework.util.MultiValueMap;
* Represents a client-side reactive HTTP response.
*
* @author Arjen Poutsma
* @author Brian Clozel
* @since 5.0
*/
public interface ClientHttpResponse extends ReactiveHttpInputMessage {
public interface ClientHttpResponse extends ReactiveHttpInputMessage, Closeable {
/**
* Return the HTTP status as an {@link HttpStatus} enum value.
@@ -39,4 +42,15 @@ public interface ClientHttpResponse extends ReactiveHttpInputMessage {
*/
MultiValueMap<String, ResponseCookie> getCookies();
/**
* Close this response, freeing any resources created.
* <p>This non-blocking method has to be called once the response has been
* processed and the resources are no longer needed; not doing so might
* create resource leaks or connection issues.
* <p>Depending on the client configuration and HTTP version,
* this can lead to closing the connection or returning it to a connection pool.
*/
@Override
void close();
}

View File

@@ -70,6 +70,10 @@ public class ClientHttpResponseDecorator implements ClientHttpResponse {
return this.delegate.getBody();
}
@Override
public void close() {
this.delegate.close();
}
@Override
public String toString() {

View File

@@ -89,6 +89,10 @@ public class ReactorClientHttpResponse implements ClientHttpResponse {
return CollectionUtils.unmodifiableMultiValueMap(result);
}
@Override
public void close() {
this.response.dispose();
}
@Override
public String toString() {