Jens Geyer created THRIFT-6193:
----------------------------------
Summary: The C++ HTTP transport does not hold the message body to
maxMessageSize
Key: THRIFT-6193
URL: https://issues.apache.org/jira/browse/THRIFT-6193
Project: Thrift
Issue Type: Bug
Components: C++ - Library
Reporter: Jens Geyer
h2. What happens
{{THttpTransport::readContent()}} accumulates the body into {{readBuffer_}} in
a read loop.
Nothing measures it against anything: the declared {{Content-Length}}, and in a
chunked body the
number of chunks, are numbers the peer chooses.
It is wider than one missing check. {{countConsumedMessageBytes()}} is never
called anywhere in
this transport -- {{grep}} over {{THttp*.\{h,cpp\}}} finds three
{{resetConsumedMessageSize()}}
and one {{checkReadBytesAvailable(len)}} in {{read()}}. So
{{remainingMessageSize_}} is reset and
never decremented, and the check in {{read()}} is a ceiling on a single caller
request against an
allowance that never depletes.
The body does not pass through the line buffer whose growth was bounded in a
previous change, so
that bound does not cover this.
h2. Measured
With {{maxMessageSize}} at its 100 MB default, against the unmodified library:
||Scenario||Peer served||Outcome||VmPeak||VmHWM||
|{{Content-length: -1}}, nothing sent after the headers|39 B|{{Could not refill
buffer}}|+0 kB|+92 kB|
|{{Content-length: -1}}, then 200 MB sent|209715239 B|same|+262228 kB|+205820
kB|
Nothing is sized from the declared length up front, so a large declaration on
its own costs
nothing. What is not held is the accumulation: 200 MB arrived in one message
against a 100 MB
configured maximum, and a chunked body has no declared total at all and simply
runs until the
peer stops sending.
h2. Fix shape
{{readContent()}} charges what it is about to read against {{maxMessageSize}}
and refuses the
message once it would exceed it, with the running total reset by
{{readHeaders()}} so that each
message on a keep-alive connection gets its own allowance.
h2. Behaviour change
A client or server exchanging bodies larger than the configured maximum has to
raise it, the way
it would for any other transport. Release note included with the patch.
_Filed with AI assistance (Claude Opus 5); reviewed and filed by Jens Geyer._
--
This message was sent by Atlassian Jira
(v8.20.10#820010)