跳到主要内容

4. 在 HTTP 中使用结构化字段

本节定义如何在文本 HTTP 字段值以及与其兼容的其他编码中序列化和解析 Structured Fields (例如 HTTP/2 [RFC7540] 中 HPACK [RFC7541] 压缩之前的表示).

4.1. 序列化 Structured Fields

给定本规范中定义的结构, 返回适合用作 HTTP 字段值的 ASCII 字符串.

  1. 如果该结构是 Dictionary 或 List 且其值为空 (即没有成员), 则完全不序列化该字段 (即省略 field-name 和 field-value).

  2. 如果该结构是 List, 令 output_string 为使用该结构运行 Serializing a List (Section 4.1.1) 的结果.

  3. 否则, 如果该结构是 Dictionary, 令 output_string 为使用该结构运行 Serializing a Dictionary (Section 4.1.2) 的结果.

  4. 否则, 如果该结构是 Item, 令 output_string 为使用该结构运行 Serializing an Item (Section 4.1.3) 的结果.

  5. 否则, 序列化失败.

  6. 返回使用 ASCII 编码 [RFC0020] 将 output_string 转换成的字节数组.

4.1.1. 序列化 List

给定一个由 (member_value, parameters) tuples 组成的数组 input_list, 返回适合用作 HTTP 字段值的 ASCII 字符串.

  1. output 为空字符串.

  2. input_list 中的每个 (member_value, parameters):

    1. 如果 member_value 是数组, 将使用 (member_value, parameters) 运行 Serializing an Inner List (Section 4.1.1.1) 的结果追加到 output.

    2. 否则, 将使用 (member_value, parameters) 运行 Serializing an Item (Section 4.1.3) 的结果追加到 output.

    3. 如果 input_list 中还有更多 member_values:

      1. 将 "," 追加到 output.

      2. 将单个 SP 追加到 output.

  3. 返回 output.

4.1.1.1. 序列化 Inner List

给定一个由 (member_value, parameters) tuples 组成的数组 inner_list, 以及作为 list_parameters 的 parameters, 返回适合用作 HTTP 字段值的 ASCII 字符串.

  1. output 为字符串 "(".

  2. inner_list 中的每个 (member_value, parameters):

    1. 将使用 (member_value, parameters) 运行 Serializing an Item (Section 4.1.3) 的结果追加到 output.

    2. 如果 inner_list 中还有更多 values, 将单个 SP 追加到 output.

  3. 将 ")" 追加到 output.

  4. 将使用 list_parameters 运行 Serializing Parameters (Section 4.1.1.2) 的结果追加到 output.

  5. 返回 output.

4.1.1.2. 序列化 Parameters

给定一个有序 Dictionary input_parameters (每个成员具有 param_keyparam_value), 返回适合用作 HTTP 字段值的 ASCII 字符串.

  1. output 为空字符串.

  2. input_parameters 中每个值为 param_valueparam_key:

    1. 将 ";" 追加到 output.

    2. 将使用 param_key 运行 Serializing a Key (Section 4.1.1.3) 的结果追加到 output.

    3. 如果 param_value 不是 Boolean true:

      1. 将 "=" 追加到 output.

      2. 将使用 param_value 运行 Serializing a bare Item (Section 4.1.3.1) 的结果追加到 output.

  3. 返回 output.

4.1.1.3. 序列化 Key

给定一个 key 作为 input_key, 返回适合用作 HTTP 字段值的 ASCII 字符串.

  1. input_key 转换为 ASCII 字符序列. 如果转换失败, 序列化失败.

  2. 如果 input_key 包含不属于 lcalpha, DIGIT, "_", "-", "." 或 "*" 的字符, 序列化失败.

  3. 如果 input_key 的第一个字符不是 lcalpha 或 "*", 序列化失败.

  4. output 为空字符串.

  5. input_key 追加到 output.

  6. 返回 output.

4.1.2. 序列化 Dictionary

给定一个有序 Dictionary input_dictionary (每个成员具有 member_key 和 tuple 值 (member_value, parameters)), 返回适合用作 HTTP 字段值的 ASCII 字符串.

  1. output 为空字符串.

  2. input_dictionary 中每个值为 (member_value, parameters)member_key:

    1. 将使用该成员的 member_key 运行 Serializing a Key (Section 4.1.1.3) 的结果追加到 output.

    2. 如果 member_value 是 Boolean true:

      1. 将使用 parameters 运行 Serializing Parameters (Section 4.1.1.2) 的结果追加到 output.
    3. 否则:

      1. 将 "=" 追加到 output.

      2. 如果 member_value 是数组, 将使用 (member_value, parameters) 运行 Serializing an Inner List (Section 4.1.1.1) 的结果追加到 output.

      3. 否则, 将使用 (member_value, parameters) 运行 Serializing an Item (Section 4.1.3) 的结果追加到 output.

    4. 如果 input_dictionary 中还有更多成员:

      1. 将 "," 追加到 output.

      2. 将单个 SP 追加到 output.

  3. 返回 output.

4.1.3. 序列化 Item

给定一个作为 bare_item 的 Item 和作为 item_parameters 的 Parameters, 返回适合用作 HTTP 字段值的 ASCII 字符串.

  1. output 为空字符串.

  2. 将使用 bare_item 运行 Serializing a Bare Item (Section 4.1.3.1) 的结果追加到 output.

  3. 将使用 item_parameters 运行 Serializing Parameters (Section 4.1.1.2) 的结果追加到 output.

  4. 返回 output.

4.1.3.1. 序列化 Bare Item

给定一个 Item 作为 input_item, 返回适合用作 HTTP 字段值的 ASCII 字符串.

  1. 如果 input_item 是 Integer, 返回使用 input_item 运行 Serializing an Integer (Section 4.1.4) 的结果.

  2. 如果 input_item 是 Decimal, 返回使用 input_item 运行 Serializing a Decimal (Section 4.1.5) 的结果.

  3. 如果 input_item 是 String, 返回使用 input_item 运行 Serializing a String (Section 4.1.6) 的结果.

  4. 如果 input_item 是 Token, 返回使用 input_item 运行 Serializing a Token (Section 4.1.7) 的结果.

  5. 如果 input_item 是 Byte Sequence, 返回使用 input_item 运行 Serializing a Byte Sequence (Section 4.1.8) 的结果.

  6. 如果 input_item 是 Boolean, 返回使用 input_item 运行 Serializing a Boolean (Section 4.1.9) 的结果.

  7. 否则, 序列化失败.

4.1.4. 序列化 Integer

给定一个 Integer 作为 input_integer, 返回适合用作 HTTP 字段值的 ASCII 字符串.

  1. 如果 input_integer 不是范围 -999,999,999,999,999 到 999,999,999,999,999 (含端点) 内的整数, 序列化失败.

  2. output 为空字符串.

  3. 如果 input_integer 小于 (但不等于) 0, 将 "-" 追加到 output.

  4. input_integer 的数值以十进制表示 (仅使用十进制数字) 追加到 output.

  5. 返回 output.

4.1.5. 序列化 Decimal

给定一个 decimal number 作为 input_decimal, 返回适合用作 HTTP 字段值的 ASCII 字符串.

  1. 如果 input_decimal 不是 decimal number, 序列化失败.

  2. 如果 input_decimal 在小数点右侧有超过三位有效数字, 将其舍入到三位小数, 最后一位舍入到最接近的值, 若距离相等则舍入到偶数值.

  3. 如果舍入后 input_decimal 在小数点左侧有超过 12 位有效数字, 序列化失败.

  4. output 为空字符串.

  5. 如果 input_decimal 小于 (但不等于) 0, 将 "-" 追加到 output.

  6. input_decimal 的整数部分以十进制表示 (仅使用十进制数字) 追加到 output. 如果该整数部分为零, 追加 "0".

  7. 将 "." 追加到 output.

  8. 如果 input_decimal 的小数部分为零, 将 "0" 追加到 output.

  9. 否则, 将 input_decimal 的小数部分的有效数字以十进制表示 (仅使用十进制数字) 追加到 output.

  10. 返回 output.

4.1.6. 序列化 String

给定一个 String 作为 input_string, 返回适合用作 HTTP 字段值的 ASCII 字符串.

  1. input_string 转换为 ASCII 字符序列. 如果转换失败, 序列化失败.

  2. 如果 input_string 包含范围 %x00-1f 或 %x7f-ff 中的字符 (即不属于 VCHAR 或 SP), 序列化失败.

  3. output 为字符串 DQUOTE.

  4. input_string 中的每个字符 char:

    1. 如果 char 是 "" 或 DQUOTE:

      1. 将 "" 追加到 output.
    2. char 追加到 output.

  5. 将 DQUOTE 追加到 output.

  6. 返回 output.

4.1.7. 序列化 Token

给定一个 Token 作为 input_token, 返回适合用作 HTTP 字段值的 ASCII 字符串.

  1. input_token 转换为 ASCII 字符序列. 如果转换失败, 序列化失败.

  2. 如果 input_token 的第一个字符不是 ALPHA 或 "*", 或者其余部分包含不属于 tchar, ":" 或 "/" 的字符, 序列化失败.

  3. output 为空字符串.

  4. input_token 追加到 output.

  5. 返回 output.

4.1.8. 序列化 Byte Sequence

给定一个 Byte Sequence 作为 input_bytes, 返回适合用作 HTTP 字段值的 ASCII 字符串.

  1. 如果 input_bytes 不是字节序列, 序列化失败.

  2. output 为空字符串.

  3. 将 ":" 追加到 output.

  4. 将按 [RFC4648] Section 4 对 input_bytes 进行 base64 编码的结果追加到 output, 同时考虑下面的要求.

  5. 将 ":" 追加到 output.

  6. 返回 output.

编码数据要求按照 [RFC4648] Section 3.2 使用 "=" 填充.

同样, 除非由于实现约束无法做到, 编码数据 SHOULD 按 [RFC4648] Section 3.5 将 pad bits 置为零.

4.1.9. 序列化 Boolean

给定一个 Boolean 作为 input_boolean, 返回适合用作 HTTP 字段值的 ASCII 字符串.

  1. 如果 input_boolean 不是 boolean, 序列化失败.

  2. output 为空字符串.

  3. 将 "?" 追加到 output.

  4. 如果 input_boolean 为 true, 将 "1" 追加到 output.

  5. 如果 input_boolean 为 false, 将 "0" 追加到 output.

  6. 返回 output.

4.2. 解析 Structured Fields

当接收实现解析已知为 Structured Fields 的 HTTP 字段时, 必须小心处理, 因为有许多 edge cases 可能导致互操作性问题甚至安全问题. 本节指定执行该操作的算法.

给定表示所选字段 field-value 的字节数组 input_bytes (如果该字段不存在则为空) 和 field_type ("dictionary", "list" 或 "item" 之一), 返回已解析的 header value.

  1. input_bytes 转换为 ASCII 字符串 input_string. 如果转换失败, 解析失败.

  2. 丢弃 input_string 中所有前导 SP 字符.

  3. 如果 field_type 是 "list", 令 output 为使用 input_string 运行 Parsing a List (Section 4.2.1) 的结果.

  4. 如果 field_type 是 "dictionary", 令 output 为使用 input_string 运行 Parsing a Dictionary (Section 4.2.2) 的结果.

  5. 如果 field_type 是 "item", 令 output 为使用 input_string 运行 Parsing an Item (Section 4.2.3) 的结果.

  6. 丢弃 input_string 中所有前导 SP 字符.

  7. 如果 input_string 非空, 解析失败.

  8. 否则, 返回 output.

生成 input_bytes 时, parsers MUST 按 [RFC7230] Section 3.2.2 将同一 section (header 或 trailer) 中字段名大小写不敏感匹配的所有字段行合并为一个逗号分隔的 field-value. 这确保整个字段值得到正确处理.

对于 Lists 和 Dictionaries, 只要顶层数据结构中的单个成员未跨多个 header instances 拆分, 这就会正确串接该字段的所有行. 这两种类型的解析算法允许制表符, 因为一些实现可能使用制表符来合并字段行.

拆分到多个字段行的 Strings 将得到不可预测的结果, 因为一个或多个逗号 (以及可选空白) 将成为 parser 输出字符串的一部分. 由于串接可能由上游 intermediary 完成, 即使 serializer 和 parser 都由同一方控制, 结果也不受它们控制.

Tokens, Integers, Decimals 和 Byte Sequences 不能跨多个字段行拆分, 因为插入的逗号会导致解析失败.

当处理分布在多个字段行上的字段值时, 如果其中某一行不能按该字段解析, parsers MAY 失败. 例如, 对于被定义为 sf-string 的 Example-String 字段, parser 允许在处理以下字段 section 时失败:

Example-String: "foo
Example-String: bar"

