MIME协议分析(转)

2024-02-19 18:18
文章标签 分析 协议 mime

本文主要是介绍MIME协议分析(转),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

第1章.     MIME概述

MIME, 全称为“Multipurpose Internet Mail Extensions”, 比较确切的中文名称为多用途互联网邮件扩展。它是当前广泛应用的一种电子邮件技术规范,基本内容定义于RFC 2045-2049(注意RFC1521RFC1522是它的过时版本)。

MIME试图在不改变SMTP协议和RFC822(邮件格式标准)的基础上,使得邮件可以传送任意二进制文件。为此,它在这些协议之上,采取了一些措施,这就是我们下面所要重点讲述的内容。

第2章.     MIME详解

2.1.  改进措施

一封邮件包括信封、邮件头和邮件体等三个部分。信封显然可以不含有二进制信息,而其它两部分则可能包含任意二进制序列,因此需要加以改进。MIME正是抓住了这两个地方来对他们加以改进。

1)        新增了一些邮件头信息,用来协商MIME的一些参数。

2)        定义了许多邮件内容的格式,对多媒体电子邮件的表示方法进行了标准化。

3)        定义了传送编码,从而可以传送任意二进制文件。

在这里,我还是要不厌其烦地强调指出,所有的改进措施都是建立在不改变原来的SMTP协议和RFC822的基础上的。事实上,我们可以把这些改进措施,看成是在用SMTP等发送邮件前所采取的预处理。

2.2.  一封简单邮件的源码

为了对MIME邮件有个直观的了解,先给出一封简单邮件的源码。源码中,行号和行号后的空格是为了分析方便而另外加的,“... ... ... ...”表示此处省略了大段编码。

   1 From: "bhw98" <bhw98@sina.com>

   2 Reply-To: bhw98@sina.com

   3 To: <bluesky7810@163.com>

   4 Subject: Re: help

   5 X-Mailer: Foxmail 4.2 [cn]

   6 Mime-Version: 1.0

   7 Content-Type: multipart/alternative;

   8  boundary="=====002_Dragon307572345230_====="

   9

  10

  11 This is a multi-part message in MIME format.

  12

  13 --=====002_Dragon307572345230_=====

  14 Content-Type: text/plain; charset="GB2312"

  15 Content-Transfer-Encoding: quoted-printable

  16

  17 bluesky7810=A3=AC=C4=FA=BA=C3=A3=A1

  18

  19 =A1=A1=A1=A1=D4=DA=CF=C2=C6=AA=D7=EE=BA=F3=BF=C9=D2=D4=CF=C2=D4=D8=B0=A1=A3=AC=C4=E3

     ... ...  ... ...

  30 =A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=A12003-04-07

  31

  32 --=====002_Dragon307572345230_=====

  33 Content-Type: text/html; charset="GB2312"

  34 Content-Transfer-Encoding: quoted-printable

  35

  36 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

  37 <HTML><HEAD>

  38 <META content=3D"text/html; charset=3Dgb2312"=

  39  http-equiv=3DContent-Type>

  40 <META content=3D"MSHTML 5.00.2920.0" name=3DGENERATOR>

     ... ...  ... ...

  79 </HTML>

  80

  81 --=====002_Dragon307572345230_=====--

  82

我们可以在用户代理中查看到这样的源码。例如可以利用用户代理来查看一封邮件的原始编码。例如在Foxmail中,选定邮件后,单击右键,选择“原始信息”项即可。至于源码的具体意思则正是后续内容所要讲的。

2.3.  邮件头

2.3.1.  邮件头的域

邮件头包含了发件人、收件人、主题、时间、MIME版本、邮件内容的类型等重要信息。每条信息称为一个域,由域名后加“”和信息内容构成,可以是一行,较长的也可以占用多行。域的首行必须“顶头”写,即左边不能有空白字符(空格和制表符);续行则必须以空白字符打头,且第一个空白字符不是信息本身固有的,解码时要过滤掉。如例27-8行分别属于一个域。

表 1中给出了邮件头中常见的域,域的含义,和域值的添加者。

域名

含义

添加者

Received

传输路径

各级邮件服务器

Return-Path

回复地址

目标邮件服务器

Delivered-To

发送地址

目标邮件服务器

Reply-To

回复地址

邮件的创建者

From

发件人地址

邮件的创建者

To

收件人地址

邮件的创建者

Cc

抄送地址

邮件的创建者

Bcc

暗送地址

邮件的创建者

Date

日期和时间

邮件的创建者

Subject

主题

邮件的创建者

Message-ID

消息ID

邮件的创建者

MIME-Version

MIME版本

邮件的创建者

Content-Type

