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 2016/04/06 09:20:23 UTC
svn commit: r1737928 - in /httpcomponents/httpcore/branches/4.4.x:
httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/
httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/
httpcore/src/main/java/org/apache/http/impl/io/ httpcore/src/test...
Author: olegk
Date: Wed Apr 6 07:20:23 2016
New Revision: 1737928
URL: http://svn.apache.org/viewvc?rev=1737928&view=rev
Log:
Support 64-bit chunk headers
Modified:
httpcomponents/httpcore/branches/4.4.x/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/ChunkDecoder.java
httpcomponents/httpcore/branches/4.4.x/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestChunkDecoder.java
httpcomponents/httpcore/branches/4.4.x/httpcore/src/main/java/org/apache/http/impl/io/ChunkedInputStream.java
httpcomponents/httpcore/branches/4.4.x/httpcore/src/test/java/org/apache/http/impl/io/TestChunkCoding.java
Modified: httpcomponents/httpcore/branches/4.4.x/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/ChunkDecoder.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/branches/4.4.x/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/ChunkDecoder.java?rev=1737928&r1=1737927&r2=1737928&view=diff
==============================================================================
--- httpcomponents/httpcore/branches/4.4.x/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/ChunkDecoder.java (original)
+++ httpcomponents/httpcore/branches/4.4.x/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/ChunkDecoder.java Wed Apr 6 07:20:23 2016
@@ -65,8 +65,8 @@ public class ChunkDecoder extends Abstra
private boolean endOfStream;
private CharArrayBuffer lineBuf;
- private int chunkSize;
- private int pos;
+ private long chunkSize;
+ private long pos;
private final MessageConstraints constraints;
private final List<CharArrayBuffer> trailerBufs;
@@ -83,8 +83,8 @@ public class ChunkDecoder extends Abstra
final HttpTransportMetricsImpl metrics) {
super(channel, buffer, metrics);
this.state = READ_CONTENT;
- this.chunkSize = -1;
- this.pos = 0;
+ this.chunkSize = -1L;
+ this.pos = 0L;
this.endOfChunk = false;
this.endOfStream = false;
this.constraints = constraints != null ? constraints : MessageConstraints.DEFAULT;
@@ -129,13 +129,13 @@ public class ChunkDecoder extends Abstra
if (separator < 0) {
separator = this.lineBuf.length();
}
+ final String s = this.lineBuf.substringTrimmed(0, separator);
try {
- final String s = this.lineBuf.substringTrimmed(0, separator);
- this.chunkSize = Integer.parseInt(s, 16);
+ this.chunkSize = Long.parseLong(s, 16);
} catch (final NumberFormatException e) {
- throw new MalformedChunkCodingException("Bad chunk header");
+ throw new MalformedChunkCodingException("Bad chunk header: " + s);
}
- this.pos = 0;
+ this.pos = 0L;
} else if (this.endOfStream) {
throw new ConnectionClosedException("Premature end of chunk coded message body: " +
"closing chunk expected");
@@ -193,7 +193,7 @@ public class ChunkDecoder extends Abstra
int totalRead = 0;
while (this.state != COMPLETED) {
- if (!this.buffer.hasData() || this.chunkSize == -1) {
+ if (!this.buffer.hasData() || this.chunkSize == -1L) {
final int bytesRead = fillBufferFromChannel();
if (bytesRead == -1) {
this.endOfStream = true;
@@ -203,21 +203,21 @@ public class ChunkDecoder extends Abstra
switch (this.state) {
case READ_CONTENT:
- if (this.chunkSize == -1) {
+ if (this.chunkSize == -1L) {
readChunkHead();
- if (this.chunkSize == -1) {
+ if (this.chunkSize == -1L) {
// Unable to read a chunk head
return totalRead;
}
- if (this.chunkSize == 0) {
+ if (this.chunkSize == 0L) {
// Last chunk. Read footers
- this.chunkSize = -1;
+ this.chunkSize = -1L;
this.state = READ_FOOTERS;
break;
}
}
- final int maxLen = this.chunkSize - this.pos;
- final int len = this.buffer.read(dst, maxLen);
+ final long maxLen = this.chunkSize - this.pos;
+ final int len = this.buffer.read(dst, (int) Math.min(maxLen, Integer.MAX_VALUE));
if (len > 0) {
this.pos += len;
totalRead += len;
@@ -233,8 +233,8 @@ public class ChunkDecoder extends Abstra
if (this.pos == this.chunkSize) {
// At the end of the chunk
- this.chunkSize = -1;
- this.pos = 0;
+ this.chunkSize = -1L;
+ this.pos = 0L;
this.endOfChunk = true;
break;
}
Modified: httpcomponents/httpcore/branches/4.4.x/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestChunkDecoder.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/branches/4.4.x/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestChunkDecoder.java?rev=1737928&r1=1737927&r2=1737928&view=diff
==============================================================================
--- httpcomponents/httpcore/branches/4.4.x/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestChunkDecoder.java (original)
+++ httpcomponents/httpcore/branches/4.4.x/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestChunkDecoder.java Wed Apr 6 07:20:23 2016
@@ -586,4 +586,24 @@ public class TestChunkDecoder {
decoder.read(null);
}
+ @Test
+ public void testHugeChunk() throws Exception {
+ final String s = "1234567890abcdef\r\n0123456789abcdef";
+ final ReadableByteChannel channel = new ReadableByteChannelMock(
+ new String[] {s}, Consts.ASCII);
+ final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
+ final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+ final ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
+
+ final ByteBuffer dst = ByteBuffer.allocate(4);
+
+ int bytesRead = decoder.read(dst);
+ Assert.assertEquals(4, bytesRead);
+ Assert.assertEquals("0123", CodecTestUtils.convert(dst));
+ dst.clear();
+ bytesRead = decoder.read(dst);
+ Assert.assertEquals(4, bytesRead);
+ Assert.assertEquals("4567", CodecTestUtils.convert(dst));
+ }
+
}
Modified: httpcomponents/httpcore/branches/4.4.x/httpcore/src/main/java/org/apache/http/impl/io/ChunkedInputStream.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/branches/4.4.x/httpcore/src/main/java/org/apache/http/impl/io/ChunkedInputStream.java?rev=1737928&r1=1737927&r2=1737928&view=diff
==============================================================================
--- httpcomponents/httpcore/branches/4.4.x/httpcore/src/main/java/org/apache/http/impl/io/ChunkedInputStream.java (original)
+++ httpcomponents/httpcore/branches/4.4.x/httpcore/src/main/java/org/apache/http/impl/io/ChunkedInputStream.java Wed Apr 6 07:20:23 2016
@@ -76,10 +76,10 @@ public class ChunkedInputStream extends
private int state;
/** The chunk size */
- private int chunkSize;
+ private long chunkSize;
/** The current position within the current chunk */
- private int pos;
+ private long pos;
/** True if we've reached the end of stream */
private boolean eof = false;
@@ -101,7 +101,7 @@ public class ChunkedInputStream extends
public ChunkedInputStream(final SessionInputBuffer in, final MessageConstraints constraints) {
super();
this.in = Args.notNull(in, "Session input buffer");
- this.pos = 0;
+ this.pos = 0L;
this.buffer = new CharArrayBuffer(16);
this.constraints = constraints != null ? constraints : MessageConstraints.DEFAULT;
this.state = CHUNK_LEN;
@@ -120,7 +120,7 @@ public class ChunkedInputStream extends
public int available() throws IOException {
if (this.in instanceof BufferInfo) {
final int len = ((BufferInfo) this.in).length();
- return Math.min(len, this.chunkSize - this.pos);
+ return (int) Math.min(len, this.chunkSize - this.pos);
} else {
return 0;
}
@@ -188,7 +188,7 @@ public class ChunkedInputStream extends
return -1;
}
}
- final int bytesRead = in.read(b, off, Math.min(len, chunkSize - pos));
+ final int bytesRead = in.read(b, off, (int) Math.min(len, chunkSize - pos));
if (bytesRead != -1) {
pos += bytesRead;
if (pos >= chunkSize) {
@@ -225,12 +225,12 @@ public class ChunkedInputStream extends
}
try {
chunkSize = getChunkSize();
- if (chunkSize < 0) {
+ if (chunkSize < 0L) {
throw new MalformedChunkCodingException("Negative chunk size");
}
state = CHUNK_DATA;
- pos = 0;
- if (chunkSize == 0) {
+ pos = 0L;
+ if (chunkSize == 0L) {
eof = true;
parseTrailerHeaders();
}
@@ -245,7 +245,7 @@ public class ChunkedInputStream extends
* comments after a semicolon. The line must end with a CRLF: "a3; some
* comment\r\n" Positions the stream at the start of the next line.
*/
- private int getChunkSize() throws IOException {
+ private long getChunkSize() throws IOException {
final int st = this.state;
switch (st) {
case CHUNK_CRLF:
@@ -272,10 +272,11 @@ public class ChunkedInputStream extends
if (separator < 0) {
separator = this.buffer.length();
}
+ final String s = this.buffer.substringTrimmed(0, separator);
try {
- return Integer.parseInt(this.buffer.substringTrimmed(0, separator), 16);
+ return Long.parseLong(s, 16);
} catch (final NumberFormatException e) {
- throw new MalformedChunkCodingException("Bad chunk header");
+ throw new MalformedChunkCodingException("Bad chunk header: " + s);
}
default:
throw new IllegalStateException("Inconsistent codec state");
Modified: httpcomponents/httpcore/branches/4.4.x/httpcore/src/test/java/org/apache/http/impl/io/TestChunkCoding.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/branches/4.4.x/httpcore/src/test/java/org/apache/http/impl/io/TestChunkCoding.java?rev=1737928&r1=1737927&r2=1737928&view=diff
==============================================================================
--- httpcomponents/httpcore/branches/4.4.x/httpcore/src/test/java/org/apache/http/impl/io/TestChunkCoding.java (original)
+++ httpcomponents/httpcore/branches/4.4.x/httpcore/src/test/java/org/apache/http/impl/io/TestChunkCoding.java Wed Apr 6 07:20:23 2016
@@ -506,5 +506,19 @@ public class TestChunkCoding {
in.close();
}
+ // Test for when buffer is larger than chunk size
+ @Test
+ public void testHugeChunk() throws IOException {
+ final ChunkedInputStream in = new ChunkedInputStream(
+ new SessionInputBufferMock("1234567890abcdef\r\n01234567", Consts.ISO_8859_1));
+ final ByteArrayOutputStream out = new ByteArrayOutputStream();
+ for (int i = 0; i < 8; ++i) {
+ out.write(in.read());
+ }
+
+ final String result = new String(out.toByteArray(), Consts.ISO_8859_1);
+ Assert.assertEquals("01234567", result);
+ }
+
}