RFC 2046 二

4. 5. 2. PostScript Subtype(标注类型)
   "application/postscript"的类型显示一个有标注的程序。通常允许两个不同的标注
语言;起始的标注1变量在[POSTSCRIPT]中描绘,另外一个标注变量在[POSTSCRIPT2]描绘。
   标注是一个Adobe体系公司的一个注册商标,MIME类型的使用
"application/postscript"意味着商标的所有的权利。
     标注语言定义提供了设施,为了内部的特殊的语言特征定义,用在程序中使用。这种
特殊语言的标号特征叫做标注文档结构规范或DSC。DSC是非常普通和充分的用于常规的信
息系统中。不管有没有要求,它被强烈的推荐使用,作为一个互用性的辅助。缺乏常规的习
惯性的结构的文档不能让人相信会在一个给定的环境下工作。同样地,一些系统可能设定最
坏的情况并拒绝处理无结构的文档。
   普通目的的执行标注细节是有严重的安全性隐患,实现者会气馁于发送一些带标注体
"off- the-shelf"的翻译。然而它通常是安全的,在发送标注给一个打印机时,在那里通过
一个典型的打印环境潜在的伤害是很大的,执行者应该考虑所有的下面个情况,在他们增加
交互式的显示标注体给他们的MIME读者的时候。
   下面是这部分的一些概要,虽然可能不全,和在标注实体传输中的可能出现的问题。
   (1)PostScript语言危险的操作包括,但不是限制,"deletefile", "renamefile",
"filenameforall", 和 "file"."File"只在一些费标准的输入输出应用中是危险的。执行可
能定义非标准的文件操作;这些可能产生对安全的危险。 "Filenameforall"文件搜索操作
通配符 ,在第一次出现时无危险的。                                       
          然而,这种操作潜在的暴露有用的信息,这种信息可能本身是敏感的。
消息发送者应该避免使用有潜在危险的文件操作符,既然这些操作符是十分可能引发安全
问题。消息接受和显示软件应该消除所有的安全隐患的文件操作符或采取特殊的方法。当
PostScript 解释器处理文件时,这些操作符应该被当作外部的代理。那样的话,使and/or
检查应该在到达解释语言本身之前完成。注意确保没有enabling full函数方法存在。       
          
    (2) PostScript 语言给现有的标准的解释器提供工具或服务等。外部环境的改变,
通常保留在文件里,有时也会存于容易丢失的内存中。与解释器相关的操作和文件有潜在的
接口。然而,无限制地使用会导致拒绝服务。PostScript解释器的操作包括exitserver操
作和startjob操作。消息发送和接收软件不应该生成PostScript,而是让解释器来完成,
既然退出的能力可能是难以获得的,在PostScript安全执行时。消息发送和接收软件应该
完全不能有能力来保留PostScript环境的改变,通过排除或禁止"startjob" 和
"exitserver"操作。 如果这些操作不能排除或完全的禁止和他们相关联的密码,就应该设
置一个hard- to-guess值。
    (3) PostScript 提供操作来设置system-wide和device-specific参数。这些参数设
置可能保留交叉的工作也可能对解释器正确操作造成危险。PostScript设置系统和设备
参数的操作包括,但不仅限于,    "setsystemparams" 和 "setdevparams"操作。消息发
送软件不应该产生依靠系统和设备参数设置能正确操作的PostScript。设置这些参数的能
力可能在安全的PostScript执行中被禁止。消息发送和显示软件有能力禁用系统和设备参
数的设置。如果这些操作不能完全禁用和他们有关的密码,至少应该设置一个
hard-to-guess值。
    (4)一些 PostScript 的执行器提供了非标准的工具来直接登陆和执行机器代码。
那样的工具是十分下容易找的,以至于滥芋充数。消息发送软件不应该提供那样的功能。
包括hardware-specific在内,它们可能在PostScript安全执行器中不可用的。消息
接收和显示软件不应该允许那样的操作,如果它们存在的话
   (5)PostScript是一种扩展语言,它的许多执行器提供了各自的扩展。本文档不
讨论这些有不确定因素的扩展。消息发送软件不应该使用非标准的扩展;因为它们可能
在一些执行器中丢失。消息发送和显示软件应该保证非标准的PostScript操作是安全的、
不会产生任何的危险。
    (6)写一个消耗大量的系统资源的PostScript是可能的。写一个循环执行的
PostScript也是可能的。如果把这两种类型的程序大送给信任的收件人,可能引起
破坏。消息发送软件应该避免解释和分发那样的程序,因为它是反社会的。消息接收和
显示软件应该提供适当的机制,当合理数量的时间消逝后作中断处理。另外,PostScript
解释器应该被限制只使用合理数目的系统资源。                 
   (7) 在PostScript里面可能包括各种形式的原始的二进制数据。在因特网邮件上
不推荐这样使用。其一是因为不是所有PostScript解释器支持这种数据格式,其二是因为
这样会使MIME Content-Tansfer-Encoding(内容传送编码)变得复杂。(没有那样的二进制
数据,PostScript可能是把数据当作line-oriented数据,如果把二进制数据和
line-oriented数据数据混合在单一的Postscript 数据流里面,PostScript把数据当作
CRLF处理,结果非常会出现问题。)
    (8) 最后,某些PostScript解释器可能存在bug,在接受者的系统里可能引发未被
授权的问题。有些我们没有办法对付,有些可以采取适当的方法纠正。
4. 5. 3. 其它application的子类型
   将来有可能定义许多其它的application的子类型。MIME执行器必须最低限度把
任何不可识别的子类型当作"application/octet-stream"类处理。
5. Composite Media Type Values(复合类型值)
   七个内容类型中复合类型占了两个。复合实体可以被MIME机制处理--一个MIME处理
器代表性地直接处理主体部分。
5. 1. Multipart Media Type(多部分类型)
      在multipart entity(多部分实体)的例子中,一个或多个不同的数据集合并在一
个单一的body(体)中,一个"multipart"(多部分)类型 field的(域)必须出现在实
体的header(头域)。body(体)必须包括一个或多个body part(体部分),每一个位
于boundary(边界)定界符线之前,最后一个则跟着一个结束边界定界符线。在它的
边界定界符线后,每一个体部分由头域、空行、体组成。因此一个体部分在语法上类
似于RFC 822中的message(消息),但是在意义上是不同的。
      一个体部分是一个实体,因此实际上不会被当作RFC 822中的消息来解释。首先,
在体部分中实际上不需要头域。因此,一个以空行开始的体部分是允许的,它被解释
成缺省值的头域。在这样的一个例子中,Content-Type(内容类型)被解释成
"text/plain; charset=US-ASCII".                            
       唯一有意义的体部分头域是以那些以"Content-"开始的名字。在体部分中所有其它
的头域可能被忽视。虽然它们通常很有可能被保留下来,必要时可以被网关丢弃。其它的域
被允许出现在体部分中但不受支持。以"X-"开始的域可能实验或私人目的被创建,它们包含
的这些信息被识别出来后,可能会被某些网关丢弃。  
注意:RFC 822消息和体部分的区别是微妙的、不重要的。 一个因特网和X.400邮件的
网关,举个例子说,必须能识别一个包含图像的体部分和一个包含压缩消息的体部分,
这个压缩的消息是一幅JPEG图像。为了描绘后者,体部分必须有"Content-Type:
message/rfc822",并且它的体(空行之后)必须是压缩的消息,它自己的体头域是
   "Content-Type: image/jpeg"。相似的语法便于消息到体部分的转化,反之亦然,
但是它们两个的区别必须被实现程序理解。(因为在特殊的情况下,体部分实际上是消
息,也可以定义为"digest"子类型。)
      正如前面所说,每一个体部分是在包含边界定界符的边界定界符线之前。边界
定界符不能出现在任何的压缩部分里面、本身的行上、任何行的前缀。这表明在至关
重要的一点是应该选一个结构代理和指定一个统一的边界参数值,在多部分的内部
不要包含边界参数值。
      所有目前和将来出现的多部分子类型必须使用同样的语法。在它们的语义上子类
   型可能不同,并在语法上强加于另外的限制,但是必须使多部分必要的语法一致。
   这种必要确保所有用户代理至少能够识别和区分多部分实体的体部分,即使是那些
   未被公认的子类型。
      正如在内容传送编码[RFC 2045]中规定的,除了 "7bit", "8bit", 和 "binary"
   外多部分实体不允许其它的编码。多部分边界定界符和头域在所有的例子中总是描
述成7bit US-ASCII(虽然头域可能编码成非US-ASCII的正文,参见 RFC 2047),体
部分的数据被编码成相应的内容传送编码。            [Page 18]
5. 1. 1.Common Syntax(共同语法)
        这部分定义多部分子类型的共同的语法。所有的多部分子类型必须使用该语法。
   一个简单的例子会在这部分的后面出现。在RFC 2049给出了一个更复杂的多部分消息