内容的类型

邮件的创建者

Content-Transfer-Encoding

内容的传输编码方式

邮件的创建者

表 1 邮件头中常见的域

非标准的、自定义域名都以X-开头,例如X-Mailer, X-MSMail-Priority等,通常在接收和发送邮件的是同一程序时才能理解它们的意义。除了后面两个域外,其他的域的意思很明了,所以下面只对后两个域做解释。

2.3.2.  Content-Type

Content-Type域,即内容类型域,它用来说明传输的内容的类型。Cotent-Type域又由“主类型/子类型”构成,主类型有text, image, audio, video, application, multipart, message等,分别表示文本、图片、音频、视频、应用、分段、消息等。每个主类型都可能有多个子类型,如text类型就包含plain, html, xml, css等子类型。以X-开头的主类型和子类型,同样表示自定义的类型,未向IANA正式注册,但大多已经约定成俗了。如application/x-zip-compressedZIP文件类型。在Windows中,注册表的“HKEY_CLASSES_ROOT\MIME\Database\Content Type”内列举了除multipart之外大部分已知的Content-Type

各种各种类型一般都可以带参数。至于参数的形式,RFC里有很多补充规定,有的允许带几个参数,较为常见的如表 2所示

主类型

参数名

含义

text

charset

字符集

image

name

名称

application

name

名称

multipart

boundary

边界

表 2 常见类型的参数

 

2.3.3.  Content-Transfer-Encoding

Content-Transfer-Encoding域即传送编码域,它用来说明后面传输的内容的编码方式。

Content-Transfer-Encoding共有Base64, Quoted-printable, 7bit, 8bit, Binary等几种。其中7bit是缺省的编码方式。电子邮件源码最初设计为全部是可打印的ASCII码的形式。非ASCII码的文本或数据要编码成要求的格式,如上面的三个例子。Base64, Quoted-Printable是在非英语国家使用最广使的编码方式。Binary方式只具有象征意义,而没有任何实用价值。关于Base64编码和Quoted-Printable编码请参考RFC文档或另外一篇文章《SMTP协议分析》。

近年来,国内多数邮件服务器已经支持8bit方式,因此只在国内传输的邮件,特别是在邮件头中,可直接使用8bit编码,对汉字不做处理。如果邮件要出国,还是老老实实地按Base64Quoted-printable编码才行

2.4.  邮件体

邮件体的类型由邮件头的“Content-Type”域指出。常见的简单类型有text/plain(纯文本)text/html(超文本)

源码中出现的multipart类型,是MIME邮件的精髓。邮件体被分为多个段,每个段又包含段头和段体两部分,这两部分之间也以空行分隔。常见的multipart类型有三种:multipart/mixed, multipart/relatedmultipart/alternative。从它们的名称,不难推知这些类型各自的含义和用处。它们之间的层次关系可归纳为图 1所示

+------------------------- multipart/mixed ----------------------+                                                                      |  +----------------- multipart/related -------------+            |                                                    |  |                                                 |            |                                                                 |  |                                                 |            |
|  |  +----multipart/alternative ---+  +----------+  |  +------+  |  |  |  |                             |  | 内嵌资源 |  |  | 附件 |  |  |  |  |  +-----------+ +----------+ |  +----------+  |  +------+  |
|  |  |  | 纯文本正文| |超文本正文| |                |            |
|  |  |  +-----------+ +----------+ |  +----------+  |  +------+  |
|  |  |                             |  | 内嵌资源 |  |  | 附件 |  |  |  |  +-----------------------------+  +----------+  |  +------+  |
|  |                                                 |            |            |  +-------------------------------------------------+            |                                                                  +-----------------------------------------------------------------+

图 1 邮件体的层次关系图

可以看出,如果在邮件中要添加附件,必须定义multipart/mixed段;如果存在内嵌资源,至少要定义multipart/related段;如果纯文本与超文本共存,至少要定义multipart/alternative段。什么是“至少”?举个例子说,如果只有纯文本与超文本正文,那么在邮件头中将类型扩大化,定义为multipart/related,甚至multipart/mixed,都是允许的。

multipart诸类型的共同特征是,在段头指定“boundary”参数字符串,段体内的每个子段以此串定界。所有的子段都以“--+boundary行开始,父段则以“--+boundary+--”行结束。段与段之间也以空行分隔。在邮件体是multipart类型的情况下,邮件体的开始部分(第一个“--+boundary行之前)可以有一些附加的文本行,相当于注释,解码时应忽略。段间也可以有一些附加的文本行,不会显示出来,如果有兴趣,不妨验证一下。

