【发布时间】:2013-08-08 07:03:04
【问题描述】:
试图解决this issue,我试图围绕Python标准库中旨在支持RFC 2231的各种函数。该 RFC 的主要目的似乎有三个方面:允许在标头参数中使用非 ASCII 编码,注意给定值的语言,以及允许标头参数跨越多行。 email.util library 提供了几个函数来处理这方面的各个方面。据我所知,它们的工作方式如下:
decode_rfc2231 仅将此类参数的值拆分为其部分,如下所示:
>>> email.utils.decode_rfc2231("utf-8''T%C3%A4st.txt")
['utf-8', '', 'T%C3%A4st.txt']
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"'))]
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"')]
所以看来,为了使用所有这些机制,我必须再添加一个步骤来取消引用我遇到的任何元组的第三个元素。这是真的,还是我在这里遗漏了一些观点?我不得不在源代码的帮助下弄清楚上面的很多内容,因为文档对细节有点模糊。我无法想象这种选择性取消引用背后的意义是什么。有道理吗?
关于如何使用这些功能的最佳参考资料是什么?
到目前为止我发现的最好的是email.message.Messageimplementation。在那里,该过程似乎与上面概述的大致相同,但每个字段在decode_params 之后通过_unquotevalue 被取消引用,并且只有get_filename 和get_boundary 折叠它们的值,所有其他字段都返回一个元组。我希望有更有用的东西。
【问题讨论】:
-
不是一个答案,但我们对 RFC 2231 进行了长时间的讨论,这可能对您在另一个问题中有用。不过,它是关于表单字段的。 — stackoverflow.com/questions/20591599/…
-
@RobStarling:谢谢! RFC 2231 一直是 haunting me for some time now,特别是因为 someone pointed out 即 HTML5 requires not using it for file names。但 HTML5 还不是标准……
-
哦,太好了。 HTML5 的人正在调整 HTTP?呃。
-
我会选择更高(使用
Message接口,即始终使用unquote)或更低(内联decode_params,collapse_rfc2231_value- 首先不要添加不必要的引号)
标签: python http mime multipartform-data