Skip to content

Commit 8f50eca

Browse files
committed
Merge request headers case-insensitively
- Switch header merging to `NocaseDict` so per-request headers truly override session defaults regardless of casing. - Ensure the auto-detected Content-Type is only added when no user-supplied variant exists, preventing duplicate header variants. - Expand the helper docstring to clarify the new merge semantics.
1 parent 8cc669c commit 8f50eca

File tree

1 file changed

+23
-9
lines changed

1 file changed

+23
-9
lines changed

async_tls_client/session/request_payload_builder.py

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
from typing import Any, Dict, Optional, TYPE_CHECKING, Tuple, Union
44
from urllib.parse import urlencode, urlparse
55

6+
from nocasedict import NocaseDict
7+
68
if TYPE_CHECKING:
79
from .session import AsyncSession
810

@@ -38,21 +40,33 @@ def _merge_headers(
3840
content_type: Optional[str]
3941
) -> Dict[str, str]:
4042
"""
41-
Merges session headers with request headers, considering Content-Type.
43+
Merge session-level and per-request headers into a single mapping.
4244
43-
Priority:
44-
1. Headers from current request
45-
2. Headers from session
46-
3. Auto-detected Content-Type
45+
Rules:
46+
- Keys are compared case-insensitively during the merge.
47+
- Per-request headers override session headers on key collisions.
48+
- If ``content_type`` is provided and no explicit ``Content-Type`` header
49+
is present (in any casing), it is added as ``content-type``.
50+
51+
Notes:
52+
This function uses ``NocaseDict`` to ensure case-insensitive behavior while
53+
merging. The resulting dictionary is a regular ``dict`` with the key
54+
casing preserved from the last writer for each header.
55+
56+
:param session_headers: Default headers configured on the session.
57+
:param request_headers: Headers supplied for the current request.
58+
:param content_type: MIME type to set as ``Content-Type`` when not already provided.
59+
60+
:returns: A case-insensitively merged dictionary of HTTP headers.
4761
"""
48-
merged = {}
62+
merged = NocaseDict()
4963
if session_headers:
5064
merged.update(session_headers)
5165
if request_headers:
5266
merged.update(request_headers)
53-
if content_type and 'Content-Type' not in merged:
54-
merged['Content-Type'] = content_type
55-
return merged
67+
if content_type and "content-type" not in merged:
68+
merged["content-type"] = content_type
69+
return dict(merged)
5670

5771

5872
def _prepare_cookies(request_url: str,

0 commit comments

Comments
 (0)