Fix behavior of ClientResponse#bodyTo** with Void

Prior to this commit, asking for a `Void` type using any of the
`ClientResponse#bodyTo*` methods would immediately return an empty
`Publisher` without consuming the response body.

Not doing so can lead to HTTP connection pool inconsistencies and/or
memory leaks, since:

* a connection that still has a response body being written to it cannot
be properly recycled in the connection pool
* incoming `DataBuffer` might not be released

This commit detects when `Void` types are asked as body types and in
those cases does the following:

1. Subscribe to the response body `Publisher` to allow the connection to
be returned to the connection pool
2. `cancel()` the body `Publisher` if the response body is not empty; in
that case, we choose to close the connection vs. consume the whole
response body

Those changes imply that `ClientHttpResponse` and other related
contracts don't need a `close()` method anymore.

Issue: SPR-16018
This commit is contained in:
Brian Clozel
2017-09-27 23:08:30 +02:00
parent ec345bf162
commit 126ac849e5
11 changed files with 122 additions and 152 deletions

View File

@@ -55,7 +55,6 @@ public class MockClientHttpResponse implements ClientHttpResponse {
private final DataBufferFactory bufferFactory = new DefaultDataBufferFactory();
private boolean closed = false;
public MockClientHttpResponse(HttpStatus status) {
Assert.notNull(status, "HttpStatus is required");
@@ -99,21 +98,9 @@ public class MockClientHttpResponse implements ClientHttpResponse {
@Override
public Flux<DataBuffer> getBody() {
if (this.closed) {
return Flux.error(new IllegalStateException("Connection has been closed."));
}
return this.body;
}
@Override
public void close() {
this.closed = true;
}
public boolean isClosed() {
return this.closed;
}
/**
* Return the response body aggregated and converted to a String using the
* charset of the Content-Type response or otherwise as "UTF-8".