Skip to content

Commit 65a1411

Browse files
committed
requests: Do not leak header modifications when calling request.
The requests() function takes a headers dict argument (call-by-reference). This object is then modified in the function. For instance the host is added and authentication information. Such behavior is not expected. It is also problematic: - Modifications of the header dictionary will be visible on the caller site. - When reusing the same (supposedly read-only) headers object for differenct calls, the second call will apparently re-use wrong headers from the previous call and may fail. This patch should also fix micropython#839. Unfortunately the copy operation does not preserve the key order and we have to touch the existing test cases. Signed-off-by: Richard Weickelt <richard@weickelt.de>
1 parent e4cf095 commit 65a1411

File tree

2 files changed

+13
-2
lines changed

2 files changed

+13
-2
lines changed

python-ecosys/requests/requests/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ def request(
4646
):
4747
if headers is None:
4848
headers = {}
49+
else:
50+
headers = headers.copy()
4951

5052
redirect = None # redirection url, None means no redirection
5153
chunked_data = data and getattr(data, "__next__", None) and not getattr(data, "__len__", None)

python-ecosys/requests/test_requests.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,11 @@ def chunks():
102102

103103
def test_overwrite_get_headers():
104104
response = requests.request(
105-
"GET", "http://example.com", headers={"Connection": "keep-alive", "Host": "test.com"}
105+
"GET", "http://example.com", headers={"Host": "test.com", "Connection": "keep-alive"}
106106
)
107107

108108
assert response.raw._write_buffer.getvalue() == (
109-
b"GET / HTTP/1.0\r\n" + b"Host: test.com\r\n" + b"Connection: keep-alive\r\n\r\n"
109+
b"GET / HTTP/1.0\r\n" + b"Connection: keep-alive\r\n" + b"Host: test.com\r\n\r\n"
110110
), format_message(response)
111111

112112

@@ -145,6 +145,14 @@ def chunks():
145145
), format_message(response)
146146

147147

148+
def test_do_not_modify_headers_argument():
149+
global do_not_modify_this_dict
150+
do_not_modify_this_dict = {}
151+
requests.request("GET", "http://example.com", headers=do_not_modify_this_dict)
152+
153+
assert do_not_modify_this_dict == {}, do_not_modify_this_dict
154+
155+
148156
test_simple_get()
149157
test_get_auth()
150158
test_get_custom_header()
@@ -153,3 +161,4 @@ def chunks():
153161
test_overwrite_get_headers()
154162
test_overwrite_post_json_headers()
155163
test_overwrite_post_chunked_data_headers()
164+
test_do_not_modify_headers_argument()

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy