Skip to content

parse_content_disposition ignores whitespace around disposition type, rejecting valid headers #12996

Description

@JSap0914

Describe the bug

parse_content_disposition (in aiohttp/multipart.py) does not strip whitespace from the disposition type (the part before the first ;) before checking whether it is a valid token. RFC 7230 permits optional whitespace (OWS) around separators, so a header value like form-data ; name="field" (space before the semicolon) is technically conforming—yet aiohttp rejects it entirely, emitting a BadContentDispositionHeader warning and returning (None, {}) instead of ('form-data', {'name': 'field'}).

To Reproduce

import warnings
from aiohttp.multipart import parse_content_disposition, BadContentDispositionHeader

# Space before the first semicolon — valid per RFC 7230 BWS rules
with warnings.catch_warnings(record=True) as w:
    warnings.simplefilter('always')
    disptype, params = parse_content_disposition('form-data ; name="field"')

print(disptype, params)  # None {}  ← bug; should be ('form-data', {'name': 'field'})
print(w[0].category.__name__ if w else 'no warning')  # BadContentDispositionHeader

Expected behavior

Trailing (and leading) whitespace on the disposition type is stripped before validation, consistent with how parameter keys are already handled (key = key.lower().strip()):

disptype='form-data'  params={'name': 'field'}

Root cause

In parse_content_disposition:

disptype, *parts = header.split(";")
if not is_token(disptype):       # ← disptype not stripped; 'form-data ' fails is_token
    warnings.warn(BadContentDispositionHeader(header))
    return None, {}

The fix is a single line: disptype = disptype.strip() before the is_token check.

aiohttp Version

master (7987bd2)

Python Version

3.12

Related component

multipart / content-disposition parsing

Code of Conduct

  • I agree to follow the aio-libs Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions