summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorBarry Warsaw <barry@python.org>2002-06-29 05:58:04 (GMT)
committerBarry Warsaw <barry@python.org>2002-06-29 05:58:04 (GMT)
commit12566a8826ad7afe123f035a43483fe97a2fa3c5 (patch)
treeae2cab6713b70a635cf8fd7567ad9e4dc09934d7 /Lib
parent908dc4bea84e4c1d5c20c03160a202c0f69db49d (diff)
downloadcpython-12566a8826ad7afe123f035a43483fe97a2fa3c5.zip
cpython-12566a8826ad7afe123f035a43483fe97a2fa3c5.tar.gz
cpython-12566a8826ad7afe123f035a43483fe97a2fa3c5.tar.bz2
Oleg Broytmann's support for RFC 2231 encoded parameters, SF patch #549133
Specifically, decode_rfc2231(), encode_rfc2231(): Functions to encode and decode RFC 2231 style parameters. decode_params(): Function to decode a list of parameters.
Diffstat (limited to 'Lib')
-rw-r--r--Lib/email/Utils.py57
1 files changed, 57 insertions, 0 deletions
diff --git a/Lib/email/Utils.py b/Lib/email/Utils.py
index 5624278..cc02f5e 100644
--- a/Lib/email/Utils.py
+++ b/Lib/email/Utils.py
@@ -45,6 +45,7 @@ import base64
from email.Encoders import _bencode, _qencode
COMMASPACE = ', '
+EMPTYSTRING = ''
UEMPTYSTRING = u''
CRLF = '\r\n'
@@ -257,3 +258,59 @@ def parseaddr(addr):
if not addrs:
return '', ''
return addrs[0]
+
+
+
+# RFC2231-related functions - parameter encoding and decoding
+def decode_rfc2231(s):
+ """Decode string according to RFC 2231"""
+ import urllib
+ charset, language, s = s.split("'", 2)
+ s = urllib.unquote(s)
+ return charset, language, s
+
+
+def encode_rfc2231(s, charset=None, language=None):
+ """Encode string according to RFC 2231"""
+ import urllib
+ s = urllib.quote(s, safe='')
+ if charset is None and language is None:
+ return s
+ else:
+ return "%s'%s'%s" % (charset, language, s)
+
+
+rfc2231_continuation = re.compile(r'^(?P<name>\w+)\*((?P<num>[0-9]+)\*?)?$')
+
+def decode_params(params):
+ """Decode parameters list according to RFC 2231"""
+ new_params = []
+ # maps parameter's name to a list of continuations
+ rfc2231_params = {}
+ # params is a sequence of 2-tuples containing (content_type, string value)
+ name, value = params[0]
+ new_params.append((name, value))
+ # Cycle through each of the rest of the parameters.
+ for name, value in params[1:]:
+ value = unquote(value)
+ mo = rfc2231_continuation.match(name)
+ if mo:
+ name, num = mo.group('name', 'num')
+ if num is not None:
+ num = int(num)
+ rfc2231_param1 = rfc2231_params.setdefault(name, [])
+ rfc2231_param1.append((num, value))
+ else:
+ new_params.append((name, '"%s"' % quote(value)))
+ if rfc2231_params:
+ for name, continuations in rfc2231_params.items():
+ value = []
+ # Sort by number
+ continuations.sort()
+ # And now append all values in num order
+ for num, continuation in continuations:
+ value.append(continuation)
+ charset, language, value = decode_rfc2231(EMPTYSTRING.join(value))
+ new_params.append((name,
+ (charset, language, '"%s"' % quote(value))))
+ return new_params