Skip to content

Commit f53741a

Browse files
committed
gh-47005: fix do_open() to let regular headers override unredirected headers
AbstractHTTPHandler.do_open() was building the request header dict by starting with unredirected_hdrs and only inserting regular headers that were not already present, giving unredirected headers priority. This contradicts get_header() and header_items(), both of which give regular headers the higher priority. Fix by unconditionally updating with req.headers so that a header set via add_header() always overrides one set via add_unredirected_header().
1 parent 36e4ffc commit f53741a

File tree

2 files changed

+18
-2
lines changed

2 files changed

+18
-2
lines changed

Lib/test/test_urllib2.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -980,6 +980,23 @@ def test_http(self):
980980
self.assertEqual(req.unredirected_hdrs["Host"], "baz")
981981
self.assertEqual(req.unredirected_hdrs["Spam"], "foo")
982982

983+
def test_http_header_priority(self):
984+
# gh-47005: regular headers set via add_header() must override
985+
# unredirected headers with the same name in do_open(), consistent
986+
# with get_header() and header_items().
987+
h = urllib.request.AbstractHTTPHandler()
988+
h.parent = MockOpener()
989+
990+
req = Request("http://example.com/", headers={"Content-Type": "application/json"})
991+
req.timeout = None
992+
req.add_unredirected_header("Content-Type", "application/x-www-form-urlencoded")
993+
994+
http = MockHTTPClass()
995+
h.do_open(http, req)
996+
997+
sent_headers = dict(http.req_headers)
998+
self.assertEqual(sent_headers["Content-Type"], "application/json")
999+
9831000
def test_http_body_file(self):
9841001
# A regular file - chunked encoding is used unless Content Length is
9851002
# already set.

Lib/urllib/request.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1293,8 +1293,7 @@ def do_open(self, http_class, req, **http_conn_args):
12931293
h.set_debuglevel(self._debuglevel)
12941294

12951295
headers = dict(req.unredirected_hdrs)
1296-
headers.update({k: v for k, v in req.headers.items()
1297-
if k not in headers})
1296+
headers.update(req.headers)
12981297

12991298
# TODO(jhylton): Should this be redesigned to handle
13001299
# persistent connections?

0 commit comments

Comments
 (0)