Description
Describe the bug
If a web.FileResponse() is used to send an empty file, then the following stack trace is raise...
File \"/usr/local/lib/python3.8/dist-packages/aiohttp/web_protocol.py\", line 485, in start
resp, reset = await task
File \"/usr/local/lib/python3.8/dist-packages/aiohttp/web_protocol.py\", line 440, in _handle_request
reset = await self.finish_response(request, resp, start_time)
File \"/usr/local/lib/python3.8/dist-packages/aiohttp/web_protocol.py\", line 591, in finish_response
await prepare_meth(request)
File \"/usr/local/lib/python3.8/dist-packages/aiohttp/web_fileresponse.py\", line 241, in prepare
return await self._sendfile(request, fobj, offset, count)
File \"/usr/local/lib/python3.8/dist-packages/aiohttp/web_fileresponse.py\", line 96, in _sendfile
await loop.sendfile(transport, fobj, offset, count)
File \"/usr/lib/python3.8/asyncio/base_events.py\", line 1120, in sendfile
return await self._sendfile_native(transport, file,
File \"/usr/lib/python3.8/asyncio/selector_events.py\", line 578, in _sendfile_native
return await self.sock_sendfile(transp._sock, file, offset, count,
File \"/usr/lib/python3.8/asyncio/base_events.py\", line 836, in sock_sendfile
self._check_sendfile_params(sock, file, offset, count)
File \"/usr/lib/python3.8/asyncio/base_events.py\", line 889, in _check_sendfile_params
raise ValueError(
So, it's actually an error to call asyncio's sendfile() function with 0 bytes.. which seems like something they would have short-circuited on purpose, but apparently have not.
Nevertheless, it was easily fixed in web.file_response.py ~96 just to add an if count > 0
around calling sendfile. And that resulted in the expected 200 response with content-length of 0.
To Reproduce
return web.FileResponse(path="/dev/null")
or
return web.FileResponse(path="/path/to/requested-resource/that-happens/to-have-zero-size")
Expected behavior
correct 200 response just with 0 length.
Logs/tracebacks
File \"/usr/local/lib/python3.8/dist-packages/aiohttp/web_protocol.py\", line 485, in start
resp, reset = await task
File \"/usr/local/lib/python3.8/dist-packages/aiohttp/web_protocol.py\", line 440, in _handle_request
reset = await self.finish_response(request, resp, start_time)
File \"/usr/local/lib/python3.8/dist-packages/aiohttp/web_protocol.py\", line 591, in finish_response
await prepare_meth(request)
File \"/usr/local/lib/python3.8/dist-packages/aiohttp/web_fileresponse.py\", line 241, in prepare
return await self._sendfile(request, fobj, offset, count)
File \"/usr/local/lib/python3.8/dist-packages/aiohttp/web_fileresponse.py\", line 96, in _sendfile
await loop.sendfile(transport, fobj, offset, count)
File \"/usr/lib/python3.8/asyncio/base_events.py\", line 1120, in sendfile
return await self._sendfile_native(transport, file,
File \"/usr/lib/python3.8/asyncio/selector_events.py\", line 578, in _sendfile_native
return await self.sock_sendfile(transp._sock, file, offset, count,
File \"/usr/lib/python3.8/asyncio/base_events.py\", line 836, in sock_sendfile
self._check_sendfile_params(sock, file, offset, count)
File \"/usr/lib/python3.8/asyncio/base_events.py\", line 889, in _check_sendfile_params
raise ValueError(
Python Version
$ python --version
Python 3.8.10
aiohttp Version
$ python -m pip show aiohttp
Name: aiohttp
Version: 3.8.4
Summary: Async http client/server framework (asyncio)
Home-page: https://github.com/aio-libs/aiohttp
Author: None
Author-email: None
License: Apache 2
Location: /usr/local/lib/python3.8/dist-packages
Requires: charset-normalizer, frozenlist, attrs, async-timeout, multidict, aiosignal, yarl
Required-by: pyht, keycloak-api, htdm, aiohttp-jinja2
multidict Version
$ python -m pip show multidict
Name: multidict
Version: 6.0.4
Summary: multidict implementation
Home-page: https://github.com/aio-libs/multidict
Author: Andrew Svetlov
Author-email: [email protected]
License: Apache 2
Location: /usr/local/lib/python3.8/dist-packages
Requires:
Required-by: yarl, aiohttp
yarl Version
$ python -m pip show yarl
Name: yarl
Version: 1.8.2
Summary: Yet another URL library
Home-page: https://github.com/aio-libs/yarl/
Author: Andrew Svetlov
Author-email: [email protected]
License: Apache 2
Location: /usr/local/lib/python3.8/dist-packages
Requires: multidict, idna
Required-by: aiohttp
OS
uname -a
Linux myhost 5.10.0-0.deb10.17-amd64 #1 SMP Debian 5.10.136-1~deb10u3 (2022-09-06) x86_64 x86_64 x86_64 GNU/Linux
Related component
Server
Additional context
No response
Code of Conduct
- I agree to follow the aio-libs Code of Conduct