diff --git a/src/main/java/com/box/sdk/BinaryBodyUtils.java b/src/main/java/com/box/sdk/BinaryBodyUtils.java index 108f699a9..31a31f59c 100644 --- a/src/main/java/com/box/sdk/BinaryBodyUtils.java +++ b/src/main/java/com/box/sdk/BinaryBodyUtils.java @@ -101,7 +101,7 @@ private static long getContentLengthFromAPIResponse(BoxAPIResponse response) { if (headerValue != null) { try { - length = Integer.parseInt(headerValue); + length = Long.parseLong(headerValue); } catch (NumberFormatException e) { throw new RuntimeException("Invalid content length: " + headerValue); } diff --git a/src/test/java/com/box/sdk/BoxAPIResponseTest.java b/src/test/java/com/box/sdk/BoxAPIResponseTest.java index c8eb80a42..cc463c096 100644 --- a/src/test/java/com/box/sdk/BoxAPIResponseTest.java +++ b/src/test/java/com/box/sdk/BoxAPIResponseTest.java @@ -1,5 +1,6 @@ package com.box.sdk; +import static com.box.sdk.BinaryBodyUtils.writeStreamWithContentLength; import static com.box.sdk.StandardCharsets.UTF_8; import static com.box.sdk.http.ContentType.APPLICATION_JSON; import static java.util.Arrays.asList; @@ -9,6 +10,9 @@ import static org.hamcrest.Matchers.is; import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.util.List; import java.util.Map; import java.util.TreeMap; @@ -16,6 +20,61 @@ public class BoxAPIResponseTest { + /** + * Simulated large InputStream that generates data on demand. + */ + static class LargeByteArrayInputStream extends InputStream { + private final long size; + private long bytesRead = 0; + + LargeByteArrayInputStream(long size) { + this.size = size; + } + + @Override + public int read() throws IOException { + if (bytesRead < size) { + bytesRead++; + return 'A'; // Simulated byte + } + return -1; // End of stream + } + + @Override + public int read(byte[] b, int off, int len) throws IOException { + if (bytesRead >= size) { + return -1; + } + int bytesToRead = (int) Math.min(len, size - bytesRead); + for (int i = 0; i < bytesToRead; i++) { + b[off + i] = 'A'; + } + bytesRead += bytesToRead; + return bytesToRead; + } + } + + + /** + * Null OutputStream that discards written data (useful for counting bytes). + */ + class NullOutputStream extends OutputStream { + long bytesWritten = 0; + @Override + public void write(int b) { + bytesWritten++; + } + + @Override + public void write(byte[] b, int off, int len) { + bytesWritten += len; + } + + long getBytesWritten() { + return bytesWritten; + } + } + @Test public void testAPIResponseHeaderIsCaseInsensitive() { Map> headers = new TreeMap<>(); @@ -85,4 +144,18 @@ public void testJsonResponseToString() { + "Body:\n{\"foo\":\"bar\"}") ); } + + @Test + public void testLargeBinaryResponseContentLength() { + long contentLength = Integer.MAX_VALUE + 10000L; + Map> headers = new TreeMap<>(); + headers.put("content-length", singletonList(Long.toString(contentLength))); + LargeByteArrayInputStream inputStream = new LargeByteArrayInputStream(contentLength); + NullOutputStream outputStream = new NullOutputStream(); + BoxAPIResponse response = new BoxAPIResponse( + 202, "GET", "https://aaa.com", headers, inputStream, "image/jpg", -1 + ); + writeStreamWithContentLength(response, outputStream); + assertThat(outputStream.getBytesWritten(), is(contentLength)); + } }