结合boundary定界和multipart层次关系图,我们分析一下源码中的邮件体层次与段嵌套关系。 在源码中,10-12行是附加文本行,13-82行是multipart/alternative型的段,包含两个子段:13-30行是纯文本正文,32-79行是超文本正文。

需要补充说明地是,构成邮件体的各段有自己的属性,这些属性由段头的域来说明。表 3给出了段头中常见的域。

域名

含义

Content-Type

段体的类型

Content-Transfer-Encoding

这篇关于MIME协议分析(转)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/725520

相关文章

Springboot中分析SQL性能的两种方式详解

《Springboot中分析SQL性能的两种方式详解》文章介绍了SQL性能分析的两种方式:MyBatis-Plus性能分析插件和p6spy框架,MyBatis-Plus插件配置简单,适用于开发和测试环... 目录SQL性能分析的两种方式:功能介绍实现方式:实现步骤:SQL性能分析的两种方式:功能介绍记录

最长公共子序列问题的深度分析与Java实现方式

《最长公共子序列问题的深度分析与Java实现方式》本文详细介绍了最长公共子序列(LCS)问题,包括其概念、暴力解法、动态规划解法,并提供了Java代码实现,暴力解法虽然简单,但在大数据处理中效率较低,... 目录最长公共子序列问题概述问题理解与示例分析暴力解法思路与示例代码动态规划解法DP 表的构建与意义动

C#使用DeepSeek API实现自然语言处理,文本分类和情感分析

《C#使用DeepSeekAPI实现自然语言处理,文本分类和情感分析》在C#中使用DeepSeekAPI可以实现多种功能,例如自然语言处理、文本分类、情感分析等,本文主要为大家介绍了具体实现步骤,... 目录准备工作文本生成文本分类问答系统代码生成翻译功能文本摘要文本校对图像描述生成总结在C#中使用Deep

Redis主从/哨兵机制原理分析

《Redis主从/哨兵机制原理分析》本文介绍了Redis的主从复制和哨兵机制,主从复制实现了数据的热备份和负载均衡,而哨兵机制可以监控Redis集群,实现自动故障转移,哨兵机制通过监控、下线、选举和故... 目录一、主从复制1.1 什么是主从复制1.2 主从复制的作用1.3 主从复制原理1.3.1 全量复制

Redis主从复制的原理分析

《Redis主从复制的原理分析》Redis主从复制通过将数据镜像到多个从节点,实现高可用性和扩展性,主从复制包括初次全量同步和增量同步两个阶段,为优化复制性能,可以采用AOF持久化、调整复制超时时间、... 目录Redis主从复制的原理主从复制概述配置主从复制数据同步过程复制一致性与延迟故障转移机制监控与维

Redis连接失败:客户端IP不在白名单中的问题分析与解决方案

《Redis连接失败:客户端IP不在白名单中的问题分析与解决方案》在现代分布式系统中,Redis作为一种高性能的内存数据库,被广泛应用于缓存、消息队列、会话存储等场景,然而,在实际使用过程中,我们可能... 目录一、问题背景二、错误分析1. 错误信息解读2. 根本原因三、解决方案1. 将客户端IP添加到Re

Redis主从复制实现原理分析

《Redis主从复制实现原理分析》Redis主从复制通过Sync和CommandPropagate阶段实现数据同步,2.8版本后引入Psync指令,根据复制偏移量进行全量或部分同步,优化了数据传输效率... 目录Redis主DodMIK从复制实现原理实现原理Psync: 2.8版本后总结Redis主从复制实

锐捷和腾达哪个好? 两个品牌路由器对比分析

《锐捷和腾达哪个好?两个品牌路由器对比分析》在选择路由器时,Tenda和锐捷都是备受关注的品牌,各自有独特的产品特点和市场定位,选择哪个品牌的路由器更合适,实际上取决于你的具体需求和使用场景,我们从... 在选购路由器时,锐捷和腾达都是市场上备受关注的品牌,但它们的定位和特点却有所不同。锐捷更偏向企业级和专

Java如何接收并解析HL7协议数据

《Java如何接收并解析HL7协议数据》文章主要介绍了HL7协议及其在医疗行业中的应用,详细描述了如何配置环境、接收和解析数据,以及与前端进行交互的实现方法,文章还分享了使用7Edit工具进行调试的经... 目录一、前言二、正文1、环境配置2、数据接收:HL7Monitor3、数据解析:HL7Busines

Spring中Bean有关NullPointerException异常的原因分析

《Spring中Bean有关NullPointerException异常的原因分析》在Spring中使用@Autowired注解注入的bean不能在静态上下文中访问,否则会导致NullPointerE... 目录Spring中Bean有关NullPointerException异常的原因问题描述解决方案总结