解析发往Google App Engine的Unicode附件名称
我有一个应用程序,它可以接收带附件的邮件。我会检查附件的文件名,以确保文件扩展名是正确的。但是,如果文件名中有变音符号或重音字符,编码就会让我的方法无法读取这个文件名,这样我就不知道怎么检查文件类型了。
举个例子,如果我发送一个文件,名字是 ZumBrückenwirtÜberGrünwaldZurück(2).gpx
然后我像这样打印出附件的名字:
attachments = [message.attachments]
attachmenttype = attachments[0][0][-4:].lower()
logging.error("attachment name %s, %s" % (attachments[0][0], attachmenttype))
我得到的结果是:
附件名称 =?ISO-8859-1?B?WnVtQnL8Y2tlbndpcnTcYmVyR3L8bndhbGRadXL8Y2soMikuZ3B4?=, b4?=
1 个回答
2
这段文字提到了一种叫做RFC2047编码的方式。你可以用email
这个工具部分解码它,但解码后还需要把它拼接起来:
import email.header
def parseHeader(h):
return ''.join(s.decode(c or 'us-ascii') for s, c in email.header.decode_header(h))
>>> parseHeader('=?ISO-8859-1?B?WnVtQnL8Y2tlbndpcnTcYmVyR3L8bndhbGRadXL8Y2soMikuZ3B4?=')
u'ZumBr\xfcckenwirt\xdcberGr\xfcnwaldZur\xfcck(2).gpx'
不过,在附件的Content-Disposition
中的filename="..."
参数里使用这种编码方式是完全错误的。RFC2047明确说明,编码词不能出现在带引号的参数里。非ASCII的参数值应该按照RFC2231的规则来传输,这些规则看起来完全不同(而且非常复杂)。
所以根据邮件标准,你应该把这个文件名当作字面意思来看,内容是“=?ISO-8859-1?B?WnVtQnL8Y2tlbndpc...”。我相信是微软的Exchange系统生成了这种无意义的东西。尽量减少对这个内容的处理(比如说,只有在字符串被包裹在=?...?=
时才解码,这在文件名中是非常不常见的)。