Skip to main content

3. Structured Data Types (结构化数据类型)

本节定义了结构化字段的抽象类型。提供的ABNF表示HTTP字段值中的线路格式。

概述

  • 有三种顶级类型可用于定义HTTP字段: Lists (列表)Dictionaries (字典)Items (项目)

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

  • Items和Inner Lists都可以使用键值对进行参数化 (Parameterized)


3.1 Lists (列表)

Lists是包含零个或多个成员的数组,每个成员可以是Item(第3.3节)或Inner List(第3.1.1节),两者都可以被参数化(第3.1.2节)。

ABNF语法

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

格式说明

每个成员由逗号和可选的空白分隔。

示例

Example-List: sugar, tea, rum

定义为Token列表的字段

空列表

空List通过根本不序列化字段来表示。这意味着定义为Lists的字段具有默认的空值。

多行分割

Lists的成员可以跨同一头部或尾部区段的多行分割(根据[RFC7230]第3.2.2节);例如,以下是等效的:

Example-List: sugar, tea, rum

等效于:

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

注意: List的单个成员不能在行之间安全分割;详见第4.2节。

实现要求

解析器必须 (MUST) 支持包含至少1024个成员的Lists。字段规范可以根据需要约束单个List值的类型和基数。


3.1.1 Inner Lists (内部列表)

Inner List是包含零个或多个Items(第3.3节)的数组。单个Items和Inner List本身都可以被参数化(第3.1.2节)。

ABNF语法

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

格式说明

Inner Lists由圆括号包围,其值由一个或多个空格分隔。

示例 1: 简单Inner Lists

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

定义为Inner Lists of Strings的List。注意最后一个成员是空的Inner List。

示例 2: 带参数的Inner Lists

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

定义为Inner Lists with Parameters(在两个级别上都有参数)的List。

实现要求

解析器必须 (MUST) 支持包含至少256个成员的Inner Lists。字段规范可以根据需要约束单个Inner List成员的类型和基数。


3.1.2 Parameters (参数)

Parameters是与Item(第3.3节)或Inner List(第3.1.1节)关联的键值对的有序映射。键在它们出现的Parameters范围内是唯一的,值是裸项目 (bare items)(即,它们本身不能被参数化;参见第3.3节)。

实现必须 (MUST) 提供通过索引和键访问Parameters的方式。规范可以 (MAY) 使用任一访问方式。

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

格式说明

  • 参数按序列化顺序排列
  • 参数键不能包含大写字母
  • 参数由分号与其Item或Inner List及其他参数分隔

示例

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

Boolean参数的特殊规则

值为Boolean(参见第3.3.6节)true的参数在序列化时必须 (MUST) 省略该值。

示例:

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

这里 a 参数是true,而 b 参数是false。

注意: 此要求仅针对序列化;解析器仍然需要正确处理参数中出现的true值。

实现要求

解析器必须 (MUST) 支持:

  • Item或Inner List上至少256个参数
  • 至少64个字符的参数键

字段规范可以根据需要约束单个参数的顺序以及它们的值类型。


3.2 Dictionaries (字典)

Dictionaries是键值对的有序映射,其中键是短文本字符串,值是Items(第3.3节)或Items数组,两者都可以被参数化(第3.1.2节)。可以有零个或多个成员,它们的键在它们出现的Dictionary范围内是唯一的。

实现必须 (MUST) 提供通过索引和键访问Dictionaries的方式。规范可以 (MAY) 使用任一访问成员的方式。

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

格式说明

  • 成员按序列化顺序排列,由逗号和可选空白分隔
  • 成员键不能包含大写字符
  • 键和值由 "=" 分隔(无空白)

示例 1: 基本Dictionary

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

注意: 在此示例中,最后的 "=" 是由于包含了Byte Sequence;参见第3.3.5节。

示例 2: Boolean值的简写

值为Boolean(参见第3.3.6节)true的成员在序列化时必须 (MUST) 省略该值。

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

这里 bc 都是true。

注意: 此要求仅针对序列化;解析器仍然需要正确处理Dictionary值中出现的true Boolean值。

示例 3: 包含Inner List

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

包含值为Token的Inner List的Dictionary。

示例 4: 混合类型

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

包含Items和Inner Lists的混合,有些带参数。

空Dictionary

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

字段定义

通常,字段规范将通过指定单个成员按其键的允许类型,以及它们的存在是必需还是可选,来定义Dictionaries的语义。

接收者必须 (MUST) 忽略键未定义或未知的成员,除非字段规范明确禁止它们。

