2.1. HTTP Fields
2.1. HTTP Fields
The component name for an HTTP field is the lowercased form of its field name as defined in Section 5.1 of [HTTP]. While HTTP field names are case insensitive, implementations MUST use lowercased field names (e.g., content-type, date, etag) when using them as component names.
The component value for an HTTP field is the field value for the named field as defined in Section 5.5 of [HTTP]. The field value MUST be taken from the named header field of the target message unless this behavior is overridden by additional parameters and rules, such as the req and tr flags, below. For most fields, the field value is an ASCII string as recommended by [HTTP], and the component value is exactly that string. Other encodings could exist in some implementations, and all non-ASCII field values MUST be encoded to ASCII before being added to the signature base. The bs parameter, as described in Section 2.1.3, provides a method for wrapping such problematic field values.
Unless overridden by additional parameters and rules, HTTP field values MUST be combined into a single value as defined in Section 5.2 of [HTTP] to create the component value. Specifically, HTTP fields sent as multiple fields MUST be combined by concatenating the values using a single comma and a single space as a separator ("," + " "). Note that intermediaries are allowed to combine values of HTTP fields with any amount of whitespace between the commas, and if this behavior is not accounted for by the verifier, the signature can fail, since the signer and verifier will see a different component value in their respective signature bases. For robustness, it is RECOMMENDED that signed messages include only a single instance of any field covered under the signature, particularly with the value for any list-based fields serialized using the algorithm below. This approach increases the chances of the field value remaining untouched through intermediaries. Where that approach is not possible and multiple instances of a field need to be sent separately, it is RECOMMENDED that signers and verifiers process any list-based fields taking all individual field values and combining them based on the strict algorithm below, to counter possible intermediary behavior. When the field in question is a Structured Field of type List or Dictionary, this effect can be accomplished more directly by requiring the strict Structured Field serialization of the field value, as described in Section 2.1.1.
Note that some HTTP fields, such as Set-Cookie [COOKIE], do not follow a syntax that allows for the combination of field values in this manner (such that the combined output is unambiguous from multiple inputs). Even though the component value is never parsed by the message signature process and is used only as part of the signature base (Section 2.5), caution needs to be taken when including such fields in signatures, since the combined value could be ambiguous. The bs parameter, as described in Section 2.1.3, provides a method for wrapping such problematic fields. See Section 7.5.6 for more discussion regarding this issue.
If the correctly combined value is not directly available for a given field by an implementation, the following algorithm will produce canonicalized results for list-based fields:
-
Create an ordered list of the field values of each instance of the field in the message, in the order they occur (or will occur) in the message.
-
Strip leading and trailing whitespace from each item in the list. Note that since HTTP field values are not allowed to contain leading and trailing whitespace, this would be a no-op in a compliant implementation.
-
Remove any obsolete line folding within the line, and replace it with a single space (" "), as discussed in Section 5.2 of [HTTP/1.1]. Note that this behavior is specific to HTTP/1.1 and does not apply to other versions of the HTTP specification, which do not allow internal line folding.
-
Concatenate the list of values with a single comma (",") and a single space (" ") between each item.
The resulting string is the component value for the field.
Note that some HTTP fields have values with multiple valid serializations that have equivalent semantics, such as allowing case- insensitive values that intermediaries could change. Applications signing and processing such fields MUST consider how to handle the values of such fields to ensure that the signer and verifier can derive the same value, as discussed in Section 7.5.2.
The following are non-normative examples of component values for header fields, given the following example HTTP message fragment:
Host: www.example.com Date: Tue, 20 Apr 2021 02:07:56 GMT X-OWS-Header: Leading and trailing whitespace. X-Obs-Fold-Header: Obsolete line folding. Cache-Control: max-age=60 Cache-Control: must-revalidate Example-Dict: a=1, b=2;x=1;y=2, c=(a b c)
The following example shows the component values for these example header fields, presented using the signature base format defined in Section 2.5:
"host": www.example.com "date": Tue, 20 Apr 2021 02:07:56 GMT "x-ows-header": Leading and trailing whitespace. "x-obs-fold-header": Obsolete line folding. "cache-control": max-age=60, must-revalidate "example-dict": a=1, b=2;x=1;y=2, c=(a b c)
Empty HTTP fields can also be signed when present in a message. The canonicalized value is the empty string. This means that the following empty header field, with (SP) indicating a single trailing space character before the empty field value:
X-Empty-Header:(SP)
is serialized by the signature base generation algorithm (Section 2.5) with an empty string value following the colon and space added after the component identifier.
"x-empty-header":(SP)
Any HTTP field component identifiers MAY have the following parameters in specific circumstances, each described in detail in their own sections:
sf A Boolean flag indicating that the component value is serialized using strict encoding of the Structured Field value (Section 2.1.1).
key A String parameter used to select a single member value from a Dictionary Structured Field (Section 2.1.2).
bs A Boolean flag indicating that individual field values are encoded using Byte Sequence data structures before being combined into the component value (Section 2.1.3).
req A Boolean flag for signed responses indicating that the component value is derived from the request that triggered this response message and not from the response message directly. Note that this parameter can also be applied to any derived component identifiers that target the request (Section 2.4).
tr A Boolean flag indicating that the field value is taken from the trailers of the message as defined in Section 6.5 of [HTTP]. If this flag is absent, the field value is taken from the header fields of the message as defined in Section 6.3 of [HTTP] (Section 2.1.4).
Multiple parameters MAY be specified together, though some combinations are redundant or incompatible. For example, the sf parameter's functionality is already covered when the key parameter is used on a Dictionary item, since key requires strict serialization of the value. The bs parameter, which requires the raw bytes of the field values from the message, is not compatible with the use of the sf or key parameters, which require the parsed data structures of the field values after combination.
Additional parameters can be defined in the "HTTP Signature Component Parameters" registry established in Section 6.5.