如果解析失败, 包括调用其他算法时失败, 整个字段值 MUST 被忽略 (即视为该字段未出现在该 section 中). 这是有意严格的要求, 旨在提升互操作性和安全性, 引用本文档的规范不允许放宽此要求.

注意, 此要求不适用于未解析该字段的实现. 例如, intermediary 在转发消息之前并不要求剥除失败的字段.

4.2.1. 解析 List

给定一个 ASCII 字符串作为 input_string, 返回由 (item_or_inner_list, parameters) tuples 组成的数组. input_string 会被修改以移除已解析的值.

  1. members 为空数组.

  2. input_string 非空时:

    1. 将使用 input_string 运行 Parsing an Item or Inner List (Section 4.2.1.1) 的结果追加到 members.

    2. 丢弃 input_string 中所有前导 OWS 字符.

    3. 如果 input_string 为空, 返回 members.

    4. 消费 input_string 的第一个字符. 如果它不是 ",", 解析失败.

    5. 丢弃 input_string 中所有前导 OWS 字符.

    6. 如果 input_string 为空, 则存在尾随逗号. 解析失败.

  3. 未找到结构化数据. 返回 members (此时为空).

4.2.1.1. 解析 Item 或 Inner List

给定一个 ASCII 字符串作为 input_string, 返回 tuple (item_or_inner_list, parameters), 其中 item_or_inner_list 可以是单个 bare item, 也可以是由 (bare_item, parameters) tuples 组成的数组. input_string 会被修改以移除已解析的值.

  1. 如果 input_string 的第一个字符是 "(", 返回使用 input_string 运行 Parsing an Inner List (Section 4.2.1.2) 的结果.

  2. 返回使用 input_string 运行 Parsing an Item (Section 4.2.3) 的结果.

4.2.1.2. 解析 Inner List

给定一个 ASCII 字符串作为 input_string, 返回 tuple (inner_list, parameters), 其中 inner_list 是由 (bare_item, parameters) tuples 组成的数组. input_string 会被修改以移除已解析的值.

  1. 消费 input_string 的第一个字符. 如果它不是 "(", 解析失败.

  2. inner_list 为空数组.

  3. input_string 非空时:

    1. 丢弃 input_string 中所有前导 SP 字符.

    2. 如果 input_string 的第一个字符是 ")":

      1. 消费 input_string 的第一个字符.

      2. parameters 为使用 input_string 运行 Parsing Parameters (Section 4.2.3.2) 的结果.

      3. 返回 tuple (inner_list, parameters).

    3. item 为使用 input_string 运行 Parsing an Item (Section 4.2.3) 的结果.

    4. item 追加到 inner_list.

    5. 如果 input_string 的第一个字符不是 SP 或 ")", 解析失败.

  4. 未找到 Inner List 的结尾. 解析失败.

4.2.2. 解析 Dictionary

给定一个 ASCII 字符串作为 input_string, 返回一个有序映射, 其 values 是 (item_or_inner_list, parameters) tuples. input_string 会被修改以移除已解析的值.

  1. dictionary 为空的有序映射.

  2. input_string 非空时:

    1. this_key 为使用 input_string 运行 Parsing a Key (Section 4.2.3.3) 的结果.

    2. 如果 input_string 的第一个字符是 "=":

      1. 消费 input_string 的第一个字符.

      2. member 为使用 input_string 运行 Parsing an Item or Inner List (Section 4.2.1.1) 的结果.

    3. 否则:

      1. value 为 Boolean true.

      2. parameters 为使用 input_string 运行 Parsing Parameters (Section 4.2.3.2) 的结果.

      3. member 为 tuple (value, parameters).

    4. 如果 dictionary 已经包含 key this_key (逐字符比较), 用 member 覆盖其值.

    5. 否则, 将 key this_key 和 value member 追加到 dictionary.

    6. 丢弃 input_string 中所有前导 OWS 字符.

    7. 如果 input_string 为空, 返回 dictionary.

    8. 消费 input_string 的第一个字符. 如果它不是 ",", 解析失败.

    9. 丢弃 input_string 中所有前导 OWS 字符.

    10. 如果 input_string 为空, 则存在尾随逗号. 解析失败.

  3. 未找到结构化数据. 返回 dictionary (此时为空).

注意, 当遇到重复的 Dictionary keys 时, 除最后一个实例外都被忽略.

4.2.3. 解析 Item

