-
-
Notifications
You must be signed in to change notification settings - Fork 2k
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
base: master
Are you sure you want to change the base?
Conversation
b325660
to
40b52d1
Compare
40b52d1
to
e6d8d76
Compare
Hi, @mdellweg, this issue is still relevant? |
I would guess so. |
e6d8d76
to
03bb3f0
Compare
@mdellweg, Since there has been no activity over the past year can you send an code example in which such a issue occurs. Also you need fill CONTRIBUTORS.txt.and change unit test. |
As mentioned, this still needs a regression test. It should go in test_sendfile_functional.py and use the |
In case the FileResponse is using _sendfile_fallback and the requested range is smaller then the chunk size, we need to only read and send count bytes.
03bb3f0
to
0ac82e1
Compare
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #6726 +/- ##
=======================================
Coverage 98.77% 98.77%
=======================================
Files 122 122
Lines 37038 37054 +16
Branches 2041 2041
=======================================
+ Hits 36585 36601 +16
Misses 314 314
Partials 139 139
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
CodSpeed Performance ReportMerging #6726 will not alter performanceComparing Summary
|
I added a test. How should I proceed? [0] https://github.com/aio-libs/aiohttp/blob/master/aiohttp/http_writer.py#L126 |
Check the headers. Seems like Content-Length may be set here: aiohttp/aiohttp/web_fileresponse.py Line 396 in 237d467
So, if that contains the correct length for the range, then the client should only read that amount of data. If there's actually more data sent than the header says, then reading the next response should produce an error. So, you could adapt the test to try sending and receiving 2 range requests in a row. |
resp = await client.get("/", headers={"Range": "bytes=20-40"}) | ||
assert resp.status == 206 | ||
body = await resp.read() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It may also be important to use the context manager correctly if we want to test 2 requests in a row.
resp = await client.get("/", headers={"Range": "bytes=20-40"}) | |
assert resp.status == 206 | |
body = await resp.read() | |
async with client.get("/", headers={"Range": "bytes=20-40"}) as resp: | |
assert resp.status == 206 | |
body = await resp.read() |
Actually, looking at the code you've edited. Isn't it already doing that in the next couple of lines: aiohttp/aiohttp/web_fileresponse.py Line 121 in 237d467
I think that code cuts it to the correct length. So, your min() is probably not making any difference functionally. It might save reading a little bit of data when it doesn't need it, but wastes a function call when it does, so I'm not clear if it would be more efficient or not. |
That is the line right after reading and handing down the too big chunk. |
Ah, yes, it writes the existing chunk first. So, actually still seems like your fix might be relevant. Did you try the test with 2 range requests in a row? |
I'll have a shot. |
Trying to demonstrate that the test will not even fail when too many bytes are sent.
Not sure if that's what you meant (looking at the test). |
I think the client should definitely be hitting an error there if there's actually more data sent. Have you tried curl or any other clients and seen it sending more data? |
No, I haven't. But also by this time, I think aiohttp is doing the right thing (see where i broke the writer too). I would have been happy to contribute at least the test to show that it is. But if it can't get it red it's not testing anything. |
All Python versions we support implement sendfile fallback internally now. So you would likely have to set the env var to reach the fallback code |
Also we have been discussing dropping the aiohttp implementation now that asyncio does it for us |
In case the FileResponse is using _sendfile_fallback and the requested
range is smaller then the chunk size, we need to only read and send
count bytes.
What do these changes do?
Are there changes in behavior for the user?
Related issue number
Checklist
CONTRIBUTORS.txt
CHANGES
folder<issue_id>.<type>
for example (588.bugfix)issue_id
change it to the pr id after creating the pr.feature
: Signifying a new feature..bugfix
: Signifying a bug fix..doc
: Signifying a documentation improvement..removal
: Signifying a deprecation or removal of public API..misc
: A ticket has been closed, but it is not of interest to users.