Server static handler includes body for HEAD response #4809
Description
🐞 Describe the bug
When using web.static to serve static content, the server responds to HEAD requests as if they were GET requests i.e. it includes a body with the file content. Apart from wasting bandwidth, this completely breaks pipelined connections because the content appears where the client is expecting to see the response headers for the next request. Possibly it may cause security issues too if an attacker can control the content because they could then deliver arbitrary headers to a client.
💡 To Reproduce
Put the script below in a file called ah.py and run it (it will serve the directory it is in on :8080).
#!/usr/bin/env python3
import os
import aiohttp.web as web
app = web.Application()
app.add_routes([web.static('/', os.path.dirname(os.path.realpath(__file__)))])
web.run_app(app)While it's running, run echo -e 'HEAD /ah.py HTTP/1.1\nHost: localhost:8080\n' | nc localhost 8080 (assumes bash shell for echo -e). It will output something like
HTTP/1.1 200 OK
Content-Type: text/x-python
Last-Modified: Wed, 10 Jun 2020 10:02:34 GMT
Content-Length: 182
Accept-Ranges: bytes
Date: Wed, 10 Jun 2020 10:11:13 GMT
Server: Python/3.6 aiohttp/3.6.2
#!/usr/bin/env python3
import os
import aiohttp.web as web
app = web.Application()
app.add_routes([web.static('/', os.path.dirname(os.path.realpath(__file__)))])
web.run_app(app)
💡 Expected behavior
It should not output any body because it is a HEAD request.
📋 Your version of the Python
$ python --version
python 3.6.6📋 Your version of the aiohttp/yarl/multidict distributions
$ python -m pip show aiohttp
Version: 3.6.2$ python -m pip show multidict
Version: 4.7.6$ python -m pip show yarl
Version: 1.4.2