如何解析EML(邮件)格式的文件以及一款小巧的EML邮件阅读工具
在理解EML格式的时候,先回顾一下历史,这样有助于理解邮件的格式,比如邮件传输时为何会有多种编码方式。此外,理解EML格式也有助于理解HTTP协议。
历史溯源
由于历史原因,我们目前看到的大部分的网络协议都是基于ASCII码这种纯文本方式,也就是基于字符串的命令行方式,比如HTTP、FTP、POP3、SMTP、TELNET等。
早期操作系统比如Unix或DOS没有图形界面,用户与电脑之间只能通过控制台进行交互,也就是通过键盘将命令(或请求)输入到电脑,当用户回车换行(\r\n)时,表示命令输入完毕。如果存在网络通信,则该命令包括用户敲击的回车换行会一并发送到服务器端,服务器端接收数据时,就会以回车换行来界定一条完整的命令是否获取完毕,否则会继续等待直到接收到"\r\n"或超时,当请求接收完毕后,服务端会执行该请求并将响应结果返回给客户端。
理解这一点非常重要,这就是为什么很多网络应用层协议都是以"\r\n"来作为结束标记。对于多行请求时,通常以两个连续的回车换行表示请求结束,也就是"\r\n\r\n",直观的用肉眼观察就是存在一个空行。
比如HTTP协议,与主机建立连接后,输入"GET / HTTP/1.1\r\n\r\n"即可获取网站的主页。
回到Email协议(SMTP和POP3),早期的电子邮件只支持ASCII码这种纯文本传输方式,但随着全世界人民对物质文化生活的不断向往,这种落后的传输方式,已经无法满足世界人民对美好生活的追求,比如图像、视频、音频、Office文件如何在邮件中展现?不同国家(非英语国家)字符集该如何传输和展现?
换句话说,就是这种非ASCII的二进制富文本,该如何传输和呈现?
MIME的诞生
此时MIME标准诞生了,MIME的出现更多的是一种向下兼容的无奈,而不是革命。通过对二进制数据或非ASCII码数据进行base64或quoted-printable编码,来实现纯ASCII码的传输。显然这种方式会让你的邮件体变大,传输效率下降。尤其附件很多时,通过MIME的boundary来解析邮件的附件也是一笔额外的负担。
同时MIME的标准也被HTTP协议所采用,我们可以通过content-type字段指定传输的内容是什么类型,通过MIME的boundary来对Form-Data数据进行扩展,让我们在POST数据时也能够在“表格”数据中插入文件,从而达到上传文件的效果。
下面是一个EML格式的文件截图,该截图是一个邮件头,该邮件头包含几个重要字段,Subject(主题),From(发件人)To(接收人),Cc(抄送人),Date(发送日期)。
其中一个最重要的字段就是Content-Type。只有解析了Content-type字段我们才能准确的将邮件体给解析并展现出来。
通过上图我们可以观察到该邮件的内容是一个混合类型,由多个部分组成,Content-type字段中的boundary被用来分割不同的部分。下图显示的是一个邮件的附件文件,该文件类型为pdf。
boundary的前缀加上"--"表示新的邮件内容的开始,紧接着为几行MIME头,仔细观察MIME头则会发现,这些字段其实和HTTP协议的头的字段是相同的。空行后则是具体的邮件内容,这些邮件内容的传输编码方式有两种:一种是base64,一种是quoted-printale,当然也可能是未编码。通常情况下,采用quoted-printable方式对HTML(邮件正文)进行编码,而对于附件文件(比如二进制文件),则采用base64进行编码。
邮件的正文可能有两个:一个是HTML格式,一个是Plain格式。为什么会有两个格式的正文?其实这两个格式展现出来的内容都是一样的,这样做的目的是为了客户端的兼容,早期的的邮件客户端可能无法显示HTML格式,或者对HTML格式的兼容性不是很好,当然喽这也是历史原因造成的。现在的邮件客户端都能显示HTML的正文了。
当邮件结束时,是以"--"+boundary+"--"来标记,也就是给boundary加上前缀"--"和后缀"--"。
通过对MIME格式的分析我们可以看到解析Content-type字段很重要,通过提取boundary并循环查找,就可以解析出不同的邮件体,从而将一封EML格式的电子邮件展现出来。
最后注意一点: MIME头中字符串采用特有的简洁的编码方式,将字符集和编码方式集成到了一起,以"=?"开始,以"?="结束。"=?"后为字符集,紧接着"?"后表示编码方式。B(b)为base64编码,Q(q)为quoted-printable编码。如下图:
EmlReader是一个客户端程序,比这更轻量级的是下面的EmlParse工具,不到150K,可批量解析eml格式邮件,并提取邮件中的正文和附件到指定目录中:
EmlParse:一款超轻量级的批量解析EML格式电子邮件的工具