Skip to content

Commit a613ee4

Browse files
committed
gh-100985: Consistently wrap IPv6 IP address during CONNECT
Update _get_hostport to always remove square brackets from IPv6 addresses. Then add them if needed in "CONNECT .." and "Host: ".
1 parent 409f533 commit a613ee4

File tree

4 files changed

+30
-6
lines changed

4 files changed

+30
-6
lines changed

Lib/http/client.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -905,17 +905,23 @@ def _get_hostport(self, host, port):
905905
host = host[:i]
906906
else:
907907
port = self.default_port
908-
if host and host[0] == '[' and host[-1] == ']':
909-
host = host[1:-1]
908+
if host and host[0] == '[' and host[-1] == ']':
909+
host = host[1:-1]
910910

911911
return (host, port)
912912

913913
def set_debuglevel(self, level):
914914
self.debuglevel = level
915915

916+
def _wrap_ipv6(self, ip):
917+
if ip.find(b':') >= 0 and ip.find(b'[') != 0:
918+
return b"[" + ip + b"]"
919+
return ip
920+
916921
def _tunnel(self):
917922
connect = b"CONNECT %s:%d HTTP/1.0\r\n" % (
918-
self._tunnel_host.encode("ascii"), self._tunnel_port)
923+
self._wrap_ipv6(self._tunnel_host.encode("ascii")),
924+
self._tunnel_port)
919925
headers = [connect]
920926
for header, value in self._tunnel_headers.items():
921927
headers.append(f"{header}: {value}\r\n".encode("latin-1"))
@@ -1177,9 +1183,7 @@ def putrequest(self, method, url, skip_host=False,
11771183

11781184
# As per RFC 273, IPv6 address should be wrapped with []
11791185
# when used as Host header
1180-
1181-
if host.find(':') >= 0:
1182-
host_enc = b'[' + host_enc + b']'
1186+
host_enc = self._wrap_ipv6(host_enc)
11831187

11841188
if port == self.default_port:
11851189
self.putheader('Host', host_enc)

Lib/test/test_httplib.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2262,6 +2262,23 @@ def test_connect_put_request(self):
22622262
self.assertIn(b'CONNECT destination.com', self.conn.sock.data)
22632263
self.assertIn(b'Host: destination.com', self.conn.sock.data)
22642264

2265+
def test_connect_put_request_ipv6(self):
2266+
self.conn.set_tunnel('[1:2:3::4]', 1234)
2267+
self.conn.request('PUT', '/', '')
2268+
self.assertEqual(self.conn.sock.host, self.host)
2269+
self.assertEqual(self.conn.sock.port, client.HTTP_PORT)
2270+
self.assertIn(b'CONNECT [1:2:3::4]:1234', self.conn.sock.data)
2271+
self.assertIn(b'Host: [1:2:3::4]:1234', self.conn.sock.data)
2272+
2273+
def test_connect_put_request_ipv6_port(self):
2274+
self.conn.set_tunnel('[1:2:3::4]:1234')
2275+
self.conn.request('PUT', '/', '')
2276+
self.assertEqual(self.conn.sock.host, self.host)
2277+
self.assertEqual(self.conn.sock.port, client.HTTP_PORT)
2278+
self.assertIn(b'CONNECT [1:2:3::4]:1234', self.conn.sock.data)
2279+
self.assertIn(b'Host: [1:2:3::4]:1234', self.conn.sock.data)
2280+
2281+
22652282
def test_tunnel_debuglog(self):
22662283
expected_header = 'X-Dummy: 1'
22672284
response_text = 'HTTP/1.0 200 OK\r\n{}\r\n\r\n'.format(expected_header)

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,7 @@ Raymond Hettinger
741741
Lisa Hewus Fresh
742742
Kevan Heydon
743743
Wouter van Heyst
744+
Derek Higgins
744745
Kelsey Hightower
745746
Jason Hildebrand
746747
Ryan Hileman
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Update HTTPSConnection to consistently wrap IPv6 Addresses when using a
2+
proxy

0 commit comments

Comments
 (0)