mirror of https://github.com/python/cpython
gh-73561: Omit interface scope from IPv6 when used as Host header (#93324)
Omit the `@interface_scope` from an IPv6 address when used as Host header by `http.client`. --------- Co-authored-by: Gregory P. Smith <greg@krypto.org> [Google LLC]
This commit is contained in:
parent
7c9f2677fb
commit
ce1096f974
|
@ -172,6 +172,13 @@ def _encode(data, name='data'):
|
|||
"if you want to send it encoded in UTF-8." %
|
||||
(name.title(), data[err.start:err.end], name)) from None
|
||||
|
||||
def _strip_ipv6_iface(enc_name: bytes) -> bytes:
|
||||
"""Remove interface scope from IPv6 address."""
|
||||
enc_name, percent, _ = enc_name.partition(b"%")
|
||||
if percent:
|
||||
assert enc_name.startswith(b'['), enc_name
|
||||
enc_name += b']'
|
||||
return enc_name
|
||||
|
||||
class HTTPMessage(email.message.Message):
|
||||
# XXX The only usage of this method is in
|
||||
|
@ -1194,7 +1201,7 @@ class HTTPConnection:
|
|||
netloc_enc = netloc.encode("ascii")
|
||||
except UnicodeEncodeError:
|
||||
netloc_enc = netloc.encode("idna")
|
||||
self.putheader('Host', netloc_enc)
|
||||
self.putheader('Host', _strip_ipv6_iface(netloc_enc))
|
||||
else:
|
||||
if self._tunnel_host:
|
||||
host = self._tunnel_host
|
||||
|
@ -1211,8 +1218,9 @@ class HTTPConnection:
|
|||
# As per RFC 273, IPv6 address should be wrapped with []
|
||||
# when used as Host header
|
||||
|
||||
if host.find(':') >= 0:
|
||||
if ":" in host:
|
||||
host_enc = b'[' + host_enc + b']'
|
||||
host_enc = _strip_ipv6_iface(host_enc)
|
||||
|
||||
if port == self.default_port:
|
||||
self.putheader('Host', host_enc)
|
||||
|
|
|
@ -283,6 +283,22 @@ class HeaderTests(TestCase):
|
|||
conn.request('GET', '/foo')
|
||||
self.assertTrue(sock.data.startswith(expected))
|
||||
|
||||
expected = b'GET /foo HTTP/1.1\r\nHost: [fe80::]\r\n' \
|
||||
b'Accept-Encoding: identity\r\n\r\n'
|
||||
conn = client.HTTPConnection('[fe80::%2]')
|
||||
sock = FakeSocket('')
|
||||
conn.sock = sock
|
||||
conn.request('GET', '/foo')
|
||||
self.assertTrue(sock.data.startswith(expected))
|
||||
|
||||
expected = b'GET /foo HTTP/1.1\r\nHost: [fe80::]:81\r\n' \
|
||||
b'Accept-Encoding: identity\r\n\r\n'
|
||||
conn = client.HTTPConnection('[fe80::%2]:81')
|
||||
sock = FakeSocket('')
|
||||
conn.sock = sock
|
||||
conn.request('GET', '/foo')
|
||||
self.assertTrue(sock.data.startswith(expected))
|
||||
|
||||
def test_malformed_headers_coped_with(self):
|
||||
# Issue 19996
|
||||
body = "HTTP/1.1 200 OK\r\nFirst: val\r\n: nval\r\nSecond: val\r\n\r\n"
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Omit the interface scope from an IPv6 address when used as Host header by :mod:`http.client`.
|
Loading…
Reference in New Issue