给定一个 ASCII 字符串作为 input_string, 返回 (bare_item, parameters) tuple. input_string 会被修改以移除已解析的值.

  1. bare_item 为使用 input_string 运行 Parsing a Bare Item (Section 4.2.3.1) 的结果.

  2. parameters 为使用 input_string 运行 Parsing Parameters (Section 4.2.3.2) 的结果.

  3. 返回 tuple (bare_item, parameters).

4.2.3.1. 解析 Bare Item

给定一个 ASCII 字符串作为 input_string, 返回 bare Item. input_string 会被修改以移除已解析的值.

  1. 如果 input_string 的第一个字符是 "-" 或 DIGIT, 返回使用 input_string 运行 Parsing an Integer or Decimal (Section 4.2.4) 的结果.

  2. 如果 input_string 的第一个字符是 DQUOTE, 返回使用 input_string 运行 Parsing a String (Section 4.2.5) 的结果.

  3. 如果 input_string 的第一个字符是 ALPHA 或 "*", 返回使用 input_string 运行 Parsing a Token (Section 4.2.6) 的结果.

  4. 如果 input_string 的第一个字符是 ":", 返回使用 input_string 运行 Parsing a Byte Sequence (Section 4.2.7) 的结果.

  5. 如果 input_string 的第一个字符是 "?", 返回使用 input_string 运行 Parsing a Boolean (Section 4.2.8) 的结果.

  6. 否则, item type 无法识别. 解析失败.

4.2.3.2. 解析 Parameters

给定一个 ASCII 字符串作为 input_string, 返回一个有序映射, 其 values 是 bare Items. input_string 会被修改以移除已解析的值.

  1. parameters 为空的有序映射.

  2. input_string 非空时:

    1. 如果 input_string 的第一个字符不是 ";", 退出循环.

    2. input_string 开头消费 ";" 字符.

    3. 丢弃 input_string 中所有前导 SP 字符.

    4. param_key 为使用 input_string 运行 Parsing a Key (Section 4.2.3.3) 的结果.

    5. param_value 为 Boolean true.

    6. 如果 input_string 的第一个字符是 "=":

      1. 消费 input_string 开头的 "=" 字符.

      2. param_value 为使用 input_string 运行 Parsing a Bare Item (Section 4.2.3.1) 的结果.

    7. 如果 parameters 已经包含 key param_key (逐字符比较), 用 param_value 覆盖其值.

    8. 否则, 将 key param_key 和 value param_value 追加到 parameters.

  3. 返回 parameters.

注意, 当遇到重复的 parameter keys 时, 除最后一个实例外都被忽略.

4.2.3.3. 解析 Key

给定一个 ASCII 字符串作为 input_string, 返回 key. input_string 会被修改以移除已解析的值.

  1. 如果 input_string 的第一个字符不是 lcalpha 或 "*", 解析失败.

  2. output_string 为空字符串.

  3. input_string 非空时:

    1. 如果 input_string 的第一个字符不是 lcalpha, DIGIT, "_", "-", "." 或 "*" 之一, 返回 output_string.

    2. char 为消费 input_string 第一个字符的结果.

    3. char 追加到 output_string.

  4. 返回 output_string.

4.2.4. 解析 Integer 或 Decimal

给定一个 ASCII 字符串作为 input_string, 返回 Integer 或 Decimal. input_string 会被修改以移除已解析的值.

NOTE: 此算法同时解析 Integers (Section 3.3.1) 和 Decimals (Section 3.3.2), 并返回相应结构.

  1. type 为 "integer".

  2. sign 为 1.

  3. input_number 为空字符串.

  4. 如果 input_string 的第一个字符是 "-", 消费它并将 sign 设为 -1.

  5. 如果 input_string 为空, 则存在空 integer. 解析失败.

  6. 如果 input_string 的第一个字符不是 DIGIT, 解析失败.

  7. input_string 非空时:

    1. char 为消费 input_string 第一个字符的结果.

    2. 如果 char 是 DIGIT, 将它追加到 input_number.

    3. 否则, 如果 type 是 "integer" 且 char 是 ".":

      1. 如果 input_number 包含超过 12 个字符, 解析失败.

      2. 否则, 将 char 追加到 input_number 并将 type 设为 "decimal".

    4. 否则, 将 char 放回 input_string 开头, 并退出循环.

    5. 如果 type 是 "integer" 且 input_number 包含超过 15 个字符, 解析失败.

    6. 如果 type 是 "decimal" 且 input_number 包含超过 16 个字符, 解析失败.

  8. 如果 type 是 "integer":

    1. input_number 解析为整数, 并令 output_number 为该结果与 sign 的乘积.
  9. 否则:

    1. 如果 input_number 的最后一个字符是 ".", 解析失败.

    2. 如果 input_number 中 "." 后面的字符数大于三, 解析失败.

    3. input_number 解析为 decimal number, 并令 output_number 为该结果与 sign 的乘积.

  10. 返回 output_number.

