FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

fix(net): preserve custom content type regardless of header casing (#97) · pythonnative/pythonnative@d902e5e · GitHub

Commit d902e5e

Browse files
fix(net): preserve custom content type regardless of header casing (#97)
Refs: #87 Co-authored-by: Owen Carey <37121709+owenthcarey@users.noreply.github.com>
1 parent 8da8fd6 commit d902e5e

2 files changed

Lines changed: 38 additions & 3 deletions

File tree

‎src/pythonnative/net.py‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ async def fetch(
147147
148148
Args:
149149
url: Target URL. Relative URLs are not supported.
150-
method: HTTP method (``"GET"``, ``"POST"``, ``"PUT"`` …).
150+
method: HTTP method (``GET``, ``POST``, ``PUT`` …).
151151
headers: Optional request headers.
152152
body: Request body. ``bytes`` are sent as-is; ``str`` is
153153
UTF-8 encoded; ``dict`` is JSON-encoded with a
@@ -203,7 +203,8 @@ def _build_request(
203203
payload = body.encode("utf-8")
204204
elif isinstance(body, Mapping):
205205
payload = json.dumps(body, default=str).encode("utf-8")
206-
header_dict.setdefault("Content-Type", "application/json")
206+
if not any(name.lower() == "content-type" for name in header_dict):
207+
header_dict["Content-Type"] = "application/json"
207208
else:
208209
raise TypeError(f"Unsupported body type: {type(body)!r}")
209210

‎tests/test_net.py‎

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
import pytest
1313

14-
from pythonnative.net import HTTPError, Response, fetch
14+
from pythonnative.net import HTTPError, Response, _build_request, fetch
1515

1616
# ======================================================================
1717
# Mini HTTP server fixture
@@ -198,3 +198,37 @@ async def run() -> Response:
198198

199199
with pytest.raises(OSError):
200200
asyncio.run(run())
201+
202+
203+
@pytest.mark.parametrize(
204+
"header_name",
205+
["Content-Type", "content-type", "CONTENT-TYPE", "Content-type"],
206+
)
207+
def test_custom_content_type_is_preserved_regardless_of_casing(header_name: str) -> None:
208+
original_headers = {header_name: "application/merge-patch+json"}
209+
request = _build_request(
210+
url="https://example.com/users",
211+
method="POST",
212+
headers=original_headers,
213+
body={"name": "Ada"},
214+
params=None,
215+
)
216+
content_types = [value for name, value in request.header_items() if name.lower() == "content-type"]
217+
assert content_types == ["application/merge-patch+json"]
218+
assert original_headers == {header_name: "application/merge-patch+json"}
219+
assert isinstance(request.data, bytes)
220+
assert json.loads(request.data.decode("utf-8")) == {"name": "Ada"}
221+
222+
223+
def test_mapping_body_defaults_to_application_json() -> None:
224+
request = _build_request(
225+
url="https://example.com/users",
226+
method="POST",
227+
headers=None,
228+
body={"name": "Ada"},
229+
params=None,
230+
)
231+
content_types = [value for name, value in request.header_items() if name.lower() == "content-type"]
232+
assert content_types == ["application/json"]
233+
assert isinstance(request.data, bytes)
234+
assert json.loads(request.data.decode("utf-8")) == {"name": "Ada"}

0 commit comments

Comments
 (0)

Back | FazBrowse Home | New Git URL