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 通过省略该值表示.