419964 - InputStreamContentProvider does not close provided

InputStream.

Now closing the provided InputStream when reading -1 or when an
exception is thrown.
This commit is contained in:
Simone Bordet 2013-10-28 11:13:17 +01:00
parent 7818d2f0c6
commit 3a10aa4164
1 changed files with 36 additions and 3 deletions

View File

@ -18,6 +18,7 @@
package org.eclipse.jetty.client.util;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.util.Iterator;
@ -25,6 +26,8 @@ import java.util.NoSuchElementException;
import org.eclipse.jetty.client.api.ContentProvider;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
/**
* A {@link ContentProvider} for an {@link InputStream}.
@ -33,19 +36,26 @@ import org.eclipse.jetty.util.BufferUtil;
* Invocations to the {@link #iterator()} method after the first will return an "empty" iterator
* because the stream has been consumed on the first invocation.
* <p />
* It is possible to specify, at the constructor, a buffer size used to read content from the
* stream, by default 4096 bytes.
* <p />
* However, it is possible for subclasses to override {@link #onRead(byte[], int, int)} to copy
* the content read from the stream to another location (for example a file), and be able to
* support multiple invocations of {@link #iterator()}, returning the iterator provided by this
* class on the first invocation, and an iterator on the bytes copied to the other location
* for subsequent invocations.
* <p />
* It is possible to specify, at the constructor, a buffer size used to read content from the
* stream, by default 4096 bytes.
* <p />
* The {@link InputStream} passed to the constructor is by default closed when is it fully
* consumed (or when an exception is thrown while reading it), unless otherwise specified
* to the {@link #InputStreamContentProvider(java.io.InputStream, int, boolean) constructor}.
*/
public class InputStreamContentProvider implements ContentProvider
{
private static final Logger LOG = Log.getLogger(InputStreamContentProvider.class);
private final InputStream stream;
private final int bufferSize;
private final boolean autoClose;
public InputStreamContentProvider(InputStream stream)
{
@ -53,9 +63,15 @@ public class InputStreamContentProvider implements ContentProvider
}
public InputStreamContentProvider(InputStream stream, int bufferSize)
{
this(stream, bufferSize, true);
}
public InputStreamContentProvider(InputStream stream, int bufferSize, boolean autoClose)
{
this.stream = stream;
this.bufferSize = bufferSize;
this.autoClose = autoClose;
}
@Override
@ -107,6 +123,7 @@ public class InputStreamContentProvider implements ContentProvider
}
else if (read < 0)
{
close();
return false;
}
else
@ -122,6 +139,7 @@ public class InputStreamContentProvider implements ContentProvider
failure = x;
// Signal we have more content to cause a call to
// next() which will throw NoSuchElementException.
close();
return true;
}
return false;
@ -145,6 +163,21 @@ public class InputStreamContentProvider implements ContentProvider
{
throw new UnsupportedOperationException();
}
private void close()
{
if (autoClose)
{
try
{
stream.close();
}
catch (IOException x)
{
LOG.ignore(x);
}
}
}
};
}
}