的例子。
        多部分实体的内容类型域需要一个边界参数"boundary"。边界定界符线定义为
   由两个连字符("-",十进制值是45)和紧跟着从内容类型头域取来的"boundary"边界
   参数值组成,空格和CRLF分隔符可选。
   注意:连字符在早期的RFC 934中的压缩消息不兼容,搜索边界符然后执行是容易的。
   然而,应该提醒多部分的消息不完全和RFC 934RFC 934中的压缩消息兼容;特别地,
   它们不服从RFC 934规定的内含连字符开头的行引用。这种机制后来不用了,因为后者
   引用了前一级的引用。这种合并使连字符在这种情况下不合适。
   设计实现程序的警告:关于内容类型的语法参数设置边界参数值经常是必要的,边界
   参数值要被后面引用。虽然不一定是必需的,但不会有危害。实现者必须仔细的学习
   语法以免产生无效的内容类型域。因此,一个多部分的内容类型头域可能像下面的样
子:
    Content-Type: multipart/mixed; boundary=gc0p4Jq0M2Yt08j34c0p
   但是下面是无效的:
    Content-Type: multipart/mixed; boundary=gc0pJq0M:08jU534c0p
   (由于冒号)必须改为:
    Content-Type: multipart/mixed; boundary="gc0pJq0M:08jU534c0p"
       这个内容类型值表明内容有一个或多个部分组成,每一个部分相互独立,语法结构
   相同是RFC 822中的消息,头域允许空,体部分在边界线      
     --gc0pJq0M:08jU534c0p前。
        边界线必须出现在行的开始,i.e.紧跟着CRLF分隔符,边界定界符线被认
   为紧接着初始的CRLF,而不是前面部分的一部分。分界符可能跟着0或多个空格
   。然后被另一个 CRLF分隔符终止。开始下一个体部分的头域或两个 CRLF分隔符
(即空行)。如果内容类型域没有则表示它使用缺省的"multipart/digest"每个
   体部分的子类型为"message/rfc822",或是"text/plain"类型。
   注意:位于边界定界符线之前的CRLF概念性地依附于边界符,因此它可能不以
   CRLF结束(空行)。体部分必须被认为以空行结束,因此在边界定界符行之前
   需要两个CRLF,第一个是前面体部分地一部分,后一个是压缩边界的一部分。
       编界定界符不能出现在压缩的原文里面,并且不能大于70个字符,不计算
前面的连字符。
       最后一个体部分的边界定界符行是特别的,在它之后没有其它的体部分了。
该边界定界符行与前面的边界定界符行一样,只是在定界符值后多了两个连字符。
   如--gc0pJq0M:08jU534c0p--
   设计实现程序注意:边界字符串和边界值对照,在每一个候选行的开始处。一个
   确切的匹配整个候选行不是必需的;但有充分的理由让边界出现在所有CRLF结束
   后。
       在第一个定界符行和最后一个定界符行之间应留出一些空间给附加的信息。
   这个区域通常有一些空白在左边,执行器必须忽略在第一个和最后一个边界行之
   间的空白。
   注意:"preamble"(导言)和"epilogue"(结尾)部分通常是没用的,因为在网关
   处理这些区域时这部分缺乏适当的类型和清楚的语义,特别在X.400 网关。然而,
   去掉preamble部分空白后,许多MIME执行器发现这是一个便利的地方,
   可以插入一些解释性的注释给收件人看,他可以用pre-MIME软件读取这部分消息,
   既然它们被MIME软件忽略。
   注意:因为边界定界符不能出现在体部分,用户代理必须小心翼翼的选择一个一致的
   边界符参数值。在上面的例子中边界符参数值是由一个设计的运算器产生的,
   这个值必须几乎不可能和现存的压缩数据重合,且不要事先扫描数据。改变运算
   规则导致更多的易读的边界定界符容易被一个老的用户代理接收,但是要更多注意
   可能该边界定界符会出现在一些数据行中。最简单的边界行是"---",相应的结束
   边界行是"-----"。 作为一个最简单的例子,下面的多部分消息有两部分,它们都是纯
文本,一个明确的指明类型,另一个则不指明:
     From: Nathaniel Borenstein
     To: Ned Freed
     Date: Sun, 21 Mar 1993 23:56:48 -0800 (PST)
     Subject: Sample message
     MIME-Version: 1.0
     Content-type: multipart/mixed; boundary="simple boundary"

     This is the preamble. It is to be ignored, though it
     is a handy place for composition agents to include an
     explanatory note to non-MIME conformant readers.

     --simple boundary

     This is implicitly typed plain US-ASCII text.
     It does NOT end with a linebreak.
     --simple boundary
     Content-type: text/plain; charset=us-ascii

     This is explicitly typed plain US-ASCII text.
     It DOES end with a linebreak.

     --simple boundary--

这里的结尾通常被忽略。
                             
在另一个multipart实体内的主体部分multipart媒体类型的使用是明确允许的。在这种
情况下很明显:我们必须确保嵌套的multipart实体使用不同的边界分隔符。看RFC 2049的
一个嵌套multipart实体的例子。
只有单个主体的multipart媒体类型的使用可能在确定的上下文中是有用的,并且是明
确允许的。
NOTE:经验表明单主体的multipart媒体类型对发送非文本的各媒体类型是有用的。它
有提供了序言的优点,在其中包括了解码指令。而且,许多SMTP(简单邮件传输协议)网
关移动或移除了MIME(多用途的网际邮件扩充协议)的首部字段,一种智能的MIME译码器
甚至能在没有Content-Type(内容类型)头的情况下对multipart(多部分)的边界进行很好的
猜测,从而成功地对报文解码。
对multipart媒体类型来说,唯一的强制性的全局参数是边界参数,它由一个字符集的1
至70个字符组成,这个字符集能健壮的通过邮件网关,不会以white space(空白段)结束。
(若边界分隔线以空白段结束,这空白段必定被认为是由网关添加的,必须删除。)它在下面
的BNF中正式地进行了规定:
boundary := 0*69 bcharsnospace
bchars := bcharsnospace / " "
bcharsnospace := DIGIT / ALPHA / "'" / "(" / ")" /
                      "+" / "_" / "," / "-" / "." /
                      "/" / ":" / "=" / "?"
总之,multipart 实体的主体可以规定如下:
     dash-boundary := "--" boundary
                    ;边界取决于Content-Type field字段的边界参数的值。
     multipart-body := [preamble CRLF]
     dash-boundary transport-padding CRLF
     body-part *encapsulation
     close-delimiter transport-padding
     [CRLF epilogue]
     transport-padding := *LWSP-char
                      ;创建者绝对不能产生非零长度的transport-padding,但接收方必
须能够处理由报文传输添加的padding。
encapsulation := delimiter transport-padding
                      CRLF body-part
delimiter := CRLF dash-boundary
close-delimiter := delimiter "--"
preamble := discard-text
epilogue := discard-text
discard-text := *(*text CRLF) *text
                  ;可以忽视或丢弃
body-part := MIME-part-headers [CRLF *OCTET]
                  ;在主体部分的内容千万不能以特定的虚边界开始,分隔符也不能在主
体的任何地方出现。注意到主体部分的语法分析器不同于报文的语法分析器,正如在文本中
描述的那样。
    OCTET :=
重要的:在这个BNF中显示的成分中自由地插入linear-white-space和RFC822注解是
不允许的。因为这个BNF没有指定一个结构化的报头字段。
注意:在确定的传输领域,RFC822的限制条文比如限制主体部分使用printable
US-ASCII 字符可能并不是有效的。(那就是说,传输领域中存在着类似在RFC821中规定
且在RFC822中假定的internet邮件传输标准,但是没有确定的限制条文。)对这些限制的放
宽可以这样被认为是局部地扩展主体的定义,比如说:在US-ASCII的范围外再包含八位位
组,只要传输支持这些扩展,并且在Content- Transfer-Encoding(内容传输编码)报头字段
中充分地记录。但是头部(不管是报文头还是主体部分的头部)在任何情况下都不允许包含
非US-ASCII字符。
注意:在multipart类型中明显缺少的是一种结构化的主体部分。那些若想提供更多结
构化或完整化的multipart报文传输便利性,则需要定义在语句构成上一致的multipart的子
类型,但在不同部分要定义相互关系。举个例子,multipart的子类型可以被定义为包括一个
特有的部分,它依次被使用来规定不同部分的关系,可以在Content-ID(内容ID)字段注
明。若采用这种方法的话,旧的执行部分将无法识别新的子类型,但将把它作为
multipart/mixed类型,这样使得用户能识别标志的部分。
5. 1. 2处理嵌套的报文和multiparts(多部分)
在这个文档的并发部分定义的"message/rfc822"子类型除非数据用完,否则不会终结。
同样,一个不正确地缩短了的"multipart"实体可能没有终止边界标记,由于邮件系统的瘫痪
在操作上会出现这种情况。
当这些实体嵌入到另一个multipart结构中时,有必要对这些实体进行正确的处理。因
此MIME的执行就要能识别在任何层次内部嵌套中的外层的边界标记。仅仅检查下一个预
期的标记或其它终结条件是不够的。
5. 1. 3 Mixed子类型
当主体部分是独立的并且需要按一定的顺序捆绑时就要用到multipart类型的子类型
"mixed" 。任何一种执行时无法识别的multipart子类型都被视为子类型"mixed"。
5. 1. 4 alternative子类型
"multipart/alternative"类型与"multipart/mixed"在语句构成上是一致的,但语意是不同的。
不同处在于主体的每一部分都是相同信息的选择性版本。
系统应当承认不同部分的内容是可互换的。系统可以根据本地的环境和参照来选择最
好的类型,有时甚至可以通过与用户的交互。对于"multipart/mixed"类型,主体部分的顺序
是很重要的。因此,alternatives以不断忠实于原文的顺序出现。通常,最佳的选择是最后部
分用系统本地环境易于接收的类型。
举个例子,"multipart/alternative"可以用来以文本格式发送报文从而能方便地在任何地方
展现出来:

