HTTPCLIENT-1143: CachingHttpClient leaks connections with stale-if-error.
Bugfix from James Miller <jamesmiller01 at gmail dot com>. git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1198939 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
c13bbbdd17
commit
c8aafc5c1a
|
@ -38,6 +38,7 @@ import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.apache.http.Header;
|
import org.apache.http.Header;
|
||||||
import org.apache.http.HeaderElement;
|
import org.apache.http.HeaderElement;
|
||||||
|
import org.apache.http.HttpEntity;
|
||||||
import org.apache.http.HttpHost;
|
import org.apache.http.HttpHost;
|
||||||
import org.apache.http.HttpMessage;
|
import org.apache.http.HttpMessage;
|
||||||
import org.apache.http.HttpRequest;
|
import org.apache.http.HttpRequest;
|
||||||
|
@ -64,6 +65,7 @@ import org.apache.http.impl.cookie.DateUtils;
|
||||||
import org.apache.http.message.BasicHttpResponse;
|
import org.apache.http.message.BasicHttpResponse;
|
||||||
import org.apache.http.params.HttpParams;
|
import org.apache.http.params.HttpParams;
|
||||||
import org.apache.http.protocol.HttpContext;
|
import org.apache.http.protocol.HttpContext;
|
||||||
|
import org.apache.http.util.EntityUtils;
|
||||||
import org.apache.http.util.VersionInfo;
|
import org.apache.http.util.VersionInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -833,6 +835,8 @@ public class CachingHttpClient implements HttpClient {
|
||||||
&& validityPolicy.mayReturnStaleIfError(request, cacheEntry, responseDate)) {
|
&& validityPolicy.mayReturnStaleIfError(request, cacheEntry, responseDate)) {
|
||||||
final HttpResponse cachedResponse = responseGenerator.generateResponse(cacheEntry);
|
final HttpResponse cachedResponse = responseGenerator.generateResponse(cacheEntry);
|
||||||
cachedResponse.addHeader(HeaderConstants.WARNING, "110 localhost \"Response is stale\"");
|
cachedResponse.addHeader(HeaderConstants.WARNING, "110 localhost \"Response is stale\"");
|
||||||
|
HttpEntity errorBody = backendResponse.getEntity();
|
||||||
|
if (errorBody != null) EntityUtils.consume(errorBody);
|
||||||
return cachedResponse;
|
return cachedResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
32
httpclient-cache/src/test/java/org/apache/http/impl/client/cache/ConsumableInputStream.java
vendored
Normal file
32
httpclient-cache/src/test/java/org/apache/http/impl/client/cache/ConsumableInputStream.java
vendored
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
package org.apache.http.impl.client.cache;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
public class ConsumableInputStream extends InputStream {
|
||||||
|
|
||||||
|
private ByteArrayInputStream buf;
|
||||||
|
private boolean closed = false;
|
||||||
|
|
||||||
|
public ConsumableInputStream(ByteArrayInputStream buf) {
|
||||||
|
this.buf = buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int read() throws IOException {
|
||||||
|
return buf.read();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
closed = true;
|
||||||
|
try {
|
||||||
|
buf.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean wasClosed() {
|
||||||
|
return closed;
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,13 +27,17 @@
|
||||||
package org.apache.http.impl.client.cache;
|
package org.apache.http.impl.client.cache;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import org.apache.http.Header;
|
import org.apache.http.Header;
|
||||||
|
import org.apache.http.HttpEntity;
|
||||||
import org.apache.http.HttpRequest;
|
import org.apache.http.HttpRequest;
|
||||||
import org.apache.http.HttpResponse;
|
import org.apache.http.HttpResponse;
|
||||||
import org.apache.http.HttpStatus;
|
import org.apache.http.HttpStatus;
|
||||||
import org.apache.http.HttpVersion;
|
import org.apache.http.HttpVersion;
|
||||||
|
import org.apache.http.entity.InputStreamEntity;
|
||||||
import org.apache.http.impl.cookie.DateUtils;
|
import org.apache.http.impl.cookie.DateUtils;
|
||||||
import org.apache.http.message.BasicHttpRequest;
|
import org.apache.http.message.BasicHttpRequest;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -83,6 +87,34 @@ public class TestRFC5861Compliance extends AbstractProtocolTest {
|
||||||
HttpTestUtils.assert110WarningFound(result);
|
HttpTestUtils.assert110WarningFound(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testConsumesErrorResponseWhenServingStale()
|
||||||
|
throws Exception{
|
||||||
|
Date tenSecondsAgo = new Date(new Date().getTime() - 10 * 1000L);
|
||||||
|
HttpRequest req1 = HttpTestUtils.makeDefaultRequest();
|
||||||
|
HttpResponse resp1 = HttpTestUtils.make200Response(tenSecondsAgo,
|
||||||
|
"public, max-age=5, stale-if-error=60");
|
||||||
|
|
||||||
|
backendExpectsAnyRequest().andReturn(resp1);
|
||||||
|
|
||||||
|
HttpRequest req2 = HttpTestUtils.makeDefaultRequest();
|
||||||
|
HttpResponse resp2 = HttpTestUtils.make500Response();
|
||||||
|
byte[] body = HttpTestUtils.getRandomBytes(101);
|
||||||
|
ByteArrayInputStream buf = new ByteArrayInputStream(body);
|
||||||
|
ConsumableInputStream cis = new ConsumableInputStream(buf);
|
||||||
|
HttpEntity entity = new InputStreamEntity(cis, 101);
|
||||||
|
resp2.setEntity(entity);
|
||||||
|
|
||||||
|
backendExpectsAnyRequest().andReturn(resp2);
|
||||||
|
|
||||||
|
replayMocks();
|
||||||
|
impl.execute(host,req1);
|
||||||
|
impl.execute(host,req2);
|
||||||
|
verifyMocks();
|
||||||
|
|
||||||
|
assertTrue(cis.wasClosed());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStaleIfErrorInResponseYieldsToMustRevalidate()
|
public void testStaleIfErrorInResponseYieldsToMustRevalidate()
|
||||||
throws Exception{
|
throws Exception{
|
||||||
|
|
Loading…
Reference in New Issue