首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >解码RFC 2231报头

解码RFC 2231报头
EN

Stack Overflow用户
提问于 2013-08-07 03:47:26
回答 2查看 1.5K关注 0票数 16

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

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

代码语言:javascript
复制
>>> email.utils.decode_rfc2231("utf-8''T%C3%A4st.txt")
['utf-8', '', 'T%C3%A4st.txt']

decode_params负责检测RFC2231 2231编码的参数。它收集属于一起的部分,并将url编码的字符串解码为字节序列。然而,这个字节序列随后被编码为latin1。所有的值都用引号括起来。此外,对于第一个参数有一些特殊的处理,它仍然必须是两个元素的元组,但是这两个元素不需要修改就可以传递到结果。

代码语言:javascript
复制
>>> 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字符串。然而,让我困惑的是,如果输入是这样的三重,那么引号将被转到输出。另一方面,如果输入是一个单引号字符串,那么这些引号将被删除。

代码语言:javascript
复制
>>> [(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.Message 实现。在那里,这个过程似乎大致上是一个上面概述的过程,但是在_unquotevalue之后,每个字段都不被引用,只有get_filenameget_boundary折叠它们的值,其他所有字段都返回一个元组。我希望有更多有用的东西。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-01-04 21:38:29

目前,除了在email.utils中使用之外,很少使用来自email.message的函数。大多数用户似乎更喜欢直接使用email.message.Message。在Python中添加单元测试(这当然可以作为示例使用)甚至还有一个比较老的发行报告,即使我不确定它与email.util的关系如何。

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

从我可以找到的几个例子中判断,我认为使用email.util进行解析是唯一的方法,即使冗长的列表理解有点难看。

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

我认为email.util RFC2231 API不是为简单的独立使用而设计的,而是作为一堆用于email.message.Message的实用方法而设计的。

票数 4
EN

Stack Overflow用户

发布于 2016-08-04 12:03:49

老问题,但我找不到一个完整的答案来解决这个问题。这就是我最后所做的事情(在Python2.7上):

代码语言:javascript
复制
def decode_rfc2231_header(header):
    """Decode a RFC 2231 header"""
    # Remove any quotes
    header = email.utils.unquote(header)
    encoding, language, value = email.utils.decode_rfc2231(header)
    value = urllib.unquote(value)
    return email.utils.collapse_rfc2231_value((encoding, language, value))

例如:

代码语言:javascript
复制
>>> name = u'èéêëēėęûüùúūàáâäæãåāāîïíīįì test ôöòóœøōõssśšłžźżçćčñń'
>>> encoded_header = email.utils.encode_rfc2231(name.encode("utf8"), 'utf8', 'en')
>>> print encoded_header 
utf8'en'%C3%A8%C3%A9%C3%AA%C3%AB%C4%93%C4%97%C4%99%C3%BB%C3%BC%C3%B9%C3%BA%C5%AB%C3%A0%C3%A1%C3%A2%C3%A4%C3%A6%C3%A3%C3%A5%C4%81%C4%81%C3%AE%C3%AF%C3%AD%C4%AB%C4%AF%C3%AC%20test%20%C3%B4%C3%B6%C3%B2%C3%B3%C5%93%C3%B8%C5%8D%C3%B5ss%C5%9B%C5%A1%C5%82%C5%BE%C5%BA%C5%BC%C3%A7%C4%87%C4%8D%C3%B1%C5%84
>>> print decode_rfc2231_header(encoded_header)
èéêëēėęûüùúūàáâäæãåāāîïíīįì test ôöòóœøōõssśšłžźżçćčñń
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18094309

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档