[ 
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)

Reply via email to