多行分割

Dictionaries的成员可以跨同一头部或尾部区段的多行分割;例如,以下是等效的:

Example-Dict: foo=1, bar=2

等效于:

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

注意: Dictionary的单个成员不能在行之间安全分割;详见第4.2节。

实现要求

解析器必须 (MUST) 支持:

  • 包含至少1024个键值对的Dictionaries
  • 至少64个字符的键

字段规范可以根据需要约束单个Dictionary成员的顺序以及它们的值类型。


3.3 Items (项目)

Item可以是Integer(第3.3.1节)、Decimal(第3.3.2节)、String(第3.3.3节)、Token(第3.3.4节)、Byte Sequence(第3.3.5节)或Boolean(第3.3.6节)。它可以有关联的参数(第3.1.2节)。

ABNF语法

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

示例

Example-Integer: 5

定义为Integer的Item的头部字段。

带参数:

Example-Integer: 5; foo=bar

3.3.1 Integers (整数)

Integers的范围为**-999,999,999,999,999999,999,999,999,999**(包括端点)(即,最多15位数字,带符号),以实现IEEE 754兼容性[IEEE754]。

ABNF语法

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

示例

Example-Integer: 42

更大的整数

大于15位数字的Integers可以通过多种方式支持;例如:

  • 使用String(第3.3.3节)
  • 使用Byte Sequence(第3.3.5节)
  • 在Integer上使用充当缩放因子的参数

序列化注意事项

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

注意: 本节中Integers中的逗号仅用于提高可读性;它们在线路格式中无效。


3.3.2 Decimals (小数)

Decimals是具有整数部分和小数部分的数字。整数部分最多有12位数字;小数部分最多有3位数字

ABNF语法

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

示例

Example-Decimal: 4.5

序列化注意事项

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

注意: 序列化算法(第4.1.5节)会舍入小数部分精度超过三位的输入。如果需要替代的舍入策略,应该由头部定义指定在序列化之前进行。


3.3.3 Strings (字符串)

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

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中不直接支持Unicode,因为它会导致许多互操作性问题,并且--除少数例外--字段值不需要它。

当字段值需要传达非ASCII内容时,可以指定Byte Sequence(第3.3.5节),以及字符编码(最好是UTF-8 [STD63])。

实现要求

解析器必须 (MUST) 支持(任何解码后)至少1024个字符的Strings。


3.3.4 Tokens (令牌)

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

ABNF语法

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

示例

Example-Token: foo123/456

实现要求

解析器必须 (MUST) 支持至少512个字符的Tokens。

注意事项

Token允许与[RFC7230]中定义的"token" ABNF规则相同的字符,但有以下例外:

  • 第一个字符必须 (required) 是ALPHA或 "*"
  • 后续字符中还允许 ":""/"

3.3.5 Byte Sequences (字节序列)

Byte Sequences可以在结构化字段中传递。

ABNF语法

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

格式说明

Byte Sequence用冒号分隔,并使用base64([RFC4648]第4节)编码。

示例

Example-ByteSequence: :cHJldGVuZCB0aGlzIGlzIGJpbmFyeSBjb250ZW50Lg==:

实现要求

解析器必须 (MUST) 支持解码后至少16384个八位字节的Byte Sequences。


3.3.6 Booleans (布尔值)

Boolean值可以在结构化字段中传递。

ABNF语法

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

格式说明

Boolean由前导 "?" 字符指示,后跟 "1" 表示true值或 "0" 表示false。

示例

Example-Boolean: ?1

特殊规则

注意,在Dictionary(第3.2节)和Parameter(第3.1.2节)值中,Boolean true通过省略值来表示


数据类型总结

类型格式示例范围/限制
Integer["-"] 1*15DIGIT42, -100±999,999,999,999,999
Decimal["-"] 1*12DIGIT "." 1*3DIGIT4.5, -0.123整数部分12位,小数3位
String"...""hello"可打印ASCII,最少1024字符
Tokenwordapplication/json最少512字符
Byte Sequence:base64::SGVsbG8=:最少16384字节
Boolean?0?1?1true/false

关键要点

  1. 三种顶级类型: List, Dictionary, Item
  2. 六种基本类型: Integer, Decimal, String, Token, Byte Sequence, Boolean
  3. 参数化: Items和Inner Lists可以有参数
  4. 严格的格式: 每种类型都有明确的ABNF定义
  5. 实现最小值: 必须支持的最小大小/数量
  6. Boolean简写: 在Dictionary和Parameters中,true可以省略值