Skip to content

Problems with HEAD responses #820

@lgelo

Description

@lgelo

RFC7231 forbids sending body content when responding to HEAD requests. Believing that servers are RFC compliant, aiohttp client is not parsing body of HEAD responses. Content of body stays in buffer and when parsing next response from the same session/connection BadStatusLine is raised. Not all servers are compliant, and unfortunately aiohttp server is one of them. Example code is bellow.

I believe the correct behaviour should be according to Postel's law: server won't send body in response to HEAD and will read and discard (maybe with warning) non-compliant responses.

#!/usr/bin/env python3.5

import asyncio
import aiohttp
from aiohttp import web

async def client(session):
    resp = await session.head('http://127.0.0.1:5000/')
    print("%d: '%s'" % (resp.status, await resp.text()))
    resp.release()

    # so far so good - try again
    resp = await session.get('http://127.0.0.1:5000/')
    print("%d: '%s'" % (resp.status, await resp.text()))
    await resp.release()

async def server(loop):
    app = web.Application()
    handler = app.make_handler()
    srv = await loop.create_server(handler, '127.0.0.1', 5000)
    return srv, handler

loop = asyncio.get_event_loop()
session = aiohttp.ClientSession(loop=loop)

srv, handler = loop.run_until_complete(server(loop))

client = loop.run_until_complete(client(session))
session.close()

loop.stop()
loop.close()

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions