POP3是一种用于从邮件服务器获取电子邮件的协议。它允许邮件客户端连接到邮件服务器,检索服务器上存储的邮件,并将邮件下载到客户端设备上。POP3的工作原理如下:
USER
?命令提供用户名,然后发送PASS
?命令提供密码以进行身份验证。STAT
?命令来查看邮箱中的邮件状态,包括邮件数量和总字节数。LIST
?命令,客户端可以查看每封邮件的索引号和大小。如果提供邮件索引号,服务器将返回特定邮件的大小。RETR
?命令,客户端可以检索特定邮件的内容,包括邮件头和正文。邮件被下载到客户端设备上。DELE
?命令,客户端可以标记要删除的邮件。邮件在标记为删除后不会立即从服务器上删除,直到客户端执行QUIT
?命令。QUIT
?命令,客户端结束POP3会话并断开连接。在断开连接之前,标记为删除的邮件将从服务器上删除。USER
??,PASS
??,LIST
??等),服务器返回响应(例如,+OK
??表示成功,-ERR
??表示错误)。LIST
??命令返回每封邮件的大小,以便客户端可以了解邮件的大小信息。DELE
??命令将邮件标记为删除。标记为删除的邮件在QUIT
??命令之前不会从服务器上真正删除。一旦客户机成功地向 POP3服务器标识了自己并且 POP3服务器已经锁定并打开了相应的邮件包, POP3会话现在处于 TRANSACTION 状态. 重复发出以下任何 POP3命令命令,POP3服务器发出响应 发出 QUIT 命令,POP3会话进入 UPDATE 状态。
STAT
?:查询邮箱中邮件的统计信息,包括邮件数量和总字节数。命令格式:
STAT
服务器应该响应一个包含两个值的响应:邮件数量和邮箱中所有邮件的总字节数。响应的格式如下:
+OK <邮件数量> <总字节数>
获取邮件服务器返回每封邮件的详细信息,包括邮件的索引号和大小。
命令格式:
LIST [<message_number>]
<message_number>
? 是可选的参数,用于指定要列出的特定邮件的索引号。如果省略了此参数,则会列出所有邮件的信息。服务器会以以下格式响应LIST
?命令:
如果未指定<message_number>
?(列出所有邮件):
+OK <邮件总数> messages (<邮件总大小> octets)
<邮件1的索引号> <邮件1的大小>
<邮件2的索引号> <邮件2的大小>
...
<邮件n的索引号> <邮件n的大小>
.
+OK
? 表示命令执行成功。<邮件总数>
? 是邮箱中邮件的数量。<邮件总大小>
? 是所有邮件的总大小(以字节为单位)。<邮件i的索引号>
? 表示第i封邮件的索引号。<邮件i的大小>
? 表示第i封邮件的大小(以字节为单位)。如果指定了<message_number>
?(列出特定邮件):
+OK <邮件索引号> <邮件大小>
+OK
? 表示命令执行成功。<邮件索引号>
? 是指定邮件的索引号。<邮件大小>
? 是指定邮件的大小(以字节为单位)。检索特定邮件的内容,其中邮件的索引号由客户端指定。RETR命令可用于下载邮件的正文和标头。
命令格式:
RETR <message_number>
服务器会以以下格式响应RETR
?命令:
如果命令执行成功:
+OK
<邮件内容>
.
+OK
? 表示命令执行成功。<邮件内容>
? 包含了邮件的完整内容,包括邮件头和正文。通常,邮件内容以文本格式返回。.
?(句号)表示邮件内容的结束。如果命令执行失败(邮件不存在或索引号无效):
-ERR <错误消息>
-ERR
? 表示命令执行失败。<错误消息>
? 包含有关失败原因的描述。标记特定邮件以删除它们,但不会立即从服务器上删除它们。删除操作只有在客户端执行QUIT
?命令时才会生效。
命令格式:
DELE <message_number>
**服务器响应: **
如果命令执行成功(邮件被成功标记为删除):
+OK Message <message_number> deleted
+OK
? 表示命令执行成功。<message_number>
? 是已标记为删除的邮件的索引号。如果命令执行失败(邮件不存在或索引号无效):
-ERR <错误消息>
?-ERR
? 表示命令执行失败。
<错误消息>
? 包含有关失败原因的描述。它不执行任何实际的操作。它的主要目的是告诉邮件服务器,客户端仍然活跃,正在使用连接,以防止连接因长时间不活动而被服务器关闭。
重置或取消标记为删除的邮件,以便这些邮件不会被删除。
RSET命令通常用于撤销之前使用DELE命令标记为删除的邮件。
命令格式:
RSET
命令响应:
如果命令执行成功:
+OK
+OK
? 表示命令执行成功。如果命令执行失败(通常是因为RSET
?命令不支持或出现其他问题):
-ERR <错误消息>
-ERR
? 表示命令执行失败。<错误消息>
? 包含有关失败原因的描述。告知邮件服务器客户端已经完成了邮件收取或管理任务,并请求结束与服务器的连接。
检索邮件的头部信息和指定行数的邮件正文。
?TOP
?命令允许客户端请求邮件服务器返回特定邮件的头部信息和部分邮件正文,以减少数据传输量和加快邮件检索速度。
命令格式:
TOP <message_number> <number_of_lines>
<message_number>
? 是要检索的邮件的索引号。客户端必须提供一个有效的索引号,以指示要检索的邮件。<number_of_lines>
? 是要返回的邮件正文的行数。客户端可以指定要检索多少行邮件正文,通常用于查看邮件的摘要信息。响应:
+OK
<邮件头部信息>
<邮件正文的前n行>
.
+OK
? 表示命令执行成功。<邮件头部信息>
? 包含了邮件的头部信息,如发件人、主题、日期等。<邮件正文的前n行>
? 包含了指定行数的邮件正文。.
?(句号)表示邮件内容的结束。检索每封邮件的唯一标识符(UID)。每封邮件都分配了一个唯一的UID,通常用于客户端在与服务器交互时标识邮件,而不仅仅依赖于邮件的序号。
命令格式:
UIDL [message_number]
响应 :
+OK
<message_number> <UID>
+OK
? 表示命令执行成功。<message_number>
? 是邮件的索引号。<UID>
? 是邮件的唯一标识符(UID)。?USER
?命令是POP3(Post Office Protocol Version 3)协议中的一条命令,用于向邮件服务器提供登录用户名。USER
?命令通常是POP3会话的第一步,用于标识客户端要使用的邮箱账户。
?PASS
?命令是POP3(Post Office Protocol Version 3)协议中的一条命令,用于向邮件服务器提供登录密码以完成身份验证。一般情况下,在使用USER
?命令提供用户名后,客户端必须使用PASS
?命令提供相应的密码,以便访问邮箱账户。
?APOP
?(Authenticated Post Office Protocol)是POP3(Post Office Protocol Version 3)协议的一种认证机制。它是一种用于安全地认证邮件客户端与邮件服务器之间的身份的方法。与普通的POP3用户名和密码认证不同,APOP
?使用一种基于哈希函数的挑战-响应机制来认证客户端的身份。
以下是APOP
?认证的工作原理:
?APOP
?认证的优点是它通过使用挑战-响应机制,使得在网络上传输的密码不会以明文形式传输,从而提高了安全性。这种认证机制确保只有知道正确密码的客户端才能通过认证。
请注意,APOP
?认证是一种POP3协议的扩展认证机制,因此并不是所有邮件服务器和邮件客户端都支持它。在使用APOP
?认证之前,确保您的邮件服务器和客户端都支持此认证方式。
通过mail.ReadMessage来解析邮件内容
message, err := mail.ReadMessage(strings.NewReader(source))
if err != nil {
log.Error(err)
return
}
通过解析出来message内部的Header结构可以获取指定key的信息
常见key有: From
?、To
?、Subject
?、Date
?、Content-Type
?、Content-Transfer-Encoding
?
from := message.Header.Get("From")
to := message.Header.Get("To")
subject := message.Header.Get("Subject")
date := message.Header.Get("Date")
message.Header.Get("Content-Type")
message.Header.Get("Content-Transfer-Encoding")
Header实际是个map, 所以可以通过for循环的方式遍历
for k, v := range message.Header {
blog.Info("key: ", k, " value:", v)
}
通常body会带有多行, 并且最后带有.结束符, 所以我们需要将这些过滤掉
str := strings.ReplaceAll(string(body), "\r\n", "")
str = strings.ReplaceAll(str, ".", "")
具体需要使用解析算法需要注根据Content-Transfer-Encoding来判断,比较常用的两种邮件编码方式为BASE64和Quoted-printable。后来的扩展 SMTP协议允许直接在邮件中传递二进制数据,而不用对它们进行邮件编码,人们将这种没有进行邮件编码的二进制数据的邮件内容称为8bit编码,为了与此 相区别,人们将没有进行邮件编码的纯ASCII码字符的邮件称为7bit编码。MIME消息体的邮件编码方式通过MIME消息头中的Content- Transfer- Encoding头字段指定,每种邮件编码方式的介绍如下:
指消息体内容全部是没有经过编码的ASCII字符。
使用base64解析示例:
decodedBody, err := base64.StdEncoding.DecodeString(str)
if err != nil {
log.Fatal("Error decoding Base64:", err)
}
log.Info(string(decodedBody))
Multipurpose Internet Mail Extensions(RFC2045)
?