Issue #3888 - Fixing for truncated long to int
+ Allowing CachedHttpContent._contentLengthValue actually hold the `long` resource size (for the 4G variant on test) + Allowing BufferUtil to not throw Exception if resource length is a positive value, but exceeds Integer.MAX_VALUE, opting instead to return a null to prevent excessive memory usage. (fixes the 10G variant of test) Signed-off-by: Joakim Erdfelt <joakim.erdfelt@gmail.com>
This commit is contained in:
parent
aef58168d0
commit
36294ef0da
|
@ -386,7 +386,7 @@ public class CachedContentFactory implements HttpContent.ContentFactory
|
||||||
{
|
{
|
||||||
private final String _key;
|
private final String _key;
|
||||||
private final Resource _resource;
|
private final Resource _resource;
|
||||||
private final int _contentLengthValue;
|
private final long _contentLengthValue;
|
||||||
private final HttpField _contentType;
|
private final HttpField _contentType;
|
||||||
private final String _characterEncoding;
|
private final String _characterEncoding;
|
||||||
private final MimeTypes.Type _mimeType;
|
private final MimeTypes.Type _mimeType;
|
||||||
|
@ -415,7 +415,7 @@ public class CachedContentFactory implements HttpContent.ContentFactory
|
||||||
_lastModified = _lastModifiedValue == -1 ? null
|
_lastModified = _lastModifiedValue == -1 ? null
|
||||||
: new PreEncodedHttpField(HttpHeader.LAST_MODIFIED, DateGenerator.formatDate(_lastModifiedValue));
|
: new PreEncodedHttpField(HttpHeader.LAST_MODIFIED, DateGenerator.formatDate(_lastModifiedValue));
|
||||||
|
|
||||||
_contentLengthValue = exists ? (int)resource.length() : 0;
|
_contentLengthValue = exists ? resource.length() : 0;
|
||||||
_contentLength = new PreEncodedHttpField(HttpHeader.CONTENT_LENGTH, Long.toString(_contentLengthValue));
|
_contentLength = new PreEncodedHttpField(HttpHeader.CONTENT_LENGTH, Long.toString(_contentLengthValue));
|
||||||
|
|
||||||
if (_cachedFiles.incrementAndGet() > _maxCachedFiles)
|
if (_cachedFiles.incrementAndGet() > _maxCachedFiles)
|
||||||
|
@ -558,7 +558,7 @@ public class CachedContentFactory implements HttpContent.ContentFactory
|
||||||
ByteBuffer buffer2 = CachedContentFactory.this.getIndirectBuffer(_resource);
|
ByteBuffer buffer2 = CachedContentFactory.this.getIndirectBuffer(_resource);
|
||||||
|
|
||||||
if (buffer2 == null)
|
if (buffer2 == null)
|
||||||
LOG.warn("Could not load " + this);
|
LOG.warn("Could not load indirect buffer from " + this);
|
||||||
else if (_indirectBuffer.compareAndSet(null, buffer2))
|
else if (_indirectBuffer.compareAndSet(null, buffer2))
|
||||||
{
|
{
|
||||||
buffer = buffer2;
|
buffer = buffer2;
|
||||||
|
|
|
@ -971,11 +971,19 @@ public class BufferUtil
|
||||||
|
|
||||||
public static ByteBuffer toBuffer(Resource resource, boolean direct) throws IOException
|
public static ByteBuffer toBuffer(Resource resource, boolean direct) throws IOException
|
||||||
{
|
{
|
||||||
int len = (int)resource.length();
|
long len = resource.length();
|
||||||
if (len < 0)
|
if (len < 0)
|
||||||
throw new IllegalArgumentException("invalid resource: " + resource + " len=" + len);
|
throw new IllegalArgumentException("invalid resource: " + resource + " len=" + len);
|
||||||
|
|
||||||
ByteBuffer buffer = direct ? BufferUtil.allocateDirect(len) : BufferUtil.allocate(len);
|
if (len > Integer.MAX_VALUE)
|
||||||
|
{
|
||||||
|
// This method cannot handle resources of this size.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ilen = (int)len;
|
||||||
|
|
||||||
|
ByteBuffer buffer = direct ? BufferUtil.allocateDirect(ilen) : BufferUtil.allocate(ilen);
|
||||||
|
|
||||||
int pos = BufferUtil.flipToFill(buffer);
|
int pos = BufferUtil.flipToFill(buffer);
|
||||||
if (resource.getFile() != null)
|
if (resource.getFile() != null)
|
||||||
|
@ -984,7 +992,7 @@ public class BufferUtil
|
||||||
{
|
{
|
||||||
try (InputStream is = resource.getInputStream())
|
try (InputStream is = resource.getInputStream())
|
||||||
{
|
{
|
||||||
BufferUtil.readFrom(is, len, buffer);
|
BufferUtil.readFrom(is, ilen, buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BufferUtil.flipToFlush(buffer, pos);
|
BufferUtil.flipToFlush(buffer, pos);
|
||||||
|
|
|
@ -160,6 +160,8 @@ public class HugeResourceTest
|
||||||
HttpURLConnection http = (HttpURLConnection)destUri.toURL().openConnection();
|
HttpURLConnection http = (HttpURLConnection)destUri.toURL().openConnection();
|
||||||
assertThat("HTTP Response Code", http.getResponseCode(), is(200));
|
assertThat("HTTP Response Code", http.getResponseCode(), is(200));
|
||||||
|
|
||||||
|
dumpResponseHeaders(http);
|
||||||
|
|
||||||
// if a Content-Length is provided, test it
|
// if a Content-Length is provided, test it
|
||||||
String contentLength = http.getHeaderField("Content-Length");
|
String contentLength = http.getHeaderField("Content-Length");
|
||||||
if (contentLength != null)
|
if (contentLength != null)
|
||||||
|
@ -186,4 +188,16 @@ public class HugeResourceTest
|
||||||
// Verify the file download size
|
// Verify the file download size
|
||||||
assertThat("Downloaded Files Size: " + filename, Files.size(outputFile), is(expectedSize));
|
assertThat("Downloaded Files Size: " + filename, Files.size(outputFile), is(expectedSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void dumpResponseHeaders(HttpURLConnection http)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
String value;
|
||||||
|
while ((value = http.getHeaderField(i)) != null)
|
||||||
|
{
|
||||||
|
String key = http.getHeaderFieldKey(i);
|
||||||
|
System.err.printf(" %s: %s%n", key, value);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue