[
https://issues.apache.org/jira/browse/THRIFT-6161?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Jens Geyer reassigned THRIFT-6161:
----------------------------------
Assignee: Jens Geyer
> Haxe TStreamTransport does not charge reads against MaxMessageSize
> ------------------------------------------------------------------
>
> Key: THRIFT-6161
> URL: https://issues.apache.org/jira/browse/THRIFT-6161
> Project: Thrift
> Issue Type: Bug
> Components: Haxe - Library
> Reporter: Jens Geyer
> Assignee: Jens Geyer
> Priority: Major
> Fix For: 0.25.0
>
> Time Spent: 10m
> Remaining Estimate: 0h
>
> h3. Problem
> {{TStreamTransport}} does not charge reads against the message budget, so
> MaxMessageSize has
> no effect on a stream-backed connection however much a message reads, as long
> as no single
> read exceeds the limit on its own. Its {{flush()}} does not restore the
> allowance either.
> h3. Why this is a defect in Haxe specifically
> There is no single convention across the bindings — there are three, and
> every other binding
> keeps to one of them:
> * *cpp, c_glib* — no endpoint charges reads (only the zlib transport does);
> reads are bounded by frame binding and the per-read check alone.
> * *java, netstd* — stream and socket endpoints do not charge; endpoints that
> know the message boundary do ({{THttpClient}} / {{THttpTransport}}, named
> pipes, a memory buffer holding one message).
> * *delphi* — every endpoint charges.
> Haxe is the only binding that departs from its own convention. It has four
> endpoint transports:
> {{TSocket}} charges (three sites), {{THttpClient}} charges,
> {{TFullDuplexHttpClient}} charges,
> and {{TStreamTransport}} charges nothing. The binding's design intends
> endpoints to charge, and
> this one silently opts out.
> {{doc/specs/thrift-tconfiguration.md}} describes MaxMessageSize as "a general
> device to be used
> with any transport or protocol", expressed as the bytes *remaining* to be
> read — which only
> means something if reads draw it down.
> h3. Fix
> Two coordinated changes, mirroring {{TSocket}}:
> * {{read()}} charges what it read.
> * {{flush()}} resets the allowance, at the same point {{TSocket}} does.
> Both are needed. Charging without resetting would leave the budget only ever
> shrinking, so a
> long-lived connection would run itself out of it — which is THRIFT-6160,
> fixed just before this.
> h3. Tests
> Two, in {{StreamTest}}, failing before and passing after. The first reads
> past the limit 32 bytes
> at a time, so nothing but cumulative accounting can catch it; the second
> checks the allowance comes
> back. Verified on neko (full suite, including the existing stream, constants
> and recursion-limit
> tests, all of which read through {{TStreamTransport}}); the python and php
> targets cross-compile
> clean.
> _Drafted with AI assistance (Claude Opus 5); reviewed and filed by Jens
> Geyer._
--
This message was sent by Atlassian Jira
(v8.20.10#820010)