From: Nathaniel Borenstein
     To: Ned Freed
     Date: Mon, 22 Mar 1993 09:41:09 -0800 (PST)
     Subject: Formatted text mail
     MIME-Version: 1.0
     Content-Type: multipart/alternative; boundary=boundary42

     --boundary42
     Content-Type: text/plain; charset=us-ascii

       ... plain text version of message goes here ...

     --boundary42
     Content-Type: text/enriched

       ... RFC 1896 text/enriched version of same message
           goes here ...

     --boundary42
     Content-Type: application/x-whatever

       ... fanciest version of same message goes here ...

     --boundary42--
在这个例子中,邮件系统理解了"application/x-whatever"格式的用户只愿看到想要的版
本,而其它用户根据他们系统的实际容量将只愿看到enriched(丰富的)版本或plain text(纯
文本的)版本。
通常,组织"multipart/alternative" 实体的用户代理商必定按偏爱递增的顺序来放置主体部分,
也就是说首选的格式放在最后。对fancy text格式,发送方用户代理商会把最简单的格式放
在最前,最丰富的格式放在最后。接手方用户代理商可挑选显示他们能够显示的最后的格式。
如果二中之一自身是multipart类型且包含不可识别的子部分时,用户代理商就会选择或者
显示这其中之一,即早期的那个,或者两者都显示。
注意:从执行者的观点看,也许把这个顺序倒过来更明智些,就是把最简单的放在最
后。然而,当"multipart/alternative"实体被认为用non-MIME-conformant阅读器时,把最简单
的放在最先是一种可能的选择。然而这种方法加重了conformant MIME阅读器的负担,在
此时它与旧的邮件阅读器的互用性就非常重要了。
也许会出现这种情况,一些用户代理如果能够识别不止一种格式,他们将会让用户选
择观看的格式。举个例子,如果报文既包括了精细格式的image 版本,又包括了易于编辑
的text版本,那将是很有意义的。但是最重要的是,用户并非无意识地看到了同一数据的多
种版本。用户或可看到最后被识别的版本,或可以作出选择。

在MULTIPART/ALTERNATIVE中CONTENT-ID(内容ID)的语义:"multipart/alternative"
实体的每一部分代表了相同的数据,但是两者之间的映射并不一定没有信息丢弃。举个例子,
当把ODA翻译成附言或纯文本时,信息就会丢弃。在两部分信息内容不一致处,建议给每
一部分一个不同的Content-ID(内容编号)值。当信息内容一致时。比如说,
"message/external-body"类型的几个部分规定了交替的方法存取一致的数据,此时就应当使用
相同的Content-ID字段值来优化任何的高速缓存机制,这机制在接受方的终端。然而,如
果有这种Content- ID字段的话,不同部分的Content- ID值也不该与描述
"multipart/alternative"的完全相同。也就是说,一个Content- ID值指着"multipart/alternative" 实
体,然而一个或多个其它的Content-ID值将指向各部分的内部。

转载于:https://www.cnblogs.com/daviyang/archive/2008/02/11/1859244.html

你可能感兴趣的:(RFC 2046 二)