IMAP的fetch指令的讲解

下面着重讲一下IMAP协议以及fetch指令,因为fetch指令时imap协议的核心功能,所以在此先着重讲解这个,后续回继续讲解别的。
1 IMAP协议数据帧格式
IMAP协议采用对称的收发帧序列号作为一对儿收发数据帧的标识,从而防止接收数据混乱。每个会话的帧序列号都是按照升序增长。帧序列号由字母 数字组成,客户端生产的每个命令的帧序列号都不同。

Send:A001(帧序列号) + 具体指令
Recv:A001(帧序列号) + 响应内容
Send:A002(帧序列号) + 具体指令
Recv:A002(帧序列号) + 响应内容
…………………
…………………
Send:A00N(帧序列号) + 具体指令
Recv:A00N(帧序列号) + 响应内容

  1. Fetch 指令分析
    Fetch指令用于读取邮件的文本内容信息,且仅用于显示的目的。
    2.1 fetch发送指令
    格式:FETCH < sequence set > < message data item names or macro >
    结果:OK-fetch完成
    NO-fetch错误:不能获取该数据
    BAD-未知命令,或者无效参数

参数1:sequence set
要读取的邮件序列集. 就是你想读取的邮件序列号的一个集合,如果UID命令使用了fetch参数,那么该值就是邮件的UID号而不是序列号(具体参考UID指令),具体格式参照下面。
格式:(从实际数据分析得出,协议里面暂时未找到)
a) 读取单个邮件序列号,下面的含义就是要读取邮件序列号为n。

Fetch n 参数2
b) 按顺序读取多个邮件序列号,下面的含义是要读取的邮件序列号为n到n+x,中间用符号’:’来隔开。

fetch n:n+x 参数2

参数2:message data item names or macro
邮件数据项名称或者宏,这些都是fetch指令中定义好的一些表示符号,如果要读取多个数据项,就用一对儿括号包括要读取的项,每项之间用“空格”隔开,如“(ALL BODY FAST )”具体数据项名称参照下面:

ALL:只返回按照一定格式的邮件摘要,包括邮件标志、RFC822.SIZE、自身的时间和信
封信息。IMAP客户机能够将标准邮件解析成这些信息并显示出来。

BODY:只返回邮件体文本格式和大小的摘要信息。IMAP客户机可以识别这些细节,并向
用户显示详细的关于邮件的信息。其实是一些非扩展的BODYSTRUCTURE的信
息。
FAST:只返回邮件的一些摘要,包括邮件标志、RFC822.SIZE、和自身的时间。

FULL:同样的还是一些摘要信息,包括邮件标志、RFC822.SIZE、自身的时间和
BODYSTRUCTURE的信息。

BODYSTRUCTUR: 是邮件的[MIME-IMB]的体结构。这是服务器通过解析[RFC-2822]
头中的[MIME-IMB]各字段和[MIME-IMB]头信息得出来 的。包括的内容有:邮
件正文的类型、字符集、编码方式等和各附件的类型、字符集、编码方式、文件名
称等等。
ENVELOPE:信息的信封结构。是服务器通过解析[RFC-2822]头中的[MIME-IMB]各字段
得出来的,默认各字段都是需要的。主要包括:自身的时间、附件数、收件人、发
件人等。
FLAGS:此邮件的标志。

INTERNALDATE:邮件的实际日期。

RFC822.SIZE:邮件的[RFC-2822]大小

RFC822.HEADER:在功能上等同于BODY.PEEK[HEADER],

RFC822:功能上等同于BODY[]。

RFC822.TEXT:功能上等同于BODY[TEXT]

UID:返回邮件的UID号,UID号是唯一标识邮件的一个号码。

BODY[section] <>:返回邮件的中的某一指定部分,返回的部分用section来
表示,section部分包含的信息通常是代表某一部分的一个数字(邮件块号)或者是下面的某一个部分:HEADER, HEADER.FIELDS, HEADER.FIELDS.NOT, MIME, and TEXT。如果section部分是空的话,那就代表返回全部的信息,包括头信息。
Partial表示获取section指定的块的一段你想要的字符串,不是必要参数,格式为<index.size>,
Index表示起始位置,size表示要读取的大小,如果size大于section选中的部分,那么就返回section选中部分的全部字符串。

BODY[HEADER]返回完整的文件头信息。

BODY[HEADER.FIELDS ()]:在小括号里面可以指定返回的特定字段。

BODY[HEADER.FIELDS.NOT ()]:在小括号里面可以指定不需要返回的特定字段。

BODY[MIME]:返回邮件的[MIME-IMB]的头信息,在正常情况下跟BODY[HEADER]没
有区别。

BODY[TEXT]:返回整个邮件体,这里的邮件体并不包括邮件头。

BODY.PEEK[

]<>
BODY[
]的一个替代形式,它不会隐式设置邮件的 \SEEN(已读) 标记。在 缺省设置时,宏BODY[
]<>会设置邮件的\SEEN标志。如果你想在不设置\SEEN标志的情况下阅读邮件的部分信息,那么可以将该宏替代BODY .PEEK[section],后者完成同前者一样的功能但不会设置该邮件的\SEEN标志。

2.2 fetch 响应
FETCH响应返回客户端的一个邮件的相关数据。这些数据是名称项及其值的数据对儿,这些数据对儿分别被放在一个圆括号中(fetch回来的所有数据都在这对儿括号内,所以fetch回来数据的最后一个字符肯定是‘)’)。意思就是在你发送fetch指令时,响应内容和参数2是一一对应的,具体格式可以参照2.3例子。

如果发送时参数2是格式  ( a b c d )
那么响应的格式就是( a value-a b value-b c value-c d value-d)
注意:a/b/c/d之间用“空格”隔开,响应中也是一样。

注意:
目前从实际数据中得出一个结论,fetch指令中,如果存在BODY系列的请求,那么在fetch响应中,会附带BODY返回邮件内容的长度大小,由一对大括号包括“{size}”,位置在响应中BODY名称和值中间,由空格间隔。参照下面示例,具体示例参照2.3.

Fetch (BODY[xxxxx] {size} value)

由此得出一个结论,要想确认fetch响应是否结束,一个是根据右括号’)’来识别fetch数据内容的尾部,另一个要注意fetch的结束响应 (OK fetch)。

2.3 例

C: 100 FETCH 3:5 BODY[header.fields (Date From Subject)]
/冒号表示间隔的一个范围:请求邮件从3到5之间所有邮件的Date:字段、 From:字段和 Subject:字段的信息/

S: * 3 FETCH (BODY[HEADER.FIELDS (“DATE” “FROM” “SUBJECT”)] {112}
DATE: Tue, 14 Sep 1999 10:09:50 -500
From: [email protected]
Subject: This is the first test message
)
S: * 4 FETCH (BODY[HEADER.FIELDS (“DATE” “FROM” “SUBJECT”)] {113}
DATE: Tue, 14 Sep 1999 10:10:04 -500
From: [email protected]
Subject: This is the second test message
)
S: * 5 FETCH (BODY[HEADER.FIELDS (“DATE” “FROM” “SUBJECT”)] {112}
DATE: Tue, 14 Sep 1999 10:20:26 -500
From: [email protected]
Subject: This is the first test message
S: A100 OK FETCH completed
C: A101 FETCH BODY[TEXT]
S:* This is the fourth test message for IMAP
S: A101 OK FETCH completed

HEADER ([RFC-2822] header of the message)
TEXT ([RFC-2822] text body of the message) MULTIPART/MIXED
1 TEXT/PLAIN
2 APPLICATION/OCTET-STREAM
3 MESSAGE/RFC822
3.HEADER ([RFC-2822] header of the message)
3. TEXT ([RFC-2822] text body of the message) MULTIPART/MIXED
3.1 TEXT/PLAIN
3.2 APPLICATION/OCTET-STREAM
4 MULTIPART/MIXED
4.1 IMAGE/GIF
4.1. MIME ([MIME-IMB] header for the IMAGE/GIF)
4.2 MESSAGE/RFC822
4.2. HEADER ([RFC-2822] header of the message)
4.2. TEXT ([RFC-2822] text body of the message) MULTIPART/MIXED
4.2.1 TEXT/PLAIN
4.2.2 MULTIPART/ALTERNATIVE
4.2.2.1 TEXT/PLAIN
4.2.2.2 TEXT/RICHTEXT
如果我们需要取第一个附件,那么命令就是:
C:a2 fetch 4 body[2];
取第三个区段的第一个子区段文本正文,命令就是:
C:a2 fetch 4 body[3.1];
取第四个区段的第二个子区段再嵌套的第一个子区段的文本正文,命令如下:
C:a2 fetch 4 body[4.2.1]
当然这个例子只是针对于一个特殊的邮件结构,一般的邮件应该都没有这么复杂的结构。

以上是对IMAP的fetch指令的讲解,希望对大家有所帮助。最近一直在关注邮件内容安全加密,想找一些公开的邮件加密软件,PGP用起来太麻烦了,不过倒是找到了一个叫做“隐秘邮”的邮件安全加密软件,是一个免费公开的邮件内容加密服务平台,无论是个人还是企业规模化都可以试用。不过从官网上查看资料其是以邮件加密网关形式存在的,也不用自己管理密钥,从操作和部署都是挺方便安全的,有兴趣的可以企业了解下,如果有更好的选择可以留言给我。谢谢大家!!!
下面着重讲一下IMAP协议以及fetch指令,因为fetch指令时imap协议的核心功能,所以在此先着重讲解这个,后续回继续讲解别的。
1 IMAP协议数据帧格式
IMAP协议采用对称的收发帧序列号作为一对儿收发数据帧的标识,从而防止接收数据混乱。每个会话的帧序列号都是按照升序增长。帧序列号由字母 数字组成,客户端生产的每个命令的帧序列号都不同。

Send:A001(帧序列号) + 具体指令
Recv:A001(帧序列号) + 响应内容
Send:A002(帧序列号) + 具体指令
Recv:A002(帧序列号) + 响应内容
…………………
…………………
Send:A00N(帧序列号) + 具体指令
Recv:A00N(帧序列号) + 响应内容

  1. Fetch 指令分析
    Fetch指令用于读取邮件的文本内容信息,且仅用于显示的目的。
    2.1 fetch发送指令
    格式:FETCH < sequence set > < message data item names or macro >
    结果:OK-fetch完成
    NO-fetch错误:不能获取该数据
    BAD-未知命令,或者无效参数

参数1:sequence set
要读取的邮件序列集. 就是你想读取的邮件序列号的一个集合,如果UID命令使用了fetch参数,那么该值就是邮件的UID号而不是序列号(具体参考UID指令),具体格式参照下面。
格式:(从实际数据分析得出,协议里面暂时未找到)
a) 读取单个邮件序列号,下面的含义就是要读取邮件序列号为n。

Fetch n 参数2
b) 按顺序读取多个邮件序列号,下面的含义是要读取的邮件序列号为n到n+x,中间用符号’:’来隔开。

fetch n:n+x 参数2

参数2:message data item names or macro
邮件数据项名称或者宏,这些都是fetch指令中定义好的一些表示符号,如果要读取多个数据项,就用一对儿括号包括要读取的项,每项之间用“空格”隔开,如“(ALL BODY FAST )”具体数据项名称参照下面:

ALL:只返回按照一定格式的邮件摘要,包括邮件标志、RFC822.SIZE、自身的时间和信
封信息。IMAP客户机能够将标准邮件解析成这些信息并显示出来。

BODY:只返回邮件体文本格式和大小的摘要信息。IMAP客户机可以识别这些细节,并向
用户显示详细的关于邮件的信息。其实是一些非扩展的BODYSTRUCTURE的信
息。
FAST:只返回邮件的一些摘要,包括邮件标志、RFC822.SIZE、和自身的时间。

FULL:同样的还是一些摘要信息,包括邮件标志、RFC822.SIZE、自身的时间和
BODYSTRUCTURE的信息。

BODYSTRUCTUR: 是邮件的[MIME-IMB]的体结构。这是服务器通过解析[RFC-2822]
头中的[MIME-IMB]各字段和[MIME-IMB]头信息得出来 的。包括的内容有:邮
件正文的类型、字符集、编码方式等和各附件的类型、字符集、编码方式、文件名
称等等。
ENVELOPE:信息的信封结构。是服务器通过解析[RFC-2822]头中的[MIME-IMB]各字段
得出来的,默认各字段都是需要的。主要包括:自身的时间、附件数、收件人、发
件人等。
FLAGS:此邮件的标志。

INTERNALDATE:邮件的实际日期。

RFC822.SIZE:邮件的[RFC-2822]大小

RFC822.HEADER:在功能上等同于BODY.PEEK[HEADER],

RFC822:功能上等同于BODY[]。

RFC822.TEXT:功能上等同于BODY[TEXT]

UID:返回邮件的UID号,UID号是唯一标识邮件的一个号码。

BODY[section] <>:返回邮件的中的某一指定部分,返回的部分用section来
表示,section部分包含的信息通常是代表某一部分的一个数字(邮件块号)或者是下面的某一个部分:HEADER, HEADER.FIELDS, HEADER.FIELDS.NOT, MIME, and TEXT。如果section部分是空的话,那就代表返回全部的信息,包括头信息。
Partial表示获取section指定的块的一段你想要的字符串,不是必要参数,格式为<index.size>,
Index表示起始位置,size表示要读取的大小,如果size大于section选中的部分,那么就返回section选中部分的全部字符串。

BODY[HEADER]返回完整的文件头信息。

BODY[HEADER.FIELDS ()]:在小括号里面可以指定返回的特定字段。

BODY[HEADER.FIELDS.NOT ()]:在小括号里面可以指定不需要返回的特定字段。

BODY[MIME]:返回邮件的[MIME-IMB]的头信息,在正常情况下跟BODY[HEADER]没
有区别。

BODY[TEXT]:返回整个邮件体,这里的邮件体并不包括邮件头。

