Skip to content

Commit ab1b252

Browse files
authored
Parse entire HTTP chunk size apache#396 (apache#528)
* Parse entire HTTP chunk size apache#396 Continue parsing HTTP chunk size up until Int.MaxValue so the actual size of the chunk can be logged if it exceeds the configured max chunk size. * Add reference to Integer.MAX_VALUE in the error message * Fix formatting
1 parent 8eb3a50 commit ab1b252

File tree

2 files changed

+19
-5
lines changed

2 files changed

+19
-5
lines changed

http-core/src/main/scala/org/apache/pekko/http/impl/engine/parsing/HttpMessageParser.scala

+6-3
Original file line numberDiff line numberDiff line change
@@ -307,17 +307,20 @@ private[http] trait HttpMessageParser[Output >: MessageOutput <: ParserOutput] {
307307
s"HTTP chunk extension length exceeds configured limit of ${settings.maxChunkExtLength} characters")
308308

309309
@tailrec def parseSize(cursor: Int, size: Long): StateResult =
310-
if (size <= settings.maxChunkSize) {
310+
if (size <= Int.MaxValue) {
311311
byteChar(input, cursor) match {
312312
case c if CharacterClasses.HEXDIG(c) => parseSize(cursor + 1, size * 16 + CharUtils.hexValue(c))
313-
case ';' if cursor > offset => parseChunkExtensions(size.toInt, cursor + 1)()
313+
case c if size > settings.maxChunkSize =>
314+
failEntityStream(
315+
s"HTTP chunk of $size bytes exceeds the configured limit of ${settings.maxChunkSize} bytes")
316+
case ';' if cursor > offset => parseChunkExtensions(size.toInt, cursor + 1)()
314317
case '\r' if cursor > offset && byteChar(input, cursor + 1) == '\n' =>
315318
parseChunkBody(size.toInt, "", cursor + 2)
316319
case '\n' if cursor > offset => parseChunkBody(size.toInt, "", cursor + 1)
317320
case c if CharacterClasses.WSP(c) => parseSize(cursor + 1, size) // illegal according to the spec but can happen, see issue #1812
318321
case c => failEntityStream(s"Illegal character '${escape(c)}' in chunk start")
319322
}
320-
} else failEntityStream(s"HTTP chunk size exceeds the configured limit of ${settings.maxChunkSize} bytes")
323+
} else failEntityStream(s"HTTP chunk size exceeds Integer.MAX_VALUE (${Int.MaxValue}) bytes")
321324

322325
try parseSize(offset, 0)
323326
catch {

http-core/src/test/scala/org/apache/pekko/http/impl/engine/parsing/RequestParserSpec.scala

+13-2
Original file line numberDiff line numberDiff line change
@@ -531,13 +531,24 @@ abstract class RequestParserSpec(mode: String, newLine: String) extends AnyFreeS
531531
closeAfterResponseCompletion shouldEqual Seq(false)
532532
}
533533

534-
"too-large chunk size" in new Test {
534+
"too-large chunk size (> Int.MaxValue)" in new Test {
535535
Seq(
536536
start,
537537
"""1a2b3c4d5e
538538
|""") should generalMultiParseTo(
539539
Right(baseRequest),
540-
Left(EntityStreamError(ErrorInfo("HTTP chunk size exceeds the configured limit of 1048576 bytes"))))
540+
Left(EntityStreamError(ErrorInfo("HTTP chunk size exceeds Integer.MAX_VALUE (2147483647) bytes"))))
541+
closeAfterResponseCompletion shouldEqual Seq(false)
542+
}
543+
544+
"too-large chunk size" in new Test {
545+
Seq(
546+
start,
547+
"""400000
548+
|""") should generalMultiParseTo(
549+
Right(baseRequest),
550+
Left(
551+
EntityStreamError(ErrorInfo("HTTP chunk of 4194304 bytes exceeds the configured limit of 1048576 bytes"))))
541552
closeAfterResponseCompletion shouldEqual Seq(false)
542553
}
543554

0 commit comments

Comments
 (0)