aiohttp
aiohttp copied to clipboard
Enabling gzip compression throws exception on 204 No content responses
Long story short
I've enabled gzip compression like that but it throws exception on 204 responses
Expected behaviour
Do not throw exception if body is absent
Actual behaviour
Traceback (most recent call last):
File "my_awesome_project/venv/lib/python3.6/site-packages/aiohttp/web_protocol.py", line 398, in start
await resp.prepare(request)
File "my_awesome_project/venv/lib/python3.6/site-packages/aiohttp/web_response.py", line 300, in prepare
return await self._start(request)
File "my_awesome_project/venv/lib/python3.6/site-packages/aiohttp/web_response.py", line 605, in _start
return await super()._start(request)
File "my_awesome_project/venv/lib/python3.6/site-packages/aiohttp/web_response.py", line 329, in _start
self._start_compression(request)
File "my_awesome_project/venv/lib/python3.6/site-packages/aiohttp/web_response.py", line 290, in _start_compression
self._do_start_compression(coding)
File "my_awesome_project/venv/lib/python3.6/site-packages/aiohttp/web_response.py", line 616, in _do_start_compression
self._compressed_body = compressobj.compress(self._body) +\
TypeError: a bytes-like object is required, not 'NoneType'
Steps to reproduce
async def enable_compression(request, response):
response.enable_compression()
....
app.on_response_prepare.append(remove_server_header)
....
but when I do
async def whatever(request):
raise web.HTTPNoContent()
exception above happens
Your environment
python 3.6.5 aiohttp (both) 3.3.2 MacOS 10.13.5 (17F77)
from aiohttp import web
async def enable_compression(request, response):
# Only enable compression if response has a body
if response.body is not None:
response.enable_compression()
async def remove_server_header(request, response):
response.headers.pop('Server', None)
async def whatever(request):
raise web.HTTPNoContent()
app = web.Application()
app.on_response_prepare.append(enable_compression)
app.on_response_prepare.append(remove_server_header)
app.router.add_get('/', whatever)
if __name__ == '__main__':
web.run_app(app)
I suspect this assert should be changed to be part of the if statement: https://github.com/aio-libs/aiohttp/blob/0ec65c0f4dc08d027f659256b09ae9cff10ab404/aiohttp/web_response.py#L707
If someone can add a test that reproduces the issue with a 204 response, then we can fix that.