Skip to content

gh-105530: Support sending HTTP header values with RFC 2047 #105621

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Doc/library/http.client.rst
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,8 @@ also send your request step by step, by using the four functions below.
Send an :rfc:`822`\ -style header to the server. It sends a line to the server
consisting of the header, a colon and a space, and the first argument. If more
arguments are given, continuation lines are sent, each consisting of a tab and
an argument.
an argument. If a header's value cannot be encoded with ISO-8859-1 (latin-1),
then it will be put into :rfc:`2047` encoded-word format.


.. method:: HTTPConnection.endheaders(message_body=None, *, encode_chunked=False)
Expand Down
7 changes: 6 additions & 1 deletion Lib/http/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@

import email.parser
import email.message
import email.header
import errno
import http
import io
Expand Down Expand Up @@ -1290,7 +1291,11 @@ def putheader(self, header, *values):
values = list(values)
for i, one_value in enumerate(values):
if hasattr(one_value, 'encode'):
values[i] = one_value.encode('latin-1')
try:
values[i] = one_value.encode('latin-1')
except UnicodeEncodeError:
hdr = email.header.Header(one_value, 'utf-8')
values[i] = hdr.encode().encode('ascii')
elif isinstance(one_value, int):
values[i] = str(one_value).encode('ascii')

Expand Down
2 changes: 2 additions & 0 deletions Lib/test/test_httplib.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,8 @@ def test_putheader(self):
self.assertIn(b'Authorization: Bearer mytoken', conn._buffer)
conn.putheader('IterHeader', 'IterA', 'IterB')
self.assertIn(b'IterHeader: IterA\r\n\tIterB', conn._buffer)
conn.putheader('EncodedWordHeader', 'مثل')
self.assertIn(b'EncodedWordHeader: =?utf-8?b?2YXYq9mE?=', conn._buffer)
conn.putheader('LatinHeader', b'\xFF')
self.assertIn(b'LatinHeader: \xFF', conn._buffer)
conn.putheader('Utf8Header', b'\xc3\x80')
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Send HTTP headers with non-ISO-8859-1 characters as UTF-8 with MIME
encoded-word syntax (per RFC 2047)