跳到主要内容

3. 结构化数据类型

本节定义 Structured Fields 的抽象类型. 所提供的 ABNF 表示 HTTP 字段值中的 on-wire 格式.

概括如下:

  • HTTP 字段可被定义为三种顶层类型: Lists, Dictionaries 和 Items.

  • Lists 和 Dictionaries 是容器. 它们的成员可以是 Items 或 Inner Lists (其本身是 Items 的数组).

  • Items 和 Inner Lists 都可以使用 key/value pairs 进行 Parameterized.

3.1. Lists

Lists 是包含零个或多个成员的数组, 每个成员可以是 Item (Section 3.3) 或 Inner List (Section 3.1.1), 二者都可以被 Parameterized (Section 3.1.2).

HTTP 字段中 Lists 的 ABNF 为:

sf-list       = list-member *( OWS "," OWS list-member )
list-member = sf-item / inner-list

每个成员由逗号和可选空白分隔. 例如, 某个值被定义为 Token List 的字段可能如下所示:

Example-List: sugar, tea, rum

空 List 通过完全不序列化该字段来表示. 这意味着被定义为 Lists 的字段具有默认空值.

注意, 根据 [RFC7230] Section 3.2.2, Lists 的成员可以拆分到同一 header 或 trailer section 中的多行. 例如, 以下二者等价:

Example-List: sugar, tea, rum

Example-List: sugar, tea
Example-List: rum

但是, List 的单个成员不能安全地拆分到多行之间. 详见 Section 4.2.

Parsers MUST 支持至少包含 1024 个成员的 Lists. 字段规范可以按需约束各个 List 值的类型和基数.

3.1.1. Inner Lists

Inner List 是包含零个或多个 Items 的数组 (Section 3.3). 单个 Items 和 Inner List 本身都可以被 Parameterized (Section 3.1.2).

Inner Lists 的 ABNF 为:

inner-list    = "(" *SP [ sf-item *( 1*SP sf-item ) *SP ] ")"
parameters

Inner Lists 由括号包围表示, 其值由一个或多个空格分隔. 某个值被定义为 String Inner Lists 的 List 的字段可能如下所示:

Example-List: ("foo" "bar"), ("baz"), ("bat" "one"), ()

注意, 此示例中的最后一个成员是空 Inner List.

某个值被定义为在两个层级都带 Parameters 的 Inner Lists 的 List 的 header 字段可能如下所示:

Example-List: ("foo"; a=1;b=2);lvl=5, ("bar" "baz");lvl=1

Parsers MUST 支持至少包含 256 个成员的 Inner Lists. 字段规范可以按需约束各个 Inner List 成员的类型和基数.

3.1.2. Parameters

Parameters 是与 Item (Section 3.3) 或 Inner List (Section 3.1.1) 关联的有序 key-value pairs 映射. 在其出现的 Parameters 作用域内, keys 是唯一的, 且 values 是 bare items (即它们自身不能被 parameterized. 见 Section 3.3).

实现 MUST 同时提供按索引和按 key 访问 Parameters 的能力. 规范 MAY 使用任一方式访问它们.

Parameters 的 ABNF 为:

parameters    = *( ";" *SP parameter )
parameter = param-key [ "=" param-value ]
param-key = key
key = ( lcalpha / "*" )
*( lcalpha / DIGIT / "_" / "-" / "." / "*" )
lcalpha = %x61-7A ; a-z
param-value = bare-item

注意, parameters 按序列化顺序排列, 且 parameter keys 不能包含大写字母. parameter 通过分号与其 Item 或 Inner List 以及其他 parameters 分隔. 例如:

Example-List: abc;a=1;b=2; cde_456, (ghi;jk=4 l);q="9";r=w

值为 Boolean true 的 Parameters (见 Section 3.3.6) 在序列化时 MUST 省略该值. 例如, 此处 "a" parameter 为 true, 而 "b" parameter 为 false:

Example-Integer: 1; a; b=?0

注意, 此要求仅适用于序列化. parsers 仍被要求在 parameter 中出现 true 值时正确处理它.

