Fix request_to_curl() corrupting dict cookies with bytes keys/values (#7675)

* Fix request_to_curl() corrupting dict cookies with bytes keys/values

PR #7603 made the list-cookie branch of request_to_curl() bytes-safe via
_cookie_value_to_unicode(), but left the sibling dict-cookie branch using
raw f-string interpolation. A dict cookie with bytes keys/values (a
supported and common form, e.g. Request(url, cookies={b"k": b"v"})) was
rendered as --cookie 'b'k'=b'v'' instead of --cookie 'k=v', producing a
broken curl command.

Route the dict branch through the same _cookie_value_to_unicode() helper,
mirroring the list branch. Add a regression test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix: apply _cookie_value_to_unicode to list-branch cookie key/value

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
greymoth 2026-06-27 04:53:32 +09:00 committed by GitHub
parent 4b40d2d06a
commit 185d6b9a20
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 31 additions and 2 deletions

View File

@ -204,13 +204,16 @@ def request_to_curl(request: Request) -> str:
cookies = ""
if request.cookies:
if isinstance(request.cookies, dict):
cookie = "; ".join(f"{k}={v}" for k, v in request.cookies.items())
cookie = "; ".join(
f"{_cookie_value_to_unicode(k)}={_cookie_value_to_unicode(v)}"
for k, v in request.cookies.items()
)
cookies = f"--cookie '{cookie}'"
elif isinstance(request.cookies, list):
cookie = "; ".join(
f"{_cookie_value_to_unicode(c['name'])}={_cookie_value_to_unicode(c['value'])}"
if "name" in c and "value" in c
else f"{next(iter(c.keys()))}={next(iter(c.values()))}"
else f"{_cookie_value_to_unicode(next(iter(c.keys())))}={_cookie_value_to_unicode(next(iter(c.values())))}"
for c in request.cookies
)
cookies = f"--cookie '{cookie}'"

View File

@ -401,6 +401,19 @@ class TestRequestToCurl:
)
self._test_request(request_object, expected_curl_command)
def test_cookies_dict_bytes(self):
request_object = Request(
"https://www.httpbin.org/post",
method="POST",
cookies={b"foo": b"bar"},
body=json.dumps({"foo": "bar"}),
)
expected_curl_command = (
"curl -X POST https://www.httpbin.org/post"
" --data-raw '{\"foo\": \"bar\"}' --cookie 'foo=bar'"
)
self._test_request(request_object, expected_curl_command)
def test_cookies_list(self):
request_object = Request(
"https://www.httpbin.org/post",
@ -455,3 +468,16 @@ class TestRequestToCurl:
" --data-raw '{\"foo\": \"bar\"}' --cookie 'foo=1'"
)
self._test_request(request_object, expected_curl_command)
def test_cookies_list_bytes_nonstandard_key(self):
request_object = Request(
"https://www.httpbin.org/post",
method="POST",
cookies=[{b"foo": b"bar"}],
body=json.dumps({"foo": "bar"}),
)
expected_curl_command = (
"curl -X POST https://www.httpbin.org/post"
" --data-raw '{\"foo\": \"bar\"}' --cookie 'foo=bar'"
)
self._test_request(request_object, expected_curl_command)