HTTPCLIENT-1281: GzipDecompressingEntity does not release InputStream when an IOException occurs while reading the Gzip header

Contributed by Francois-Xavier Bonnet <francois-xavier.bonnet at centraliens.net>

git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1422997 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Oleg Kalnichevski 2012-12-17 16:12:18 +00:00
parent a92a196de2
commit 5c0cb57422
3 changed files with 47 additions and 6 deletions

View File

@ -1,6 +1,10 @@
Changes in trunk
-------------------
* [HTTPCLIENT-1281] GzipDecompressingEntity does not release InputStream when an IOException occurs
while reading the Gzip header.
Contributed by Francois-Xavier Bonnet <francois-xavier.bonnet at centraliens.net>
* [HTTPCLIENT-1277] Caching client sends a 304 to an unconditional request.
Contributed by Francois-Xavier Bonnet <francois-xavier.bonnet at centraliens.net>

View File

@ -31,6 +31,7 @@ import java.io.OutputStream;
import org.apache.http.HttpEntity;
import org.apache.http.entity.HttpEntityWrapper;
import org.apache.http.util.EntityUtils;
/**
* Common base class for decompressing {@link HttpEntity} implementations.
@ -67,13 +68,18 @@ abstract class DecompressingEntity extends HttpEntityWrapper {
*/
@Override
public InputStream getContent() throws IOException {
if (wrappedEntity.isStreaming()) {
if (content == null) {
content = getDecompressingInputStream(wrappedEntity.getContent());
try {
if (wrappedEntity.isStreaming()) {
if (content == null) {
content = getDecompressingInputStream(wrappedEntity.getContent());
}
return content;
} else {
return getDecompressingInputStream(wrappedEntity.getContent());
}
return content;
} else {
return getDecompressingInputStream(wrappedEntity.getContent());
} catch (IOException e) {
EntityUtils.consume(wrappedEntity);
throw e;
}
}

View File

@ -28,12 +28,17 @@
package org.apache.http.client.entity;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.atomic.AtomicBoolean;
import junit.framework.Assert;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.InputStreamEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.util.EntityUtils;
import org.junit.Test;
@ -63,4 +68,30 @@ public class TestGZip {
Assert.assertEquals("some kind of text", EntityUtils.toString(gunzipe, Consts.ASCII));
}
@Test
public void testGzipDecompressingEntityDoesNotCrashInConstructorAndLeaveInputStreamOpen()
throws Exception {
final AtomicBoolean inputStreamIsClosed = new AtomicBoolean(false);
HttpEntity in = new InputStreamEntity(new InputStream() {
@Override
public int read() throws IOException {
throw new IOException("An exception occurred");
}
@Override
public void close() throws IOException {
inputStreamIsClosed.set(true);
}
}, 123);
GzipDecompressingEntity gunzipe = new GzipDecompressingEntity(in);
try {
gunzipe.getContent();
} catch (IOException e) {
// As I cannot get the content, GzipDecompressingEntity is supposed
// to have released everything
Assert.assertTrue(inputStreamIsClosed.get());
}
}
}