Batu Lab NotesPractical developer guides

Read a repeated response header from a local message

By Batu ยท English technical notes

Also published in our primary archive.

Some response headers can occur more than once, so retrieving only one field can discard information. This example parses a local, in-memory header block containing two Set-Cookie fields and one X-Request-Id field. message.get_all("Set-Cookie", []) returns both cookie field values in their header order. The assertions verify that neither cookie disappeared and that the ordinary request identifier remains available through item access.

HeaderParser is a convenient standard-library parser for a complete header block when no message body is needed. Its parsestr input ends with a blank line, which marks the end of headers. get_all returns the provided fallback when a field is absent; using [] gives callers a predictable collection in this example. These message APIs are available in Python 3.3 and later; the explicit policy.default used here is suitable for Python 3.6 and later.

This technique preserves header field strings; it does not implement HTTP response parsing, cookie storage, cookie expiration, or the browser rules for combining Set-Cookie values. In particular, do not join cookies and then treat the result as one Set-Cookie field in production. Apply an HTTP- and cookie-aware policy when the values affect requests or persistent state.

See the official email.parser documentation and email.message documentation. AI assistance disclosure: this article was drafted with AI assistance and should be checked against the application's HTTP handling requirements.

from email import policy
from email.parser import HeaderParser


raw_headers = (
    "Set-Cookie: session=abc; Path=/\n"
    "Set-Cookie: theme=dark; Path=/\n"
    "X-Request-Id: local-42\n"
    "\n"
)
message = HeaderParser(policy=policy.default).parsestr(raw_headers)
cookies = message.get_all("Set-Cookie", [])

assert cookies == ["session=abc; Path=/", "theme=dark; Path=/"]
assert message["X-Request-Id"] == "local-42"

print("cookies=" + " | ".join(cookies))
print("request_id=" + message["X-Request-Id"])
cookies=session=abc; Path=/ | theme=dark; Path=/
request_id=local-42