BODY.PEEK[

]<>
BODY[
]的一个替代形式,它不会隐式设置邮件的 \SEEN(已读) 标记。在 缺省设置时,宏BODY[
]<>会设置邮件的\SEEN标志。如果你想在不设置\SEEN标志的情况下阅读邮件的部分信息,那么可以将该宏替代BODY .PEEK[section],后者完成同前者一样的功能但不会设置该邮件的\SEEN标志。

2.2 fetch 响应
FETCH响应返回客户端的一个邮件的相关数据。这些数据是名称项及其值的数据对儿,这些数据对儿分别被放在一个圆括号中(fetch回来的所有数据都在这对儿括号内,所以fetch回来数据的最后一个字符肯定是‘)’)。意思就是在你发送fetch指令时,响应内容和参数2是一一对应的,具体格式可以参照2.3例子。

如果发送时参数2是格式  ( a b c d )
那么响应的格式就是( a value-a b value-b c value-c d value-d)
注意:a/b/c/d之间用“空格”隔开,响应中也是一样。

注意:
目前从实际数据中得出一个结论,fetch指令中,如果存在BODY系列的请求,那么在fetch响应中,会附带BODY返回邮件内容的长度大小,由一对大括号包括“{size}”,位置在响应中BODY名称和值中间,由空格间隔。参照下面示例,具体示例参照2.3.

Fetch (BODY[xxxxx] {size} value)

由此得出一个结论,要想确认fetch响应是否结束,一个是根据右括号’)’来识别fetch数据内容的尾部,另一个要注意fetch的结束响应 (OK fetch)。

2.3 例

C: 100 FETCH 3:5 BODY[header.fields (Date From Subject)]
/冒号表示间隔的一个范围:请求邮件从3到5之间所有邮件的Date:字段、 From:字段和 Subject:字段的信息/

S: * 3 FETCH (BODY[HEADER.FIELDS (“DATE” “FROM” “SUBJECT”)] {112}
DATE: Tue, 14 Sep 1999 10:09:50 -500
From: [email protected]
Subject: This is the first test message
)
S: * 4 FETCH (BODY[HEADER.FIELDS (“DATE” “FROM” “SUBJECT”)] {113}
DATE: Tue, 14 Sep 1999 10:10:04 -500
From: [email protected]
Subject: This is the second test message
)
S: * 5 FETCH (BODY[HEADER.FIELDS (“DATE” “FROM” “SUBJECT”)] {112}
DATE: Tue, 14 Sep 1999 10:20:26 -500
From: [email protected]
Subject: This is the first test message
S: A100 OK FETCH completed
C: A101 FETCH BODY[TEXT]
S:* This is the fourth test message for IMAP
S: A101 OK FETCH completed

HEADER ([RFC-2822] header of the message)
TEXT ([RFC-2822] text body of the message) MULTIPART/MIXED
1 TEXT/PLAIN
2 APPLICATION/OCTET-STREAM
3 MESSAGE/RFC822
3.HEADER ([RFC-2822] header of the message)
3. TEXT ([RFC-2822] text body of the message) MULTIPART/MIXED
3.1 TEXT/PLAIN
3.2 APPLICATION/OCTET-STREAM
4 MULTIPART/MIXED
4.1 IMAGE/GIF
4.1. MIME ([MIME-IMB] header for the IMAGE/GIF)
4.2 MESSAGE/RFC822
4.2. HEADER ([RFC-2822] header of the message)
4.2. TEXT ([RFC-2822] text body of the message) MULTIPART/MIXED
4.2.1 TEXT/PLAIN
4.2.2 MULTIPART/ALTERNATIVE
4.2.2.1 TEXT/PLAIN
4.2.2.2 TEXT/RICHTEXT
如果我们需要取第一个附件,那么命令就是:
C:a2 fetch 4 body[2];
取第三个区段的第一个子区段文本正文,命令就是:
C:a2 fetch 4 body[3.1];
取第四个区段的第二个子区段再嵌套的第一个子区段的文本正文,命令如下:
C:a2 fetch 4 body[4.2.1]
当然这个例子只是针对于一个特殊的邮件结构,一般的邮件应该都没有这么复杂的结构。

以上是对IMAP的fetch指令的讲解,希望对大家有所帮助。最近一直在关注邮件内容安全加密,想找一些公开的邮件加密软件,PGP用起来太麻烦了,不过倒是找到了一个叫做“隐秘邮”的邮件安全加密软件,是一个免费公开的邮件内容加密服务平台,无论是个人还是企业规模化都可以试用。不过从官网上查看资料其是以邮件加密网关形式存在的,也不用自己管理密钥,从操作和部署都是挺方便安全的,有兴趣的可以企业了解下,如果有更好的选择可以留言给我。谢谢大家!!!

猜你喜欢

转载自blog.csdn.net/Bi_HH/article/details/87935487