Repository navigation
Fix read_chunk() on body parts with a zero Content-Length - #13760
Dreamsorcerer merged 6 commits into
Conversation
read_chunk() picks its read strategy by testing self._length for truthiness, so a part with an explicit Content-Length: 0 (legal outside multipart/form-data, where the RFC 7578 special case nulls the length) fell through to _read_chunk_from_stream(). That path asserts the requested chunk size is at least the boundary length, so callers asking for a small chunk on an empty part hit an AssertionError instead of getting an immediate empty chunk. Test the length against None instead: an empty part now yields an empty chunk and reaches EOF like any other part with a known length. Fixes aio-libs#13758.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #13760 +/- ##
=======================================
Coverage 99.04% 99.04%
=======================================
Files 135 135
Lines 51562 51569 +7
Branches 2696 2696
=======================================
+ Hits 51068 51075 +7
Misses 371 371
Partials 123 123
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. |
|
Merging this PR will not alter performance
Comparing Footnotes
|
a2dd75b to
3fabea9
Compare
Backport to 3.15: 💚 backport PR created✅ Backport PR branch: Backported as #13853 🤖 @patchback |
Backport to 3.14: 💚 backport PR created✅ Backport PR branch: Backported as #13854 🤖 @patchback |
What do these changes do?
BodyPartReader.read_chunk()chose its read strategy by testingself._lengthfor truthiness. A part with an explicitContent-Length: 0(legaloutside
multipart/form-data, where the RFC 7578 special case nulls thelength out) therefore fell through to
_read_chunk_from_stream(), whoseminimum chunk size assertion then failed for chunk sizes below the boundary
length:
The truthiness test now checks against
Noneinstead, so an empty part takesthe length-based path:
read_chunk()returns an immediate empty chunk and thepart reaches EOF, like any other part with a known length. The line dates back
to 2016 (f1351a3), when the stream fallback was introduced.
Are there changes in behavior for developers?
read_chunk(size)on aContent-Length: 0part returnsb""for any sizeinstead of raising
AssertionErrorwhensize < len(boundary) + 2.read()/release()on such parts already worked with the default chunksize (which satisfies the assertion by accident) and are unaffected beyond
now being correct for small configured chunk sizes too.
multipart/form-dataparts are unchanged: theirContent-Lengthheader isignored per RFC 7578 §4.8,
_lengthstaysNone, and the stream fallbackstill applies.
Content-Length) are unchanged:_length is Noneroutesthem to
_read_chunk_from_stream()exactly as before.Passing a negative chunk size remains a preexisting wart of the length-based
path (it makes the underlying
read()drain the remaining stream beforefailing); it affects parts with a positive
Content-Lengthon master thesame way and is out of scope here.
Checklist
CONTRIBUTORS.txt(added in this PR)CHANGES/folder (PR number will follow once opened)Fixes #13758.