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())