Skip to content

Accept case-insensitive range unit names in http_range - #13581

Open
Manny7717 wants to merge 2 commits into
aio-libs:masterfrom
Manny7717:fix/http-range-case-insensitive
Open

Accept case-insensitive range unit names in http_range#13581
Manny7717 wants to merge 2 commits into
aio-libs:masterfrom
Manny7717:fix/http-range-case-insensitive

Conversation

@Manny7717

Copy link
Copy Markdown

What do these changes do?

BaseRequest.http_range now matches the range unit name case-insensitively (re.IGNORECASE), per RFC 9110 §14.1.1 ("All range unit names are case-insensitive").

Previously a valid header like Range: Bytes=0-499 failed the ^bytes=(\d*)-(\d*)$ regex, raising ValueError("range not in acceptable format"), which FileResponse converts into 416 Requested Range Not Satisfiable — even for a perfectly satisfiable range. Only lowercase bytes= worked.

Are there changes in behavior for the user?

Yes, for the better: case variants of the range unit (Bytes, BYTES, bYtEs, …) are now accepted and yield 206 Partial Content where lowercase already did. Behavior for lowercase bytes= and for genuinely malformed ranges (non-bytes units, non-numeric bounds, multi-range, empty) is unchanged — those still raise the same ValueError.

Is it a substantial burden for the maintainers to support this?

No. One regex flag; no API surface change; the pure-Python http_range property is the only code path touched. FileResponse consumes it, so the fix propagates automatically.

Related issue number

Fixes #13580

Checklist

  • I think the code is well written
  • Unit tests for the changes exist
  • Documentation reflects the changes (N/A — bug fix, no user-facing docs to update; CHANGES fragment added)
  • If you provide code modification, please add yourself to CONTRIBUTORS.txt
    • The format is .
    • Please keep alphabetical order, the file is sorted by names.
  • Add a new news fragment into the CHANGES/ folder
    • name it <issue_or_pr_num>.<type>.rst (e.g. 588.bugfix.rst)
    • if you don't have an issue number, change it to the pull request number after creating the PR
    • .bugfix: A bug fix for something the maintainers deemed an improper undesired behavior that got corrected to match pre-agreed expectations.
Test output
$ python -m pytest -o addopts="" -p no:aiohttp tests/test_web_request.py -q
143 passed in 0.68s

(10 of those are the http_range/range parsing tests, including the new test_range_to_slice_uppercase_unit.)

End-to-end repro (local web.FileResponse server, raw TCP requests):

Range: bytes=0-3   -> HTTP/1.1 206 Partial Content      (control)
Range: Bytes=0-3   -> HTTP/1.1 206 Partial Content      (fixed; was 416)
Range: BYTES=0-3   -> HTTP/1.1 206 Partial Content      (fixed; was 416)

Drafted with Hermes Agent (deepseek-v4-flash); reviewed by Manny7717.

Range unit names are case-insensitive per RFC 9110 section 14.1.1.
The previous regex only matched lowercase 'bytes', so valid headers
like 'Range: Bytes=0-499' raised ValueError and made FileResponse
return 416 for satisfiable ranges.
@psf-chronographer psf-chronographer Bot added the bot:chronographer:provided There is a change note present in this PR label Aug 29, 2026
@codecov

codecov Bot commented Aug 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.02%. Comparing base (20acdf4) to head (d4c8eef).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##           master   #13581   +/-   ##
=======================================
  Coverage   99.02%   99.02%           
=======================================
  Files         135      135           
  Lines       50500    50504    +4     
  Branches     2652     2652           
=======================================
+ Hits        50007    50011    +4     
  Misses        370      370           
  Partials      123      123           
Flag Coverage Δ
Autobahn 22.03% <20.00%> (+<0.01%) ⬆️
CI-GHA 98.91% <100.00%> (+<0.01%) ⬆️
OS-Linux 98.68% <100.00%> (+<0.01%) ⬆️
OS-Windows 97.09% <100.00%> (+<0.01%) ⬆️
OS-macOS 97.97% <100.00%> (+<0.01%) ⬆️
Py-3.10 98.10% <100.00%> (-0.01%) ⬇️
Py-3.11 98.34% <100.00%> (+<0.01%) ⬆️
Py-3.12 98.43% <100.00%> (+<0.01%) ⬆️
Py-3.13 98.42% <100.00%> (+0.01%) ⬆️
Py-3.14 98.45% <100.00%> (+<0.01%) ⬆️
Py-3.14t 97.61% <100.00%> (-0.01%) ⬇️
Py-pypy-3.11 97.40% <100.00%> (+0.01%) ⬆️
VM-macos 97.97% <100.00%> (+<0.01%) ⬆️
VM-ubuntu 98.68% <100.00%> (+<0.01%) ⬆️
VM-windows 97.09% <100.00%> (+<0.01%) ⬆️
cython-coverage 83.07% <0.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

@codspeed-hq

codspeed-hq Bot commented Aug 29, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 96 untouched benchmarks
⏩ 83 skipped benchmarks1


Comparing Manny7717:fix/http-range-case-insensitive (d4c8eef) with master (20acdf4)

Open in CodSpeed

Footnotes

  1. 83 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@Manny7717
Manny7717 marked this pull request as ready for review August 29, 2026 04:19
@greptile-apps

greptile-apps Bot commented Aug 29, 2026

Copy link
Copy Markdown

Confidence Score: 5/5

The PR appears safe to merge with no actionable correctness, compatibility, or security issues identified.

The regex flag affects only the casing of the literal bytes token, retains ASCII numeric matching and the existing validation paths, and is covered by a focused regression test; no consumers in the related repositories use the modified property.

Reviews (1): Last reviewed commit: "Add PR-numbered news fragment symlink" | Re-trigger Greptile

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bot:chronographer:provided There is a change note present in this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

http_range rejects valid case-insensitive range unit names (Range: Bytes=… → 416)

1 participant