【问题标题】:Go (lang) parsing an email header and keeping orderGo(lang)解析电子邮件标题并保持顺序
【发布时间】:2017-05-06 21:35:18
【问题描述】:

我在 Go 中使用 net/mail 库,一切都很好,但是我想传递原始电子邮件并保持标题的顺序。这很重要,因为在每个邮件服务器上传递消息的邮件服务器都会按顺序添加它们的标题。没有顺序,很难知道谁收到了什么,何时以及每个服务器添加了什么标头。 net/mailstores the headers in a map,根据定义,它没有顺序的概念。似乎是一个奇怪的选择,因为标题顺序仅基于电子邮件中的顺序,但事实就是如此。 有人对我如何保留标题的读取顺序有任何建议吗?

谢谢

【问题讨论】:

  • 它将它存储在map[string][]string (textproto.MIMEHeader) 中。键是标头名称,值是该标头所有出现的切片,应该是按顺序。我不知道你为什么认为他们没有被订购?在什么情况下会失败?
  • 因为我无法解析邮件标头并将它们打印出来并获得原始订单,但我想我当时完全错过了一些东西。我解析了一封邮件,然后从net/mail 对象重新生成了邮件,并担心ReceivedReceived-SPF 会失去顺序,因为地图没有排序,但你说Received[0] 与@987654330 匹配@。正如在电子邮件中一样,当每个服务器添加它们时,它们将彼此相邻,因此当从地图重新创建标题时,我需要以某种方式将各自的标题对从数组位置放在一起?

标签: email go email-headers


【解决方案1】:

net/mail 包使用net/textproto 包来解析标头 (见ReadMessage())。具体来说,它使用ReadMIMEHeader() 标头,记录为:

返回的映射 m 将 CanonicalMIMEHeaderKey(key) 映射到一系列值 与输入中遇到的顺序相同。

如果你愿意,可以view the full source,但基本流程是:

headers = make(map[string][]string)
for {
    key, value := readNextHeader()
    if key == "" {
        return headers // End of headers
    }

    if headers[key] == nil {
        headers[key] = []string{value}
    } else {
        headers[key] = append(headers[key], value)
    }
}

确实,邮件中出现的标题的原始顺序 丢失了,但我不知道这真的很重要的任何情况。什么 丢失的是多值标头的顺序。切片确保它们 与它们在电子邮件中出现的顺序相同。

您可以通过一个简单的程序来验证这一点,该程序会遍历标题和 比较值 (such as this one in the Playground)。


但是,匹配 ReceivedReceived-SPF 标头有点复杂, 如:

  1. 并非每个Received 标头都有对应的Received-SPF 标头;
  2. Received-SPF 标头可能不会出现在Received 标头上方;这是 recommended but not mandated by the RFC(此外,许多程序不 甚至遵循 RFC,所以这无论如何都不能保证)。

因此,您要么需要解析标头的值并根据 ,或者使用net/textproto 包来获得对 标题。您可以使用ReadMIMEHeader() 的来源作为起点。

【讨论】:

    猜你喜欢
    • 2020-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-18
    • 2018-02-23
    • 2011-06-25
    • 2018-11-10
    相关资源
    最近更新 更多