IMAP 是具狀態的郵件存取協定。RFC 9051 定義 IMAP4rev2;它取代 RFC 3501 中的 IMAP4rev1。用戶端會管理伺服器上的信箱與訊息狀態,因此多個用戶端可以檢視同一個信箱。
連線與命令 #
IMAP 使用 TCP 上的文字協定。連接埠 143 以明文開始,並可透過 STARTTLS 協商 TLS;連接埠 993 從建立連線起就使用 TLS。用戶端必須取得功能、在密碼驗證前協商 TLS,並要求驗證憑證與主機名稱。
協定狀態會限制合法命令:
- 在未驗證狀態中,用戶端協商功能、TLS 與驗證。
- 在已驗證狀態中,可以管理與列出信箱。
- 在已選取狀態中,已選取一個信箱,可以擷取或變更訊息狀態。
LOGOUT進入登出狀態;伺服器傳送未加標籤的BYE與帶標籤的完成回應後,工作階段便會關閉。
每個用戶端命令都以用戶端選擇的標籤開頭。伺服器回應分為未加標籤(*)、繼續要求(+)或帶標籤的完成回應:
S: * OK IMAP4rev2 ready
C: A001 CAPABILITY
S: * CAPABILITY IMAP4rev2 STARTTLS SASL-IR
S: A001 OK completed
C: A002 STARTTLS
S: A002 OK begin TLS negotiation nowTLS 建立後,用戶端會再次傳送 CAPABILITY,因為功能可能不同。當伺服器與用戶端支援時,使用 SASL 驗證機制,而不是 LOGIN。
信箱與訊息 #
已驗證的連線可以列出、建立、重新命名、訂閱及選取信箱。SELECT 以讀寫方式開啟信箱;EXAMINE 以唯讀方式開啟。訊息具有會隨信箱變更而改變的序號,以及在 UIDVALIDITY epoch 內穩定的唯一識別碼(UID)。持久用戶端必須使用 UID、記錄 UIDVALIDITY,並在它變更時重新同步。
信箱名稱是協定字串,而不是作業系統路徑。使用 LIST 探索階層分隔符與名稱,保留伺服器提供的 UTF-8 名稱,並在需要時加引號或以 literal 傳送。INBOX 不區分大小寫;其他名稱可能依伺服器規則區分大小寫。
系統旗標包括 \Seen、\Answered、\Flagged、\Deleted 與 \Draft。用戶端以 STORE 將訊息標記為已刪除;EXPUNGE 會移除標記為 \Deleted 的訊息。在可能接收並行信箱更新的工作流程中,避免使用序號。
FETCH 會擷取訊息屬性或本文區段。SEARCH 會回傳符合的訊息。IMAP literal 可攜帶無法安全出現在引號字串中的資料;伺服器可以先要求繼續,再讓用戶端傳送同步 literal。像 {4096}\r\n 這樣的 literal 標記會宣告後續確切的八位元組數。剖析器必須消耗該長度,而不是掃描 literal 內容中的換行。
閒置與同步 #
IDLE 讓用戶端在保持連線期間接收未經請求的信箱變更。用戶端必須先以 DONE 終止 IDLE,才能傳送另一個命令。以 UID 為基礎的同步、UID FETCH 與伺服器功能檢查,可以避免將信箱快照視為永久穩定。
選取信箱時,未加標籤的 EXISTS、EXPUNGE、FETCH 及相關回應會回報變更。清除會重新編排後續序號,因此用戶端必須立即更新序號對映,並持續以 UID 識別持久狀態。儲存最後已知的 UID、旗標、UIDVALIDITY 與相關修改狀態;當兩端都宣告支援時,CONDSTORE 與 QRESYNC 等擴充功能可以減少傳輸,但後備路徑仍必須執行正確的 UID 重新掃描。
IMAP 傳輸訊息位元組與中繼資料;MIME 定義電子郵件本文結構與傳輸編碼。不要將 IMAP 的逐行命令編碼與七位元打包機制混淆:IMAP 命令列使用 ASCII 語法,而 literal 傳輸八位元組。
評論
在 GitHub 上閱讀或評論(發表評論需要登入)