diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/util/PathContentProvider.java b/jetty-client/src/main/java/org/eclipse/jetty/client/util/PathContentProvider.java
index ed83660394b..9a1532d50a0 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/util/PathContentProvider.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/util/PathContentProvider.java
@@ -31,14 +31,17 @@ import java.util.Iterator;
import java.util.NoSuchElementException;
import org.eclipse.jetty.client.api.ContentProvider;
+import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
/**
- * A {@link ContentProvider} for files using JDK 7's {@code java.nio.file} APIs.
- *
- * It is possible to specify, at the constructor, a buffer size used to read content from the
- * stream, by default 4096 bytes.
+ *
A {@link ContentProvider} for files using JDK 7's {@code java.nio.file} APIs.
+ * It is possible to specify, at the constructor, a buffer size used to read
+ * content from the stream, by default 4096 bytes.
+ * If a {@link ByteBufferPool} is provided via {@link #setByteBufferPool(ByteBufferPool)},
+ * the buffer will be allocated from that pool, otherwise one buffer will be
+ * allocated and used to read the file.
*/
public class PathContentProvider extends AbstractTypedContentProvider
{
@@ -47,6 +50,7 @@ public class PathContentProvider extends AbstractTypedContentProvider
private final Path filePath;
private final long fileSize;
private final int bufferSize;
+ private ByteBufferPool bufferPool;
public PathContentProvider(Path filePath) throws IOException
{
@@ -81,6 +85,16 @@ public class PathContentProvider extends AbstractTypedContentProvider
return fileSize;
}
+ public ByteBufferPool getByteBufferPool()
+ {
+ return bufferPool;
+ }
+
+ public void setByteBufferPool(ByteBufferPool byteBufferPool)
+ {
+ this.bufferPool = byteBufferPool;
+ }
+
@Override
public Iterator iterator()
{
@@ -89,7 +103,7 @@ public class PathContentProvider extends AbstractTypedContentProvider
private class PathIterator implements Iterator, Closeable
{
- private final ByteBuffer buffer = ByteBuffer.allocateDirect(bufferSize);
+ private ByteBuffer buffer;
private SeekableByteChannel channel;
private long position;
@@ -106,6 +120,9 @@ public class PathContentProvider extends AbstractTypedContentProvider
{
if (channel == null)
{
+ buffer = bufferPool == null ?
+ ByteBuffer.allocateDirect(bufferSize) :
+ bufferPool.acquire(bufferSize, true);
channel = Files.newByteChannel(filePath, StandardOpenOption.READ);
if (LOG.isDebugEnabled())
LOG.debug("Opened file {}", filePath);
@@ -121,9 +138,6 @@ public class PathContentProvider extends AbstractTypedContentProvider
position += read;
- if (!hasNext())
- close();
-
buffer.flip();
return buffer;
}
@@ -139,17 +153,13 @@ public class PathContentProvider extends AbstractTypedContentProvider
}
}
- @Override
- public void remove()
- {
- throw new UnsupportedOperationException();
- }
-
@Override
public void close()
{
try
{
+ if (bufferPool != null && buffer != null)
+ bufferPool.release(buffer);
if (channel != null)
channel.close();
}
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/util/MultiPartContentProviderTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/util/MultiPartContentProviderTest.java
index 03f051cc520..ad59b41cdac 100644
--- a/jetty-client/src/test/java/org/eclipse/jetty/client/util/MultiPartContentProviderTest.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/util/MultiPartContentProviderTest.java
@@ -43,7 +43,6 @@ import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import org.eclipse.jetty.client.AbstractHttpClientServerTest;
-import org.eclipse.jetty.client.api.ContentProvider;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeader;
@@ -284,7 +283,8 @@ public class MultiPartContentProviderTest extends AbstractHttpClientServerTest
});
MultiPartContentProvider multiPart = new MultiPartContentProvider();
- ContentProvider content = new PathContentProvider(contentType, tmpPath);
+ PathContentProvider content = new PathContentProvider(contentType, tmpPath);
+ content.setByteBufferPool(client.getByteBufferPool());
multiPart.addFilePart(name, tmpPath.getFileName().toString(), content, null);
multiPart.close();
ContentResponse response = client.newRequest("localhost", connector.getLocalPort())