MRCPv2 是 Media Resource Control Protocol Version 2 (MRCPv2)的缩写,这一篇翻译RFC6787一节6.2. Generic Message Headers
所有 MRCPv2 头字段,包括以下小节中定义的通用头和稍后定义的资源特定头字段,都遵循与 RFC 5322 [RFC5322] 第 3.1 节中给出的相同通用格式。
每个头字段由一个名称后跟一个冒号(“:”)和值组成。 标题字段名称不区分大小写。 该值之前可以有任意数量的 LWS(线性空白),但最好使用单个 SP(空格)。
通过在每个额外行之前至少使用一个 SP 或 HT(水平制表符),标题字段可以扩展到多行。
generic-field = field-name ":" [ field-value ]
field-name = token
field-value = *LWS field-content *( CRLF 1*LWS field-content)
field-content =
字段内容不包括任何前导或尾随 LWS(即,在字段值的第一个非空白字符之前或字段值的最后一个非空白字符之后出现的线性空白)。 可以在不改变字段值语义的情况下删除此类前导或尾随 LWS。
在解释字段值或向下游转发消息之前,字段内容之间出现的任何 LWS 可以用单个 SP 替换。
MRCPv2 服务器和客户端不得依赖于头字段顺序。 建议首先发送通用头字段,然后是请求头或响应头字段,最后是实体头字段。
但是,MRCPv2 服务器和客户端必须准备好以任何顺序处理头字段。 此规则的唯一例外是当消息中有多个具有相同名称的头字段时。
当且仅当该头字段的整个值被定义为逗号分隔列表时,消息中才可能出现多个具有相同名称的头字段。
由于特定于供应商/设备商的参数可能依赖于顺序,因此必须可以将多个相同名称的头字段组合成一个“名称:值”对而不改变消息的语义,方法是将每个后续值附加到第一个,每个 用逗号分隔。 因此,接收具有相同名称的头字段的顺序对于组合头字段值的解释很重要,因此中间人在转发消息时不得更改这些值的顺序。
generic-header = channel-identifier
/ accept
/ active-request-id-list
/ proxy-sync-id
/ accept-charset
/ content-type
/ content-id
/ content-base
/ content-encoding
/ content-location
/ content-length
/ fetch-timeout
/ cache-control
/ logging-tag
/ set-cookie
/ vendor-specific
所有 MRCPv2 请求、响应和事件都必须包含 Channel-Identifier 头字段。 当控制通道被添加到会话中并通过来自服务器的 SDP 应答中的“a=channel”属性与客户端通信时,该值由服务器分配。
头字段值由“@”符号分隔的两部分组成。 第一部分是一个明确的字符串,用于标识 MRCPv2 会话。 第二部分是一个字符串标记,指定第 3.1 节中列出的一种媒体处理资源类型。
明确的字符串(第一部分)必须难以猜测,在服务器管理的资源实例中是唯一的,并且对于通过单个 SIP 对话与该服务器建立的所有资源通道都是通用的。
channel-identifier = "Channel-Identifier" ":" channel-id CRLF
channel-id = 1*alphanum "@" 1*alphanum
Accept 头字段遵循 [H14.1] 中定义的语法。 语义也是相同的,除了如果不存在 Accept 头字段,服务器必须假设一个特定于被控制的资源类型的默认值。 通过在 SET-PARAMS 方法中发送此头字段,可以为会话中的资源更改此默认值。 可以通过 GET-PARAMS 方法找到会话中资源的此头字段的当前默认值。 此头字段可能出现在任何请求中。
在请求中,此头字段指示请求适用的请求 ID 列表。 当有多个请求处于 PENDING 或 IN-PROGRESS 并且客户端希望此请求专门应用于其中一个或多个请求时,这很有用。
在响应中,此头字段返回该方法修改或影响的请求 ID 列表。 可能有一个或多个请求处于 PENDING 或 IN-PROGRESS 请求状态。 当影响一个或多个 PENDING 或 IN-PROGRESS 请求的方法从客户端发送到服务器时,响应必须在其标题部分包含受此命令影响或修改的请求 ID 列表。
Active-Request-Id-List 仅用于请求和响应,不用于事件。
例如,如果一个没有 Active-Request-Id-List 的 STOP 请求被发送到一个(语音)合成资源,该资源有一个或多个处于 PENDING 或 IN-PROGRESS 状态的 SPEAK 请求,则必须取消所有 SPEAK 请求,包括状态是IN-PROGRESS的。
对 STOP 请求的响应在 Active-Request-Id-List 值中包含所有终止的 SPEAK 请求的请求 ID。 发送 STOP 响应后,服务器不得为终止的请求发送任何 SPEAK-COMPLETE 或 RECOGNITION-COMPLETE 事件。
active-request-id-list = "Active-Request-Id-List" ":"
request-id *("," request-id) CRLF
当任何服务器资源生成“可打断(barge-in-able)”事件时,它还会生成一个唯一标记(unique tag)。 标记在事件中作为此头字段的值发送到客户端。 然后,客户端充当服务器资源之间的中介,并使用从服务器资源接收到的 Proxy-Sync-Id 向(语音)合成服务器资源发送 BARGE-IN-OCCURRED 方法。 当(语音)识别器和(语音)合成器资源属于同一会话时,它们可能会选择一起工作以实现更快的交互和响应。 在这里,Proxy-Sync-Id 帮助接收事件的资源(由客户端作为中介)决定是否已通过资源的直接交互处理此事件。
这个头字段可能只出现在**事件(event)**和 BARGE-IN-OCCURRED 方法上。 此头字段的名称仅出于历史原因包含“代理”一词,并不意味着涉及代理服务器。
proxy-sync-id = "Proxy-Sync-Id" ":" 1*VCHAR CRLF
参见[H14.2]。 这为响应中返回的实体或与此请求关联的事件指定了可接受的字符集。 这对于指定要在 RECOGNITION-COMPLETE 事件的自然语言语义标记语言 (NLSML) 结果中使用的字符集很有用。 此头字段仅用于请求。
见 [H14.17]。 MRCPv2 支持一组受限制的内容注册媒体类型,包括语音标记(speech markup)、语法(gramma)和识别结果(recognition results)。 适用于每个 MRCPv2 资源类型的内容类型在文档的相应部分中指定,并在 IANA 维护的 MIME 媒体类型注册表中注册。 支持多部分内容类型“multipart/mixed”来传达上述内容的多个,在这种情况下,正文部分不得包含任何 MRCPv2 特定的头字段。 这个头字段可能出现在所有消息中。
content-type = "Content-Type" ":" media-type-value CRLF
media-type-value = type "/" subtype *( ";" parameter )
type = token
subtype = token
parameter = attribute "=" value
attribute = token
value = token / quoted-string
此头字段包含可引用内容的 ID 或名称。 此头字段根据 RFC 2392 [RFC2392] 中的规范操作,并且是多部分消息中内容消歧所必需的。 在 MRCPv2 中,无论何时客户端或服务器存储相关内容,都必须可以使用此 ID 检索。 通过使用第 13.6 节中描述的“会话”URI 方案对其进行寻址,可以稍后在会话中引用此类内容。 这个头字段可能出现在所有消息中。
Content-Base 实体头可以用于指定用于解析实体内的相对 URI 的基本 URI。
content-base = "Content-Base" ":" absoluteURI CRLF
但是请注意,实体主体中内容的基本 URI 可以在该实体主体中重新定义。 这方面的一个例子是多部分媒体,它又可以在其中包含多个实体。 这个头字段可能出现在所有消息中。
Content-Encoding 实体头用作 Content-Type 的修饰符。 如果存在,它的值指示已将哪些附加内容编码应用于实体主体,因此必须应用哪些解码机制才能获得 Content-Type 头字段引用的媒体类型。 内容编码主要用于允许压缩文档而不丢失其底层媒体类型的标识。 请注意,SIP 会话可用于确定接受的编码(请参阅第 7 节)。 这个头字段可能出现在所有消息中。
content-encoding = "Content-Encoding" ":"
*WSP content-coding
*(*WSP "," *WSP content-coding *WSP )
CRLF
[H3.5] 中定义了内容编码。 它的一个使用示例是 Content-Encoding:gzip
如果多个编码已应用于一个实体,则内容编码必须按照它们被应用的顺序列出。
Content-Location 实体报头可以用于为包含在消息中的实体提供资源位置,当该实体可以从与所请求资源的 URI 分开的位置访问时。 参考[H14.14]。
content-location = "Content-Location" ":"
( absoluteURI / relativeURI ) CRLF
Content-Location 值是请求时与此特定实体对应的资源位置的声明。 此头字段仅用于优化目的。 这个头字段的接收者可以假设被发送的实体与已经检索到的或者可能已经从 Content-Location URI 中检索到的实体相同。
例如,如果客户端提供了一个内联语法标记,并且它之前已经从某个 URI 中检索到它,则可以使用 Content-Location 头字段将该 URI 作为实体的一部分提供。 这允许像识别器这样的资源查看它的缓存,看看这个语法是否以前被检索、编译和缓存。 在这种情况下,它可能会使用先前编译的语法对象进行优化。
如果 Content-Location 是相对 URI,则相对 URI 被解释为相对于 Content-Base URI。 这个头字段可能出现在所有消息中。
此头字段包含消息正文内容的长度(即,在最后一个头字段之后的双 CRLF 之后)。 与 HTTP 不同,它必须包含在所有携带超出头部分内容的消息中。 如果缺少,则假定默认值为零。 否则,按[H14.13]解释。 当对消息体没有用处的消息包含一个消息时,即 Content-Length 不为零,接收方必须忽略消息体的内容。 这个头字段可能出现在所有消息中。
content-length = "Content-Length" ":" 1*19DIGIT CRLF
当(语音)识别器或(语音)合成器需要获取文档或其他资源时,该头字段控制相应的 URI 访问属性。 这定义了服务器可能需要通过网络获取的内容的超时时间。 该值被解释为以毫秒为单位,范围从 0 到特定于实现的最大值。 建议服务器谨慎接受长超时值。 此头字段的默认值是特定于实现的。 该头字段可能出现在 DEFINE-GRAMMAR、RECOGNIZE、SPEAK、SET-PARAMS 或 GET-PARAMS 中。
fetch-timeout = "Fetch-Timeout" ":" 1*19DIGIT CRLF
如果服务器实现内容缓存,则在访问和缓存存储的内容时,它必须遵守 HTTP 1.1 [RFC2616] 的缓存正确性规则。 特别是,缓存的 URI 或文档的“expires”和“cache-control”头字段必须被尊重,并优先于此头字段设置的 Cache-Control 默认值。
Cache-Control 指令用于为会话或请求定义服务器上的默认缓存算法。 指令的范围基于发送它的方法。 如果该指令是在 SET-PARAMS 方法上发送的,它适用于服务器在该会话期间对外部文档发出的所有请求,除非它被单个请求的 Cache-Control 头字段覆盖。
如果指令是针对任何其他请求发送的,则它们仅适用于服务器为该请求发出的外部文档请求。 GET-PARAMS 方法中的空 Cache-Control 头字段是请求服务器返回服务器上当前的 Cache-Control 指令设置。 此头字段可能仅在请求时出现.
cache-control = "Cache-Control" ":"
[*WSP cache-directive
*( *WSP "," *WSP cache-directive *WSP )]
CRLF
cache-directive = "max-age" "=" delta-seconds
/ "max-stale" [ "=" delta-seconds ]
/ "min-fresh" "=" delta-seconds
delta-seconds = 1*19DIGIT
此处,delta-seconds 是一个十进制时间值,指定从服务器收到消息响应或数据的那一刻起经过的秒数。
不同的缓存指令选项允许客户端要求服务器覆盖默认的缓存过期机制:
max-age Indicates that the client can tolerate the server
using content whose age is no greater than the
specified time in seconds. Unless a "max-stale"
directive is also included, the client is not willing
to accept a response based on stale data.
min-fresh Indicates that the client is willing to accept a
server response with cached data whose expiration is
no less than its current age plus the specified time
in seconds. If the server's cache time-to-live
exceeds the client-supplied min-fresh value, the
server MUST NOT utilize cached content.
max-stale Indicates that the client is willing to allow a server
to utilize cached data that has exceeded its
expiration time. If "max-stale" is assigned a value,
then the client is willing to allow the server to use
cached data that has exceeded its expiration time by
no more than the specified number of seconds. If no
value is assigned to "max-stale", then the client is
willing to allow the server to use stale data of any
age.
如果请求服务器缓存使用未经验证的 陈旧(stale) 响应/数据,则只有在这不与有关缓存验证的任何“必须”级要求(例如,“必须重新验证”缓存控制指令)不冲突时,它才可以这样做 与相应 URI 相关的 HTTP 1.1 规范)。
如果 MRCPv2 Cache-Control 指令和服务器上的缓存条目都包含“max-age”指令,则使用两个值中较小的值来确定该请求的缓存条目的新鲜度。
该头字段可以作为 SET-PARAMS/GET-PARAMS 方法的一部分发送,以设置或检索服务器生成的日志的日志记录标签。 设置后,该值将一直存在,直到设置新值或会话结束。 MRCPv2 服务器可以提供一种机制来创建其输出日志的子集,以便系统管理员可以仅检查或提取日志文件部分,在此期间日志标记被设置为特定值。
建议客户端在日志记录标记信息中包含标识 MRCPv2 客户端用户代理的信息,以便可以确定哪个 MRCPv2 客户端请求在服务器上生成了给定的日志消息。 还建议 MRCPv2 客户端不要记录个人身份信息,例如信用卡号和国民身份证号。
logging-tag = "Logging-Tag" ":" 1*UTFCHAR CRLF
由于 MRCPv2 服务器上关联的 HTTP 客户端代表 MRCPv2 客户端获取文档进行处理,因此 MRCPv2 服务器的 HTTP 客户端中的 cookie 存储被视为 MRCPv2 客户端的 HTTP 客户端中的 cookie 存储的扩展。
这要求 MRCPv2 客户端和服务器能够根据需要同步它们的公共 cookie 存储。 为了使 MRCPv2 客户端能够将其存储的 cookie 推送到 MRCPv2 服务器并从 MRCPv2 服务器获取新的 cookie 存储回 MRCPv2 客户端,Set-Cookie 实体标头字段可以包含在 MRCPv2 请求中以更新 cookie 存储在 服务器并在最终的 MRCPv2 响应或事件中返回,以随后更新客户端自己的 cookie 存储。 服务器上存储的 cookie 在 MRCPv2 会话期间持续存在,并且必须在会话结束时销毁。 为确保支持 cookie,MRCPv2 客户端和服务器必须支持 Set-Cookie 实体标头字段。
请注意,是 MRCPv2 客户端决定将哪些 cookie(如果有)发送到服务器。 不要求共享所有 cookie。 相反,建议 MRCPv2 客户端仅传送 MRCPv2 服务器处理其请求所需的 cookie。
set-cookie = "Set-Cookie:" cookies CRLF
cookies = cookie *("," *LWS cookie)
cookie = attribute "=" value *(";" cookie-av)
cookie-av = "Comment" "=" value
/ "Domain" "=" value
/ "Max-Age" "=" value
/ "Path" "=" value
/ "Secure"
/ "Version" "=" 1*19DIGIT
/ "Age" "=" delta-seconds
set-cookie = "Set-Cookie:" SP set-cookie-string
set-cookie-string = cookie-pair *( ";" SP cookie-av )
cookie-pair = cookie-name "=" cookie-value
cookie-name = token
cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE )
cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E
token =
cookie-av = expires-av / max-age-av / domain-av /
path-av / secure-av / httponly-av /
extension-av / age-av
expires-av = "Expires=" sane-cookie-date
sane-cookie-date =
max-age-av = "Max-Age=" non-zero-digit *DIGIT
non-zero-digit = %x31-39
domain-av = "Domain=" domain-value
domain-value =
path-av = "Path=" path-value
path-value =
secure-av = "Secure"
httponly-av = "HttpOnly"
extension-av =
age-av = "Age=" delta-seconds
Set-Cookie 头字段在 RFC 6265 [RFC6265] 中指定。 “Age”属性在本规范中被引入以指示 cookie 的年龄并且是可选的。 MRCPv2 客户端或服务器必须根据 HTTP/1.1 规范 [RFC2616] 中的年龄计算规则计算 cookie 的年龄,并相应地附加“Age”属性。 提供此属性是因为自从客户端从 HTTP 服务器接收到 cookie 以来可能已经过去了一段时间。
它不是让客户端按实际年龄减少 Max-Age,而是逐字传递 Max-Age 并附加“Age”属性,从而保持接收到的 cookie,同时仍然考虑时间已经过去的事实。
MRCPv2 客户端或服务器必须为“Domain”和“Path”属性提供默认值,如 RFC 6265 中指定的那样,如果它们被 HTTP 源服务器省略。 请注意,在这种情况下,“Domain”属性值中没有前导点。 尽管可以修改通过 HTTP 协议接收的明确指定的“域”值以包含前导点,但 MRCPv2 客户端或服务器在通过 MRCPv2 协议接收时不得修改“域”值。
一个 MRCPv2 客户端或服务器可以将相同类型的多个 cookie 头字段组合成一个“字段名:字段值”对,如第 6.2 节所述。
Set-Cookie 头字段可以在随后导致服务器执行 HTTP 访问的任何请求中指定。 当服务器从 HTTP 源服务器接收到新的 cookie 信息时,假设 cookie 存储根据 RFC 6265 进行了修改,服务器必须根据需要在 MRCPv2 COMPLETE 响应或事件中返回新的 cookie 信息,以允许客户端更新 它自己的饼干店。
SET-PARAMS 请求可以指定 Set-Cookie 头字段来更新服务器上的 cookie 存储。 GET-PARAMS 请求可用于将“Set-Cookie”类型 cookie 的整个 cookie 存储返回给客户端。
这组头字段允许客户端设置或检索特定于供应商的参数。
vendor-specific = "Vendor-Specific-Parameters" ":"
[vendor-specific-av-pair
*(";" vendor-specific-av-pair)] CRLF
vendor-specific-av-pair = vendor-av-pair-name "="
value
vendor-av-pair-name = 1*UTFCHAR
这种形式的头字段可以在任何方法(请求)中发送,并用于在服务器端管理特定于实现的参数。
vendor-av-pair-name 遵循反向 Internet 域名约定(有关语法和注册信息,请参阅第 13.1.6 节)。 vendor 属性的值在“=”符号之后指定,并且可以被引用。 例如:
com.example.companyA.paramxyz=256
com.example.companyA.paramabc=High
com.example.companyB.paramxyz=Low
当在 GET-PARAMS 中用于从服务器获取这些参数的当前值时,此头字段值可能包含一个以分号分隔的特定于实现的属性名称列表。