的net/mail
包使用net/textproto
包來解析報頭 (見ReadMessage()
)。具體而言,它使用ReadMIMEHeader()
爲 頭,其被記錄爲:
返回的映射米地圖CanonicalMIMEHeaderKey(鍵)值 的在輸入遇到同樣的順序的序列。
您可以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)
}
}
這是真的,因爲他們出現消息 在頭的原始順序是輸了,但我不意識到這真的很重要的任何場景。 不是 lost是多值標題的順序。切片確保它們的順序與電子郵件中顯示的順序相同,爲 。
您可以使用一個簡單的程序對頭進行循環驗證,並且 比較值(such as this one in the Playground)。
然而,匹配Received
和Received-SPF
頭是稍微複雜, 爲:
- 不是每個
Received
報頭可以具有相應的Received-SPF
報頭;
Received-SPF
標題可能不會出現在Received
標題之上;這是 recommended but not mandated by the RFC(此外,許多程序不要求 甚至遵循RFC,所以這不會是一個保證)。
所以你要麼需要解析頭的價值,並基於 與它們匹配,或者使用net/textproto
包更多低級別的訪問 頭。您可以使用ReadMIMEHeader()
的來源作爲起點。
它將它存儲在'map [string] [] string'('textproto.MIMEHeader')中。關鍵是標題名稱,該值是所有出現該標題的片段,它應該*爲*。我不確定你爲什麼認爲他們沒有訂購?在哪種情況下失敗? – Carpetsmoker
因爲我無法解析郵件標題,並將它們打印出來並獲得原始順序,但我認爲我完全錯過了某些東西。我解析了一封郵件,然後從'net/mail'對象重新生成了郵件,並擔心'Received'和'Received-SPF'會失序,因爲地圖沒有排序,但是您說'Received [0 ]'與'Received-SPF [0]'匹配。正如在電子郵件中,當每個服務器添加它們時,這些將會彼此相鄰,所以當從地圖重新創建標題時,我需要將各個標題對從陣列位置放在一起? – amlwwalker