Merged branch 'jetty-9.3.x' into 'master'.
This commit is contained in:
commit
c52c8304d8
|
@ -31,14 +31,17 @@ import java.util.Iterator;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
import org.eclipse.jetty.client.api.ContentProvider;
|
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.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link ContentProvider} for files using JDK 7's {@code java.nio.file} APIs.
|
* <p>A {@link ContentProvider} for files using JDK 7's {@code java.nio.file} APIs.</p>
|
||||||
* <p>
|
* <p>It is possible to specify, at the constructor, a buffer size used to read
|
||||||
* It is possible to specify, at the constructor, a buffer size used to read content from the
|
* content from the stream, by default 4096 bytes.
|
||||||
* 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.</p>
|
||||||
*/
|
*/
|
||||||
public class PathContentProvider extends AbstractTypedContentProvider
|
public class PathContentProvider extends AbstractTypedContentProvider
|
||||||
{
|
{
|
||||||
|
@ -47,6 +50,7 @@ public class PathContentProvider extends AbstractTypedContentProvider
|
||||||
private final Path filePath;
|
private final Path filePath;
|
||||||
private final long fileSize;
|
private final long fileSize;
|
||||||
private final int bufferSize;
|
private final int bufferSize;
|
||||||
|
private ByteBufferPool bufferPool;
|
||||||
|
|
||||||
public PathContentProvider(Path filePath) throws IOException
|
public PathContentProvider(Path filePath) throws IOException
|
||||||
{
|
{
|
||||||
|
@ -81,6 +85,16 @@ public class PathContentProvider extends AbstractTypedContentProvider
|
||||||
return fileSize;
|
return fileSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ByteBufferPool getByteBufferPool()
|
||||||
|
{
|
||||||
|
return bufferPool;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setByteBufferPool(ByteBufferPool byteBufferPool)
|
||||||
|
{
|
||||||
|
this.bufferPool = byteBufferPool;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterator<ByteBuffer> iterator()
|
public Iterator<ByteBuffer> iterator()
|
||||||
{
|
{
|
||||||
|
@ -89,7 +103,7 @@ public class PathContentProvider extends AbstractTypedContentProvider
|
||||||
|
|
||||||
private class PathIterator implements Iterator<ByteBuffer>, Closeable
|
private class PathIterator implements Iterator<ByteBuffer>, Closeable
|
||||||
{
|
{
|
||||||
private final ByteBuffer buffer = ByteBuffer.allocateDirect(bufferSize);
|
private ByteBuffer buffer;
|
||||||
private SeekableByteChannel channel;
|
private SeekableByteChannel channel;
|
||||||
private long position;
|
private long position;
|
||||||
|
|
||||||
|
@ -106,6 +120,9 @@ public class PathContentProvider extends AbstractTypedContentProvider
|
||||||
{
|
{
|
||||||
if (channel == null)
|
if (channel == null)
|
||||||
{
|
{
|
||||||
|
buffer = bufferPool == null ?
|
||||||
|
ByteBuffer.allocateDirect(bufferSize) :
|
||||||
|
bufferPool.acquire(bufferSize, true);
|
||||||
channel = Files.newByteChannel(filePath, StandardOpenOption.READ);
|
channel = Files.newByteChannel(filePath, StandardOpenOption.READ);
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("Opened file {}", filePath);
|
LOG.debug("Opened file {}", filePath);
|
||||||
|
@ -121,9 +138,6 @@ public class PathContentProvider extends AbstractTypedContentProvider
|
||||||
|
|
||||||
position += read;
|
position += read;
|
||||||
|
|
||||||
if (!hasNext())
|
|
||||||
close();
|
|
||||||
|
|
||||||
buffer.flip();
|
buffer.flip();
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
@ -139,17 +153,13 @@ public class PathContentProvider extends AbstractTypedContentProvider
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void remove()
|
|
||||||
{
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close()
|
public void close()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
if (bufferPool != null && buffer != null)
|
||||||
|
bufferPool.release(buffer);
|
||||||
if (channel != null)
|
if (channel != null)
|
||||||
channel.close();
|
channel.close();
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,6 @@ import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.servlet.http.Part;
|
import javax.servlet.http.Part;
|
||||||
|
|
||||||
import org.eclipse.jetty.client.AbstractHttpClientServerTest;
|
import org.eclipse.jetty.client.AbstractHttpClientServerTest;
|
||||||
import org.eclipse.jetty.client.api.ContentProvider;
|
|
||||||
import org.eclipse.jetty.client.api.ContentResponse;
|
import org.eclipse.jetty.client.api.ContentResponse;
|
||||||
import org.eclipse.jetty.http.HttpFields;
|
import org.eclipse.jetty.http.HttpFields;
|
||||||
import org.eclipse.jetty.http.HttpHeader;
|
import org.eclipse.jetty.http.HttpHeader;
|
||||||
|
@ -284,7 +283,8 @@ public class MultiPartContentProviderTest extends AbstractHttpClientServerTest
|
||||||
});
|
});
|
||||||
|
|
||||||
MultiPartContentProvider multiPart = new MultiPartContentProvider();
|
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.addFilePart(name, tmpPath.getFileName().toString(), content, null);
|
||||||
multiPart.close();
|
multiPart.close();
|
||||||
ContentResponse response = client.newRequest("localhost", connector.getLocalPort())
|
ContentResponse response = client.newRequest("localhost", connector.getLocalPort())
|
||||||
|
|
Loading…
Reference in New Issue