This commit is contained in:
Fridayworks 2026-02-24 14:26:02 -05:00 committed by GitHub
commit 380e318ee6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 23 additions and 4 deletions

View File

@ -71,7 +71,9 @@ def _normalize_header_key(key: str | bytes, encoding: str | None = None) -> byte
return key if isinstance(key, bytes) else key.encode(encoding or "ascii")
def _normalize_header_value(value: str | bytes, encoding: str | None = None) -> bytes:
def _normalize_header_value(
value: str | bytes, encoding: str | None = None, name: str | bytes = ""
) -> bytes:
"""
Coerce str/bytes into a strictly byte-wise HTTP header value.
"""
@ -79,7 +81,18 @@ def _normalize_header_value(value: str | bytes, encoding: str | None = None) ->
return value
if not isinstance(value, str):
raise TypeError(f"Header value must be str or bytes, not {type(value)}")
return value.encode(encoding or "ascii")
try:
return value.encode(encoding or "ascii")
except UnicodeEncodeError as exc:
if name:
raise UnicodeEncodeError(
exc.encoding,
exc.object,
exc.start,
exc.end,
f"{exc.reason} (header: {name!r})",
) from None
raise
def _parse_content_type_charset(content_type: str) -> str | None:
@ -153,12 +166,12 @@ class Headers(typing.MutableMapping[str, str]):
elif isinstance(headers, Mapping):
for k, v in headers.items():
bytes_key = _normalize_header_key(k, encoding)
bytes_value = _normalize_header_value(v, encoding)
bytes_value = _normalize_header_value(v, encoding, name=k)
self._list.append((bytes_key, bytes_key.lower(), bytes_value))
elif headers is not None:
for k, v in headers:
bytes_key = _normalize_header_key(k, encoding)
bytes_value = _normalize_header_value(v, encoding)
bytes_value = _normalize_header_value(v, encoding, name=k)
self._list.append((bytes_key, bytes_key.lower(), bytes_value))
self._encoding = encoding

View File

@ -214,6 +214,12 @@ def test_parse_header_links(value, expected):
assert all(link in all_links for link in expected)
def test_header_encoding_error_includes_name():
# https://github.com/encode/httpx/issues/3400
with pytest.raises(UnicodeEncodeError, match="header: 'auth'"):
httpx.Headers({"auth": "\u0437\u0434\u0440\u0430\u0432\u0435\u0439"})
def test_parse_header_links_no_link():
all_links = httpx.Response(200).links
assert all_links == {}