Merge a23676eecf into b5addb64f0
This commit is contained in:
commit
380e318ee6
@ -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
|
||||
|
||||
@ -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 == {}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user