Parsers MUST 在 Item 或 Inner List 上支持至少 256 个 parameters, 并支持至少 64 个字符的 parameter keys. 字段规范可以按需约束各个 parameters 的顺序以及其 values 的类型.

3.2. Dictionaries

Dictionaries 是有序 key-value pairs 映射, 其中 keys 是较短的文本字符串, values 是 Items (Section 3.3) 或 Items 的数组, 二者都可以被 Parameterized (Section 3.1.2). 它们可以包含零个或多个成员, 且 keys 在其出现的 Dictionary 作用域内是唯一的.

实现 MUST 同时提供按索引和按 key 访问 Dictionaries 的能力. 规范 MAY 使用任一方式访问成员.

Dictionaries 的 ABNF 为:

sf-dictionary  = dict-member *( OWS "," OWS dict-member )
dict-member = member-key ( parameters / ( "=" member-value ))
member-key = key
member-value = sf-item / inner-list

成员按序列化顺序排列, 并由带可选空白的逗号分隔. Member keys 不能包含大写字符. Keys 和 values 由 "=" 分隔 (不带空白). 例如:

Example-Dict: en="Applepie", da=:w4ZibGV0w6ZydGU=:

注意, 在此示例中, 最后的 "=" 是因为包含了 Byte Sequence. 见 Section 3.3.5.

值为 Boolean true 的成员 (见 Section 3.3.6) 在序列化时 MUST 省略该值. 例如, 此处 "b" 和 "c" 都为 true:

Example-Dict: a=?0, b, c; foo=bar

注意, 此要求仅适用于序列化. parsers 仍被要求在 Dictionary values 中出现 Boolean true 值时正确处理它.

具有某个值为 Token Inner List 的成员的 Dictionary:

Example-Dict: rating=1.5, feelings=(joy sadness)

混合包含 Items 和 Inner Lists, 且其中一些带 parameters 的 Dictionary:

Example-Dict: a=(1 2), b=3, c=4;aa=bb, d=(5 6);valid

与 Lists 一样, 空 Dictionary 通过省略整个字段表示. 这意味着被定义为 Dictionaries 的字段具有默认空值.

通常, 字段规范会通过按 key 指定各个成员允许的类型以及其出现是必需还是可选, 来定义 Dictionaries 的语义. 除非字段规范明确禁止, 接收者 MUST 忽略 key 未定义或未知的成员.

注意, Dictionaries 的成员可以拆分到同一 header 或 trailer section 中的多行. 例如, 以下二者等价:

Example-Dict: foo=1, bar=2

Example-Dict: foo=1
Example-Dict: bar=2

但是, Dictionary 的单个成员不能安全地拆分到多行之间. 详见 Section 4.2.

Parsers MUST 支持至少包含 1024 个 key/value pairs 的 Dictionaries, 并支持至少 64 个字符的 keys. 字段规范可以按需约束各个 Dictionary 成员的顺序以及其 values 的类型.

3.3. Items

Item 可以是 Integer (Section 3.3.1), Decimal (Section 3.3.2), String (Section 3.3.3), Token (Section 3.3.4), Byte Sequence (Section 3.3.5) 或 Boolean (Section 3.3.6). 它可以具有关联的 parameters (Section 3.1.2).

Items 的 ABNF 为:

sf-item   = bare-item parameters
bare-item = sf-integer / sf-decimal / sf-string / sf-token
/ sf-binary / sf-boolean

例如, 被定义为 Integer Item 的 header 字段可能如下所示:

Example-Integer: 5

或带 parameters:

Example-Integer: 5; foo=bar

3.3.1. Integers

Integers 的范围为 -999,999,999,999,999 到 999,999,999,999,999, 含端点 (即最多十五位数字, 可带符号), 以兼容 IEEE 754 [IEEE754].

Integers 的 ABNF 为:

sf-integer = ["-"] 1*15DIGIT

例如:

Example-Integer: 42

超过 15 位的 Integers 可以通过多种方式支持. 例如, 使用 String (Section 3.3.3), Byte Sequence (Section 3.3.5), 或作为缩放因子的 Integer parameter.

