summaryrefslogtreecommitdiffstats
path: root/Lib/email
diff options
context:
space:
mode:
authorR. David Murray <rdmurray@bitdance.com>2010-12-13 23:51:19 (GMT)
committerR. David Murray <rdmurray@bitdance.com>2010-12-13 23:51:19 (GMT)
commit7ec754b7da863c5b0c5ca212da8a2585db989bf8 (patch)
treeb388a68e00b9ee639129033bc3983fbe94cb2a64 /Lib/email
parent796343b1988e3e47c9b400053f844c2bb0352d9a (diff)
downloadcpython-7ec754b7da863c5b0c5ca212da8a2585db989bf8.zip
cpython-7ec754b7da863c5b0c5ca212da8a2585db989bf8.tar.gz
cpython-7ec754b7da863c5b0c5ca212da8a2585db989bf8.tar.bz2
#1078919: make add_header automatically do RFC2231 encoding when needed.
Also document the use of three-tuples if control of the charset and language is desired.
Diffstat (limited to 'Lib/email')
-rw-r--r--Lib/email/message.py24
-rw-r--r--Lib/email/test/test_email.py23
2 files changed, 44 insertions, 3 deletions
diff --git a/Lib/email/message.py b/Lib/email/message.py
index a835ce2..8d68c09 100644
--- a/Lib/email/message.py
+++ b/Lib/email/message.py
@@ -57,7 +57,11 @@ def _splitparam(param):
def _formatparam(param, value=None, quote=True):
"""Convenience function to format and return a key=value pair.
- This will quote the value if needed or if quote is true.
+ This will quote the value if needed or if quote is true. If value is a
+ three tuple (charset, language, value), it will be encoded according
+ to RFC2231 rules. If it contains non-ascii characters it will likewise
+ be encoded according to RFC2231 rules, using the utf-8 charset and
+ a null language.
"""
if value is not None and len(value) > 0:
# A tuple is used for RFC 2231 encoded parameter values where items
@@ -67,6 +71,12 @@ def _formatparam(param, value=None, quote=True):
# Encode as per RFC 2231
param += '*'
value = utils.encode_rfc2231(value[2], value[0], value[1])
+ else:
+ try:
+ value.encode('ascii')
+ except UnicodeEncodeError:
+ param += '*'
+ value = utils.encode_rfc2231(value, 'utf-8', '')
# BAW: Please check this. I think that if quote is set it should
# force quoting even if not necessary.
if quote or tspecials.search(value):
@@ -438,11 +448,19 @@ class Message:
name is the header field to add. keyword arguments can be used to set
additional parameters for the header field, with underscores converted
to dashes. Normally the parameter will be added as key="value" unless
- value is None, in which case only the key will be added.
+ value is None, in which case only the key will be added. If a
+ parameter value contains non-ASCII characters it can be specified as a
+ three-tuple of (charset, language, value), in which case it will be
+ encoded according to RFC2231 rules. Otherwise it will be encoded using
+ the utf-8 charset and a language of ''.
- Example:
+ Examples:
msg.add_header('content-disposition', 'attachment', filename='bud.gif')
+ msg.add_header('content-disposition', 'attachment',
+ filename=('utf-8', '', Fußballer.ppt'))
+ msg.add_header('content-disposition', 'attachment',
+ filename='Fußballer.ppt'))
"""
parts = []
for k, v in _params.items():
diff --git a/Lib/email/test/test_email.py b/Lib/email/test/test_email.py
index 7993486..78fb961 100644
--- a/Lib/email/test/test_email.py
+++ b/Lib/email/test/test_email.py
@@ -510,6 +510,29 @@ class TestMessageAPI(TestEmailBase):
self.assertEqual(msg.get_payload(decode=True),
bytes(x, 'raw-unicode-escape'))
+ # Issue 1078919
+ def test_ascii_add_header(self):
+ msg = Message()
+ msg.add_header('Content-Disposition', 'attachment',
+ filename='bud.gif')
+ self.assertEqual('attachment; filename="bud.gif"',
+ msg['Content-Disposition'])
+
+ def test_noascii_add_header(self):
+ msg = Message()
+ msg.add_header('Content-Disposition', 'attachment',
+ filename="Fußballer.ppt")
+ self.assertEqual(
+ 'attachment; filename*="utf-8\'\'Fu%C3%9Fballer.ppt"',
+ msg['Content-Disposition'])
+
+ def test_nonascii_add_header_via_triple(self):
+ msg = Message()
+ msg.add_header('Content-Disposition', 'attachment',
+ filename=('iso-8859-1', '', 'Fußballer.ppt'))
+ self.assertEqual(
+ 'attachment; filename*="iso-8859-1\'\'Fu%DFballer.ppt"',
+ msg['Content-Disposition'])
# Test the email.encoders module