4.2.5. 解析 String

给定一个 ASCII 字符串作为 input_string, 返回未加引号的 String. input_string 会被修改以移除已解析的值.

  1. output_string 为空字符串.

  2. 如果 input_string 的第一个字符不是 DQUOTE, 解析失败.

  3. 丢弃 input_string 的第一个字符.

  4. input_string 非空时:

    1. char 为消费 input_string 第一个字符的结果.

    2. 如果 char 是反斜杠 ("\"):

      1. 如果 input_string 现在为空, 解析失败.

      2. next_char 为消费 input_string 第一个字符的结果.

      3. 如果 next_char 不是 DQUOTE 或 "\", 解析失败.

      4. next_char 追加到 output_string.

    3. 否则, 如果 char 是 DQUOTE, 返回 output_string.

    4. 否则, 如果 char 在范围 %x00-1f 或 %x7f-ff 内 (即不属于 VCHAR 或 SP), 解析失败.

    5. 否则, 将 char 追加到 output_string.

  5. 到达 input_string 末尾但未找到闭合 DQUOTE. 解析失败.

4.2.6. 解析 Token

给定一个 ASCII 字符串作为 input_string, 返回 Token. input_string 会被修改以移除已解析的值.

  1. 如果 input_string 的第一个字符不是 ALPHA 或 "*", 解析失败.

  2. output_string 为空字符串.

  3. input_string 非空时:

    1. 如果 input_string 的第一个字符不属于 tchar, ":" 或 "/", 返回 output_string.

    2. char 为消费 input_string 第一个字符的结果.

    3. char 追加到 output_string.

  4. 返回 output_string.

4.2.7. 解析 Byte Sequence

给定一个 ASCII 字符串作为 input_string, 返回 Byte Sequence. input_string 会被修改以移除已解析的值.

  1. 如果 input_string 的第一个字符不是 ":", 解析失败.

  2. 丢弃 input_string 的第一个字符.

  3. 如果在 input_string 末尾之前没有 ":" 字符, 解析失败.

  4. b64_content 为消费 input_string 内容直到但不包括第一个 ":" 字符的结果.

  5. 消费 input_string 开头的 ":" 字符.

  6. 如果 b64_content 包含不属于 ALPHA, DIGIT, "+", "/" 和 "=" 的字符, 解析失败.

  7. binary_content 为对 b64_content 进行 base64 解码 [RFC4648] 的结果, 必要时合成 padding (注意下面关于接收者行为的要求). 如果 base64 解码失败, 解析失败.

  8. 返回 binary_content.

由于某些 base64 实现不允许拒绝未正确使用 "=" padding 的编码数据 (见 [RFC4648] Section 3.2), 除非 parsers 无法被配置为这样做, 否则 parsers SHOULD NOT 在 "=" padding 不存在时失败.

由于某些 base64 实现不允许拒绝具有非零 pad bits 的编码数据 (见 [RFC4648] Section 3.5), 除非 parsers 无法被配置为这样做, 否则 parsers SHOULD NOT 在存在非零 pad bits 时失败.

本规范不放宽 [RFC4648] Sections 3.1 和 3.3 中的要求. 因此, parsers MUST 在出现 base64 alphabet 之外的字符以及编码数据中出现换行符时失败.

4.2.8. 解析 Boolean

给定一个 ASCII 字符串作为 input_string, 返回 Boolean. input_string 会被修改以移除已解析的值.

  1. 如果 input_string 的第一个字符不是 "?", 解析失败.

  2. 丢弃 input_string 的第一个字符.

  3. 如果 input_string 的第一个字符匹配 "1", 丢弃该第一个字符并返回 true.

  4. 如果 input_string 的第一个字符匹配 "0", 丢弃该第一个字符并返回 false.

  5. 没有匹配的值. 解析失败.