[
https://issues.apache.org/jira/browse/THRIFT-6193?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Jens Geyer resolved THRIFT-6193.
--------------------------------
Fix Version/s: 0.25.0
Assignee: Jens Geyer
Resolution: Fixed
> 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
> Assignee: Jens Geyer
> Priority: Major
> Fix For: 0.25.0
>
> Time Spent: 20m
> Remaining Estimate: 0h
>
> 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)