虽然可以序列化带前导零的 Integers (例如 "0002", "-01") 和带符号零 ("-0"), 但实现可能不会保留这些区别.

注意, 本节正文中 Integers 内的逗号仅用于提高可读性. 它们在线上格式中无效.

3.3.2. Decimals

Decimals 是包含整数部分和小数部分的数字. 整数部分最多 12 位数字, 小数部分最多 3 位数字.

Decimals 的 ABNF 为:

sf-decimal  = ["-"] 1*12DIGIT "." 1*3DIGIT

例如, 值被定义为 Decimal 的 header 可能如下所示:

Example-Decimal: 4.5

虽然可以序列化带前导零的 Decimals (例如 "0002.5", "-01.334"), 带尾随零的 Decimals (例如 "5.230", "-0.40"), 以及带符号零 (例如 "-0.0"), 但实现可能不会保留这些区别.

注意, 序列化算法 (Section 4.1.5) 会将小数部分精度超过三位的输入四舍五入. 如果需要替代舍入策略, header 定义应指定在序列化前执行该策略.

3.3.3. Strings

Strings 是零个或多个可打印 ASCII [RFC0020] 字符 (即 %x20 到 %x7E 范围). 注意, 这排除了制表符, 换行符, 回车符等.

Strings 的 ABNF 为:

sf-string = DQUOTE *chr DQUOTE
chr = unescaped / escaped
unescaped = %x20-21 / %x23-5B / %x5D-7E
escaped = "\" ( DQUOTE / "\" )

Strings 以双引号分隔, 使用反斜杠 ("") 转义双引号和反斜杠. 例如:

Example-String: "hello world"

注意, Strings 只使用 DQUOTE 作为分隔符. 单引号不分隔 Strings. 此外, 只有 DQUOTE 和 "" 可以被转义. 在 "" 后出现其他字符 MUST 导致解析失败.

Unicode 不直接在 Strings 中支持, 因为它会导致许多互操作性问题, 并且除少数例外外, 字段值并不需要它.

当字段值需要传递非 ASCII 内容时, 可以指定 Byte Sequence (Section 3.3.5), 并同时指定字符编码 (最好是 UTF-8 [STD63]).

Parsers MUST 支持 (经过任何解码后) 至少 1024 个字符的 Strings.

3.3.4. Tokens

Tokens 是较短的文本词. 它们的抽象模型与其在 HTTP 字段值序列化中的表达相同.

Tokens 的 ABNF 为:

sf-token = ( ALPHA / "*" ) *( tchar / ":" / "/" )

例如:

Example-Token: foo123/456

Parsers MUST 支持至少 512 个字符的 Tokens.

注意, Token 允许与 [RFC7230] 中定义的 "token" ABNF 规则相同的字符, 但有两个例外: 第一个字符必须是 ALPHA 或 "*", 且后续字符中还允许 ":" 和 "/".

3.3.5. Byte Sequences

Byte Sequences 可在 Structured Fields 中传递.

Byte Sequence 的 ABNF 为:

sf-binary = ":" *(base64) ":"
base64 = ALPHA / DIGIT / "+" / "/" / "="

Byte Sequence 以冒号分隔, 并使用 base64 ([RFC4648] Section 4) 编码. 例如:

Example-ByteSequence: :cHJldGVuZCB0aGlzIGlzIGJpbmFyeSBjb250ZW50Lg==:

Parsers MUST 支持解码后至少 16384 个 octets 的 Byte Sequences.

3.3.6. Booleans

Boolean values 可在 Structured Fields 中传递.

Boolean 的 ABNF 为:

sf-boolean = "?" boolean
boolean = "0" / "1"

Boolean 以开头的 "?" 字符表示, 后跟 "1" 表示 true 值, 或 "0" 表示 false 值. 例如:

Example-Boolean: ?1

注意, 在 Dictionary (Section 3.2) 和 Parameter (Section 3.1.2) values 中, Boolean true 通过省略该值表示.