分类:
2011-03-29 13:49:07
SIP头域和HTTP头域在语法和语义上都比较类似。特别的,SIP头域遵循[H4.2]关于消息头的语法的定义,并且遵循多行的扩展头域的规则。(后者 is specified in HTTP with implicit whitespace and folding)。这个规范遵循RFC2234[10],并且把清晰的空白和封装作为内在的语法规则。
[H4.2]也定义了具有相同域名的多个头域,他们的值是用逗号分开的列表,可以合并到一个头域中。这个也适用于SIP,但是细节上略有不同,因为语法不同。实际上,任何SIP的包头语法都是基于如下范式的:
header = “ header-name” HCOLON header-value *(COMMA header-value)
这个允许合并在具有同一个域名的多个头域,到一个用逗号分割的单个头域中。Contact头域除了当域值是”*”之外,都允许用逗号分割的列表。
头域遵循在RFC2822的2.2节定义的通用头域格式。每一个头域都由一个域名加上冒号(”:”)和域值组成。
field-name:field-value
消息头的正则语法在25节中有介绍介绍。
在消息头中,允许在冒号的左右有任意个数的空白;但是,在实现中,建议避免域名和冒号中间有空格,并且建议在冒号和值之间使用单个空格(SP)。
Subject: lunch
Subject : lunch
Subject :lunch
Subject: lunch
所以,上面的都是合法的,也是相等的,但是最后一种是我们所推荐的。
头域可以扩展成为多行的,只要在每一个附加行前边用至少一个SP或者水平TAB(HT)打头就可以了。这种多行的头域在行结尾并且在下一行之前的空白SP(或者HT)将被认为是一个单个的SP字符。所以,下边的例子是相等的:
Subject: I know you’re there, pick up the phone and talk to me!
Subject: I know you’re there,
pick up the phone,
and talk to me!
头域中的不同域名的相关顺序并没有什么意义。虽然如此,我们还是强烈建议与路由相关的域(VIA,ROUTE,Record-Route,Proxy-Require,Max-Forwards,Proxy-Authorization等等)放在消息头的最前边,这样可以提高处理的速度。相同域名的域之间的顺序非常重要。只有当单个头域的域值是可以用逗号分割的列表的时候,才可以表达成为同一个域名的多个头域(这就是说,如果遵循7.3定义的语法)。也就是意味着必须可以将同一个域名的多个头域在不改变消息语义的前提下,改换表达成为一对”域名: 域值”;这个转换是通过顺序增加每一个域的域值,域值之间用逗号分割。这个规则有几个例外,就是WWW-Authenticate,Authorization,Proxy-Authenticate,和Proxy-Authorization头域。多个头域行可以在消息头中出现,但是由于他们的语法并不遵循7.3中定义的通用格式,所以,他们并不能合并成为单个头域行。
在实现上,必须能够既能够处理多个头域行的情况,也必须能够处理用逗号分割的合并的单个头域行的情况。
下边的几组头域是相等的:
Route:
Subject: Lunch
Route:
Route:
Route:
Route:
Subject: Lunch
Subject: Lunch
Route:
下边各组是合法的,但是并不相等。
Route:
Route:
Route:
Route:
Route:
Route:
Route:
每一个头域值的格式是依赖于它的头域名的。他可以是任意顺序的TEXT-UTF8字符,也可以是一个空格,标记,分隔符,引号括起来的字串的组合。很多头域都回附带一个通用的域值格式。这个域值格式是由分号分开的参数名和参数值的组合:
field-name: field-value *(;parameter-name=parameter-value)
虽然在域值里边可以有任意数量的parameter-name/parameter-value对,但是不能允许有相同的parameter-name存在(唯一性)。除了特别指出的头域之外,头域中的域名、域值、parameter name parameter-value都是大小写不敏感的。标记词始终是大小写不铭感的。除非有特别的指定,引号串的字符串是大小写敏感的。例如:
Contact:
和
CONTACT:
相同。
Content-Disposition: session;handling=optional
和
content-disposition: Session;HANDLING=OPTIONAL
相同。
下边的两个头域不相同:
Warning: 370 devnull “Choose a bigger pipe”
Warning: 370 devnull “CHOOSE A BIGGER PIPE”
有一些头域是仅仅在请求(或者应答)中有效的。这些头域叫做请求头域或者应答头域。如果消息中的头域与这个消息的类型不匹配(比如在应答消息中出现的请求头域),这个头域必须被忽略。20节定义了每一个头域的分类。
SIP提供了一个用缩写格式来表达通用头域名字的机制。这个有助于避免消息过大而导致通讯层无法传输(比如在UDP传输的时候超过了最大传输单元(MTU))。这个缩写格式在20节定义。
缩写格式的消息头域名字可以在不改变消息语义的情况下替代较大的消息头域名字。在单个消息中,头域名字既可以用长的格式,也可以用缩写格式。在实现中,必须同时支持对长名字和缩写名字的处理。
请求信息,包括这个规范以后的扩展的新请求,都可以包含一个消息正文体。对消息正文体的解释依赖域请求的方法(请求类型)。对于应答消息来说,请求方法和应答状态(response status code)决定了消息正文体的格式。所有的应答消息都可以有一个消息正文体(body)。
消息中的internet媒体类别必须在Content-Type头域中指明。如果消息正文(body)通过某种形式的编码(encoding),比如压缩等等,都必须在Content-Encoding 头域中指明,否则Content-Encoding域必须忽略。如果可行,消息体的字符集作为Content-type头域的值的一部分表达。
在RFC2046[11]中定义的多部分”multipart” MIME类型可以在消息体中应用。在由多部分组成的消息体发送的时候,如果接受方的实现中,包头域的Accept域中,不包含多部分的标记,那么发送方必须发送一个非多部分的session description。[1]
SIP消息可以包含二进制的包体或者部分包体。如果发送方没有其他显示的字符集参数指出,媒体的文本”text”子类型会是缺省的字符集”UTF
在Content-Length头域中存放了包体的字节长度。第20.14节讲述了本域的详细解释。
HTTP/1.1的“chunked”传输编码方式并不适用于SIP。(备注:chuncked编码传输方式是通过把消息正文体分为一系列的块来传输的,每一块有它自己的大小标记)
不同于HTTP的是,SIP实现可以使用UDP或者其他非可靠传输协议。每一帧包括一个请求或者应答。第18节讲述了非可靠传输的应用。
在处理以面向流的通讯为基础的SIP消息的时候,必须忽略在开始行之前的CRLF[H4.1]。
Content-Length头域用来确定每一个SIP消息在通讯流中的结束位置的。在基于面向流通讯基础上的SIP消息一定要使用这个头域。