You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2019/03/28 11:24:10 UTC
[httpcomponents-core] branch PR-114 created (now 7068d0c)
This is an automated email from the ASF dual-hosted git repository.
olegk pushed a change to branch PR-114
in repository https://gitbox.apache.org/repos/asf/httpcomponents-core.git.
at 7068d0c HTTPCORE-573 FileContentDecoder don't always enforce the maximum number of bytes to transfer
This branch includes the following new commits:
new 7068d0c HTTPCORE-573 FileContentDecoder don't always enforce the maximum number of bytes to transfer
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
[httpcomponents-core] 01/01: HTTPCORE-573 FileContentDecoder don't
always enforce the maximum number of bytes to transfer
Posted by ol...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
olegk pushed a commit to branch PR-114
in repository https://gitbox.apache.org/repos/asf/httpcomponents-core.git
commit 7068d0c3750cd54a136df7fadb1dbbac9cd3e201
Author: Julien Coloos <ju...@gmail.com>
AuthorDate: Tue Mar 26 17:45:32 2019 +0100
HTTPCORE-573 FileContentDecoder don't always enforce the maximum number of bytes to transfer
Limit the number of bytes read from the internal buffer when
transferring, so that the maximum requested ('count') is respected.
---
.../hc/core5/http/impl/nio/IdentityDecoder.java | 3 +-
.../http/impl/nio/LengthDelimitedDecoder.java | 2 +-
.../core5/http/impl/nio/TestIdentityDecoder.java | 67 ++++++++++++++++++++++
.../http/impl/nio/TestLengthDelimitedDecoder.java | 67 ++++++++++++++++++++++
4 files changed, 137 insertions(+), 2 deletions(-)
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/IdentityDecoder.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/IdentityDecoder.java
index 08f03a3..06935ac 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/IdentityDecoder.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/IdentityDecoder.java
@@ -92,8 +92,9 @@ public class IdentityDecoder extends AbstractContentDecoder implements FileConte
long bytesRead;
if (this.buffer.hasData()) {
+ final int maxLen = this.buffer.length();
dst.position(position);
- bytesRead = this.buffer.read(dst);
+ bytesRead = this.buffer.read(dst, count < maxLen ? (int)count : maxLen);
} else {
if (this.channel.isOpen()) {
if (position > dst.size()) {
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/LengthDelimitedDecoder.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/LengthDelimitedDecoder.java
index 1a00718..46849b8 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/LengthDelimitedDecoder.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/LengthDelimitedDecoder.java
@@ -119,7 +119,7 @@ public class LengthDelimitedDecoder extends AbstractContentDecoder implements Fi
if (this.buffer.hasData()) {
final int maxLen = Math.min(chunk, this.buffer.length());
dst.position(position);
- bytesRead = this.buffer.read(dst, maxLen);
+ bytesRead = this.buffer.read(dst, count < maxLen ? (int)count : maxLen);
} else {
if (this.channel.isOpen()) {
if (position > dst.size()) {
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/http/impl/nio/TestIdentityDecoder.java b/httpcore5/src/test/java/org/apache/hc/core5/http/impl/nio/TestIdentityDecoder.java
index e077211..dd8af8e 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/http/impl/nio/TestIdentityDecoder.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/http/impl/nio/TestIdentityDecoder.java
@@ -255,6 +255,73 @@ public class TestIdentityDecoder {
}
@Test
+ public void testDecodingFileWithLimit() throws Exception {
+ final ReadableByteChannel channel = new ReadableByteChannelMock(
+ new String[] {"stuff; more stuff; ", "a lot more stuff!"}, StandardCharsets.US_ASCII);
+
+ final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, 0, StandardCharsets.US_ASCII);
+ final BasicHttpTransportMetrics metrics = new BasicHttpTransportMetrics();
+ final IdentityDecoder decoder = new IdentityDecoder(channel, inbuf, metrics);
+
+ final int i = inbuf.fill(channel);
+ Assert.assertEquals(19, i);
+
+ createTempFile();
+ final RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw");
+ try {
+ final FileChannel fchannel = testfile.getChannel();
+ long pos = 0;
+
+ // transferred from buffer
+ long bytesRead = decoder.transfer(fchannel, pos, 1);
+ Assert.assertEquals(1, bytesRead);
+ Assert.assertFalse(decoder.isCompleted());
+ Assert.assertEquals(0, metrics.getBytesTransferred());
+ pos += bytesRead;
+
+ bytesRead = decoder.transfer(fchannel, pos, 2);
+ Assert.assertEquals(2, bytesRead);
+ Assert.assertFalse(decoder.isCompleted());
+ Assert.assertEquals(0, metrics.getBytesTransferred());
+ pos += bytesRead;
+
+ bytesRead = decoder.transfer(fchannel, pos, 17);
+ Assert.assertEquals(16, bytesRead);
+ Assert.assertFalse(decoder.isCompleted());
+ Assert.assertEquals(0, metrics.getBytesTransferred());
+ pos += bytesRead;
+
+ // transferred from channel
+ bytesRead = decoder.transfer(fchannel, pos, 1);
+ Assert.assertEquals(1, bytesRead);
+ Assert.assertFalse(decoder.isCompleted());
+ Assert.assertEquals(1, metrics.getBytesTransferred());
+ pos += bytesRead;
+
+ bytesRead = decoder.transfer(fchannel, pos, 2);
+ Assert.assertEquals(2, bytesRead);
+ Assert.assertFalse(decoder.isCompleted());
+ Assert.assertEquals(3, metrics.getBytesTransferred());
+ pos += bytesRead;
+
+ bytesRead = decoder.transfer(fchannel, pos, 15);
+ Assert.assertEquals(14, bytesRead);
+ Assert.assertFalse(decoder.isCompleted());
+ Assert.assertEquals(17, metrics.getBytesTransferred());
+ pos += bytesRead;
+
+ bytesRead = decoder.transfer(fchannel, pos, 1);
+ Assert.assertEquals(-1, bytesRead);
+ Assert.assertTrue(decoder.isCompleted());
+ Assert.assertEquals(17, metrics.getBytesTransferred());
+ } finally {
+ testfile.close();
+ }
+ Assert.assertEquals("stuff; more stuff; a lot more stuff!",
+ CodecTestUtils.readFromFile(this.tmpfile));
+ }
+
+ @Test
public void testWriteBeyondFileSize() throws Exception {
final ReadableByteChannel channel = new ReadableByteChannelMock(
new String[] {"a"}, StandardCharsets.US_ASCII);
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/http/impl/nio/TestLengthDelimitedDecoder.java b/httpcore5/src/test/java/org/apache/hc/core5/http/impl/nio/TestLengthDelimitedDecoder.java
index 34b241c..3a0b96e 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/http/impl/nio/TestLengthDelimitedDecoder.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/http/impl/nio/TestLengthDelimitedDecoder.java
@@ -363,6 +363,73 @@ public class TestLengthDelimitedDecoder {
}
@Test
+ public void testDecodingFileWithLimit() throws Exception {
+ final ReadableByteChannel channel = new ReadableByteChannelMock(
+ new String[] {"stuff; more stuff; ", "a lot more stuff!!!"}, StandardCharsets.US_ASCII);
+
+ final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, 0, StandardCharsets.US_ASCII);
+ final BasicHttpTransportMetrics metrics = new BasicHttpTransportMetrics();
+ final LengthDelimitedDecoder decoder = new LengthDelimitedDecoder(channel, inbuf, metrics, 36);
+
+ final int i = inbuf.fill(channel);
+ Assert.assertEquals(19, i);
+
+ createTempFile();
+ final RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw");
+ try {
+ final FileChannel fchannel = testfile.getChannel();
+ long pos = 0;
+
+ // transferred from buffer
+ long bytesRead = decoder.transfer(fchannel, pos, 1);
+ Assert.assertEquals(1, bytesRead);
+ Assert.assertFalse(decoder.isCompleted());
+ Assert.assertEquals(0, metrics.getBytesTransferred());
+ pos += bytesRead;
+
+ bytesRead = decoder.transfer(fchannel, pos, 2);
+ Assert.assertEquals(2, bytesRead);
+ Assert.assertFalse(decoder.isCompleted());
+ Assert.assertEquals(0, metrics.getBytesTransferred());
+ pos += bytesRead;
+
+ bytesRead = decoder.transfer(fchannel, pos, 17);
+ Assert.assertEquals(16, bytesRead);
+ Assert.assertFalse(decoder.isCompleted());
+ Assert.assertEquals(0, metrics.getBytesTransferred());
+ pos += bytesRead;
+
+ // transferred from channel
+ bytesRead = decoder.transfer(fchannel, pos, 1);
+ Assert.assertEquals(1, bytesRead);
+ Assert.assertFalse(decoder.isCompleted());
+ Assert.assertEquals(1, metrics.getBytesTransferred());
+ pos += bytesRead;
+
+ bytesRead = decoder.transfer(fchannel, pos, 2);
+ Assert.assertEquals(2, bytesRead);
+ Assert.assertFalse(decoder.isCompleted());
+ Assert.assertEquals(3, metrics.getBytesTransferred());
+ pos += bytesRead;
+
+ bytesRead = decoder.transfer(fchannel, pos, 15);
+ Assert.assertEquals(14, bytesRead);
+ Assert.assertTrue(decoder.isCompleted());
+ Assert.assertEquals(17, metrics.getBytesTransferred());
+ pos += bytesRead;
+
+ bytesRead = decoder.transfer(fchannel, pos, 1);
+ Assert.assertEquals(-1, bytesRead);
+ Assert.assertTrue(decoder.isCompleted());
+ Assert.assertEquals(17, metrics.getBytesTransferred());
+ } finally {
+ testfile.close();
+ }
+ Assert.assertEquals("stuff; more stuff; a lot more stuff!",
+ CodecTestUtils.readFromFile(this.tmpfile));
+ }
+
+ @Test
public void testWriteBeyondFileSize() throws Exception {
final ReadableByteChannel channel = new ReadableByteChannelMock(
new String[] {"a"}, StandardCharsets.US_ASCII);