Skip to content

Commit 670facc

Browse files
gh-159044: Fix http.client tunnel headers with non-string values
Co-authored-by: LorenaMBorges <lborgescomp@gmail.com>
1 parent 5a22a62 commit 670facc

4 files changed

Lines changed: 24 additions & 2 deletions

File tree

‎Doc/library/http.client.rst‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,8 @@ HTTPConnection Objects
370370
proxy server).
371371

372372
The *headers* argument should be a mapping of extra HTTP headers to send with
373-
the CONNECT request.
373+
the CONNECT request. Non-string header values are converted to strings via
374+
:func:`str`.
374375

375376
As HTTP/1.1 is used for HTTP CONNECT tunnelling request, `as per the RFC
376377
<https://datatracker.ietf.org/doc/html/rfc7231#section-4.3.6>`_, a HTTP ``Host:``

‎Lib/http/client.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1015,7 +1015,7 @@ def _tunnel(self):
10151015
headers = [connect]
10161016
for header, value in self._tunnel_headers.items():
10171017
header_bytes = header.encode("latin-1")
1018-
value_bytes = value.encode("latin-1")
1018+
value_bytes = str(value).encode("latin-1")
10191019
if not _is_legal_header_name(header_bytes):
10201020
raise ValueError('Invalid header name %r' % (header_bytes,))
10211021
if _is_illegal_header_value(value_bytes):

‎Lib/test/test_httplib.py‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2793,6 +2793,23 @@ def _create_connection(address, timeout=None, source_address=None):
27932793
self.assertIsNotNone(exc)
27942794
self.assertTrue(sock.file_closed)
27952795

2796+
def test_tunnel_nonstr_headers(self):
2797+
class CustomObject:
2798+
def __str__(self):
2799+
return 'custom-str'
2800+
2801+
self.conn.set_tunnel('destination.com', headers={
2802+
'None-Value': None,
2803+
'Integer-Value': 9,
2804+
'Custom-Value': CustomObject(),
2805+
})
2806+
2807+
self.conn.request('HEAD', '/', '')
2808+
2809+
self.assertIn(b'None-Value: None\r\n', self.conn.sock.data)
2810+
self.assertIn(b'Integer-Value: 9\r\n', self.conn.sock.data)
2811+
self.assertIn(b'Custom-Value: custom-str\r\n', self.conn.sock.data)
2812+
27962813

27972814
if __name__ == '__main__':
27982815
unittest.main(verbosity=2)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Restore the previous behaviour of :meth:`http.client.HTTPConnection.set_tunnel`
2+
where header values that are not strings (such as :const:`None`, :class:`int`
3+
or other objects) are converted with :class:`str` instead of raising
4+
:exc:`AttributeError` when the request is sent.

0 commit comments

Comments
 (0)