Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix FileResponse fallback code #6726

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES/6726.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fixed a bug in ``FileResponse`` fallback code when the requested range is smaller than the chunk size.
1 change: 1 addition & 0 deletions CONTRIBUTORS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ Martin Sucha
Mathias Fröjdman
Mathieu Dugré
Matt VanEseltine
Matthias Dellweg
Matthias Marquardt
Matthieu Hauglustaine
Matthieu Rigal
Expand Down
1 change: 0 additions & 1 deletion aiohttp/http_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,6 @@ async def write(
if self.length >= chunk_len:
self.length = self.length - chunk_len
else:
chunk = chunk[: self.length]
self.length = 0
if not chunk:
return
Expand Down
35 changes: 35 additions & 0 deletions tests/test_web_sendfile_functional.py
Original file line number Diff line number Diff line change
Expand Up @@ -1164,3 +1164,38 @@ async def handler(request: web.Request) -> web.FileResponse:

resp.release()
await client.close()


@pytest.mark.parametrize("chunk_size", (15, 31))
async def test_a_ranged_request_serves_no_additional_bytes(
aiohttp_client: AiohttpClient, sender: _Sender, chunk_size: int
) -> None:
filepath = pathlib.Path(__file__).parent / "aiohttp.jpg"

async def handler(request: web.Request) -> web.FileResponse:
return sender(filepath, chunk_size=chunk_size)

app = web.Application()
app.router.add_get("/", handler)
client = await aiohttp_client(app)

async with await client.get("/", headers={"Range": "bytes=20-40"}) as resp:
assert resp.status == 206
assert resp.headers["content-length"] == "21"
body = await resp.read()

async with await client.get("/", headers={"Range": "bytes=20-40"}) as resp:
assert resp.status == 206
assert resp.headers["content-length"] == "21"
body2 = await resp.read()

# 21 bytes, because http range headers are including both fenceposts.
assert len(body) == 21

# Additionally verify that we are served the right bytes from that file.
with filepath.open("rb") as f:
f.seek(20)
content = f.read(21)
assert content == body

assert body == body2
Loading