|
3 | 3 | from typing import Any, Dict, Optional, TYPE_CHECKING, Tuple, Union |
4 | 4 | from urllib.parse import urlencode, urlparse |
5 | 5 |
|
| 6 | +from nocasedict import NocaseDict |
| 7 | + |
6 | 8 | if TYPE_CHECKING: |
7 | 9 | from .session import AsyncSession |
8 | 10 |
|
@@ -38,21 +40,33 @@ def _merge_headers( |
38 | 40 | content_type: Optional[str] |
39 | 41 | ) -> Dict[str, str]: |
40 | 42 | """ |
41 | | - Merges session headers with request headers, considering Content-Type. |
| 43 | + Merge session-level and per-request headers into a single mapping. |
42 | 44 |
|
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. |
47 | 61 | """ |
48 | | - merged = {} |
| 62 | + merged = NocaseDict() |
49 | 63 | if session_headers: |
50 | 64 | merged.update(session_headers) |
51 | 65 | if request_headers: |
52 | 66 | 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) |
56 | 70 |
|
57 | 71 |
|
58 | 72 | def _prepare_cookies(request_url: str, |
|
0 commit comments