解码RFC 2231标头

MvG*_*MvG 16 python mime http multipartform-data

为了解决这个问题,我试图围绕Python标准库中旨在支持RFC 2231的各种函数.该RFC的主要目的似乎是三方面:允许在头参数中进行非ASCII编码,注意给定值的语言,并允许头参数跨越多行.该email.util提供了几个功能来处理这方面的各个方面.据我所知,它们的工作原理如下:

decode_rfc2231 只将这样一个参数的值拆分成它的部分,如下所示:

>>> email.utils.decode_rfc2231("utf-8''T%C3%A4st.txt")
['utf-8', '', 'T%C3%A4st.txt']
Run Code Online (Sandbox Code Playgroud)

decode_params负责检测RFC2231编码的参数.它收集属于一起的部分,并将url编码的字符串解码为字节序列.然而,该字节序列被编码为latin1.并且所有值都用引号括起来.此外,第一个参数有一些特殊的处理,它仍然必须是两个元素的元组,但是这两个元素在没有修改的情况下传递给结果.

>>> email.utils.decode_params([
...   (1,2),
...   ("foo","bar"),
...   ("name*","utf-8''T%C3%A4st.txt"),
...   ("baz*0","two"),("baz*1","-part")])
[(1, 2), ('foo', '"bar"'), ('baz', '"two-part"'), ('name', ('utf-8', '', '"Täst.txt"'))]
Run Code Online (Sandbox Code Playgroud)

collapse_rfc2231_value可用于将此三重编码,语言和字节序列转换为正确的unicode字符串.然而,令我困惑的是,如果输入是这样的三倍,那么引号将被转移到输出.另一方面,如果输入是单引号字符串,则将删除这些引号.

>>> [(k, email.utils.collapse_rfc2231_value(v)) for k, v in
...  email.utils.decode_params([
...   (1,2),
...   ("foo","bar"),
...   ("name*","utf-8''T%C3%A4st.txt"),
...   ("baz*0","two"),("baz*1","-part")])[1:]]
[('foo', 'bar'), ('baz', 'two-part'), ('name', '"Täst.txt"')]
Run Code Online (Sandbox Code Playgroud)

所以似乎为了使用所有这些机器,我必须再添加一个步骤来取消我遇到的任何元组的第三个元素.这是真的吗,还是我在这里错过了一些观点?我必须在源代码的帮助下弄清楚上面的很多内容,因为文档在细节上有点模糊.我无法想象这有选择性的不引用的背后可能是什么.有没有意义呢?

关于如何使用这些功能的最佳参考是什么?

到目前为止我发现的最好的是实施.在那里,过程似乎大致上面概述,但每场得到通过未加引号后,只有和崩溃他们的价值观,所有其他人返回一个元组来代替.我希望有更有用的东西.email.message.Message _unquotevaluedecode_paramsget_filenameget_boundary

Uli*_*ler 4

目前,除了 inside 之外, from 的函数email.utils很少被使用email.message。大多数用户似乎更喜欢email.message.Message直接使用。甚至还有一个关于向 Python 添加单元测试(肯定可以用作示例)的有点老的问题报告,即使我不确定它与email.util.

我发现的一个简短的例子是这篇博文,但是,它不包含多个句子和一些有关 RFC2231 解析的信息 SLOC。然而,作者指出,许多 MTA 使用RFC2047。根据您的用例,这也可能是一个问题。

从我能找到的几个例子来看,我认为你的解析方法 usingemail.util是唯一的方法,即使长列表理解有点难看。

由于在某些方面缺乏示例,因此编写一个新的 RFC2231 解析器可能是明智的(如果您确实需要一个更好、也许更快或更漂亮的代码库)。出于兼容性原因,新的实现可以基于Dovecot RFC2231 解析器等现有实现(您甚至可以使用Dovecot 单元测试email.util。由于 C 代码对我来说似乎相当复杂,而且除了Python2 向后移植之外,我找不到任何 python 实现移植到 Python 的任务email.util并不容易(请注意,Dovecot 是LGPL 许可的,这可能是您项目中的一个问题)

我认为email.utilRFC2231 API 并不是为简单的独立使用而设计的,而更多的是作为一堆在email.message.Message.