diff --git a/Lib/http/cookiejar.py b/Lib/http/cookiejar.py index 68cf16c93cc1c8..7345cba5a94e51 100644 --- a/Lib/http/cookiejar.py +++ b/Lib/http/cookiejar.py @@ -656,16 +656,15 @@ def request_path(request): return path def request_port(request): - host = request.host - i = host.find(':') - if i >= 0: - port = host[i+1:] - try: - int(port) - except ValueError: - _debug("nonnumeric port: '%s'", port) - return None + match = cut_port_re.search(request.host) + if match: + port = match[0].removeprefix(':') else: + i = request.host.rfind(':') + if (i >= 0 + and not ']' in request.host[i+1:] + and not request.host.startswith('[')): # to prevent IPv6 addresses + _debug("nonnumeric port: '%s'", request.host[i+1:]) port = DEFAULT_HTTP_PORT return port @@ -1075,11 +1074,7 @@ def set_ok_domain(self, cookie, request): def set_ok_port(self, cookie, request): if cookie.port_specified: - req_port = request_port(request) - if req_port is None: - req_port = "80" - else: - req_port = str(req_port) + req_port = str(request_port(request)) for p in cookie.port.split(","): try: int(p) @@ -1148,8 +1143,6 @@ def return_ok_expires(self, cookie, request): def return_ok_port(self, cookie, request): if cookie.port: req_port = request_port(request) - if req_port is None: - req_port = "80" for p in cookie.port.split(","): if p == req_port: break diff --git a/Lib/test/test_http_cookiejar.py b/Lib/test/test_http_cookiejar.py index 04cb440cd4ccf6..1970b993d6acdf 100644 --- a/Lib/test/test_http_cookiejar.py +++ b/Lib/test/test_http_cookiejar.py @@ -839,6 +839,19 @@ def test_request_port(self): req = urllib.request.Request("http://www.acme.com/", headers={"Host": "www.acme.com:4321"}) self.assertEqual(request_port(req), DEFAULT_HTTP_PORT) + req = urllib.request.Request("http://www.acme.com:", + headers={"Host": "www.acme.com:4321"}) + self.assertEqual(request_port(req), DEFAULT_HTTP_PORT) + req = urllib.request.Request("http://www.acme.com:not_a_port", + headers={"Host": "www.acme.com:4321"}) + self.assertEqual(request_port(req), DEFAULT_HTTP_PORT) + req = urllib.request.Request("http://[::1]:1234", + headers={"Host": "[::1]:4321"}) + self.assertEqual(request_port(req), "1234") + req = urllib.request.Request("http://[::1]", + headers={"Host": "[::1]:4321"}) + self.assertEqual(request_port(req), DEFAULT_HTTP_PORT) + def test_request_host(self): # this request is illegal (RFC2616, 14.2.3) @@ -1262,6 +1275,72 @@ def test_missing_final_slash(self): c.add_cookie_header(req) self.assertTrue(req.has_header("Cookie")) + def test_set_ok_port(self): + pol = DefaultCookiePolicy() + c = CookieJar(policy=pol) + headers_with_port_1234 = ["Set-Cookie: CUSTOMER=WILE_E_COYOTE; path=/; port=1234"] + headers_with_default_port = ["Set-Cookie: CUSTOMER=WILE_E_COYOTE; path=/; port=80"] + req = urllib.request.Request("http://127.0.0.1:1234") + res = FakeResponse(headers_with_port_1234, "http://127.0.0.1:1234") + self.assertTrue(pol.set_ok_port(c.make_cookies(res, req)[0], req)) + + req = urllib.request.Request("http://acme.com:1234") + res = FakeResponse(headers_with_port_1234, "http://acme.com:1234") + self.assertTrue(pol.set_ok_port(c.make_cookies(res, req)[0], req)) + + req = urllib.request.Request("http://[::1]:1234") + res = FakeResponse(headers_with_port_1234, "http://[::1]:1234") + self.assertTrue(pol.set_ok_port(c.make_cookies(res, req)[0], req)) + + req = urllib.request.Request("http://[::1]:1235") + res = FakeResponse(headers_with_port_1234, "http://[::1]:1235") + self.assertFalse(pol.set_ok_port(c.make_cookies(res, req)[0], req)) + + req = urllib.request.Request("http://acme.com:") + res = FakeResponse(headers_with_default_port, "http://acme.com:") + self.assertTrue(pol.set_ok_port(c.make_cookies(res, req)[0], req)) + res = FakeResponse(headers_with_port_1234, "http://acme.com:") + self.assertFalse(pol.set_ok_port(c.make_cookies(res, req)[0], req)) + + req = urllib.request.Request("http://acme.com:not_a_port") + res = FakeResponse(headers_with_default_port, "http://acme.com:not_a_port") + self.assertTrue(pol.set_ok_port(c.make_cookies(res, req)[0], req)) + res = FakeResponse(headers_with_port_1234, "http://acme.com:not_a_port") + self.assertFalse(pol.set_ok_port(c.make_cookies(res, req)[0], req)) + + def test_return_ok_port(self): + pol = DefaultCookiePolicy() + c = CookieJar(policy=pol) + headers_with_port_1234 = ["Set-Cookie: CUSTOMER=WILE_E_COYOTE; path=/; port=1234"] + headers_with_default_port = ["Set-Cookie: CUSTOMER=WILE_E_COYOTE; path=/; port=80"] + req = urllib.request.Request("http://127.0.0.1:1234") + res = FakeResponse(headers_with_port_1234, "http://127.0.0.1:1234") + self.assertTrue(pol.return_ok_port(c.make_cookies(res, req)[0], req)) + + req = urllib.request.Request("http://acme.com:1234") + res = FakeResponse(headers_with_port_1234, "http://acme.com:1234") + self.assertTrue(pol.return_ok_port(c.make_cookies(res, req)[0], req)) + + req = urllib.request.Request("http://[::1]:1234") + res = FakeResponse(headers_with_port_1234, "http://[::1]:1234") + self.assertTrue(pol.return_ok_port(c.make_cookies(res, req)[0], req)) + + req = urllib.request.Request("http://[::1]:1235") + res = FakeResponse(headers_with_port_1234, "http://[::1]:1235") + self.assertFalse(pol.return_ok_port(c.make_cookies(res, req)[0], req)) + + req = urllib.request.Request("http://acme.com:") + res = FakeResponse(headers_with_default_port, "http://acme.com:") + self.assertTrue(pol.return_ok_port(c.make_cookies(res, req)[0], req)) + res = FakeResponse(headers_with_port_1234, "http://acme.com:") + self.assertFalse(pol.return_ok_port(c.make_cookies(res, req)[0], req)) + + req = urllib.request.Request("http://acme.com:not_a_port") + res = FakeResponse(headers_with_default_port, "http://acme.com:not_a_port") + self.assertTrue(pol.return_ok_port(c.make_cookies(res, req)[0], req)) + res = FakeResponse(headers_with_port_1234, "http://acme.com:not_a_port") + self.assertFalse(pol.return_ok_port(c.make_cookies(res, req)[0], req)) + def test_domain_mirror(self): pol = DefaultCookiePolicy(rfc2965=True) diff --git a/Misc/NEWS.d/next/Library/2025-06-28-14-10-07.gh-issue-135993.Gmyux9.rst b/Misc/NEWS.d/next/Library/2025-06-28-14-10-07.gh-issue-135993.Gmyux9.rst new file mode 100644 index 00000000000000..f2113ec786be1e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-06-28-14-10-07.gh-issue-135993.Gmyux9.rst @@ -0,0 +1,2 @@ +:mod:`http.cookiejar`: Fix a bug that occurs when :class:`~http.cookiejar.DefaultCookiePolicy` +attempts to parse the port of an IPv6 address in func ``request_port()``. Patch by Weilin Du.