From b180278da6d83a69795dffa667bac941775b7ab5 Mon Sep 17 00:00:00 2001 From: Neil Jenkins Date: Mon, 5 Mar 2018 13:49:54 +1100 Subject: [PATCH] Add :all suffix option for requesting header fields Also refactor description of how this works to reduce redundancy --- spec/mail/message.mdown | 43 +++++++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/spec/mail/message.mdown b/spec/mail/message.mdown index 31d7c0fc..68e58a68 100644 --- a/spec/mail/message.mdown +++ b/spec/mail/message.mdown @@ -109,7 +109,7 @@ These properties are derived from the [@!RFC5322] and [@!RFC6532] message header * Any header not defined in [@!RFC5322] or [@!RFC2369] - **MessageIds** - The header is parsed as a list of `msg-id` values, as specified in [@!RFC5322] section 3.6.4, into the `String[]` type. + The header is parsed as a list of `msg-id` values, as specified in [@!RFC5322] section 3.6.4, into the `String[]` type. If parsing fails, the value is `null`. To prevent obviously nonsense behaviour, which can lead to interoperability issues, this form may only be fetched or set for the following header fields: @@ -120,7 +120,7 @@ These properties are derived from the [@!RFC5322] and [@!RFC6532] message header * Any header not defined in [@!RFC5322] or [@!RFC2369] - **Date** - The header is parsed as a `date-time` value, as specified in [@!RFC5322] section 3.3, into the `Date` type. + The header is parsed as a `date-time` value, as specified in [@!RFC5322] section 3.3, into the `Date` type. If parsing fails, the value is `null`. To prevent obviously nonsense behaviour, which can lead to interoperability issues, this form may only be fetched or set for the following header fields: @@ -129,7 +129,7 @@ These properties are derived from the [@!RFC5322] and [@!RFC6532] message header * Any header not defined in [@!RFC5322] or [@!RFC2369] - **URL** - The header is parsed as a URL, as described in [@!RFC2369], into the `String` type. This does not include the surrounding angle brackets or any comments in the header with the URL. + The header is parsed as a URL, as described in [@!RFC2369], into the `String` type. This does not include the surrounding angle brackets or any comments in the header with the URL. If parsing fails, the value is `null`. To prevent obviously nonsense behaviour, which can lead to interoperability issues, this form may only be fetched or set for the following header fields: @@ -141,7 +141,7 @@ These properties are derived from the [@!RFC5322] and [@!RFC6532] message header * List-Archive * Any header not defined in [@!RFC5322] or [@!RFC2369] -The following low-level **Email** properties are specified for complete access to the header data of the message. Where `{header-field-name}` is specified within a property name, this means any series of one or more printable ASCII characters (i.e. characters that have values between 33 and 126, inclusive), except colon. Where `{header-form}` is specified within a property name, this means one of the parsed-form name specified above. +The following low-level **Email** property is specified for complete access to the header data of the message: - **headers**: `EmailHeader[]` (immutable) This is a list of all [@!RFC5322] header fields, in the same order they appear in the message. An **EmailHeader** object has the following properties: @@ -151,16 +151,35 @@ The following low-level **Email** properties are specified for complete access t - **value**: `String` The header *field value* as defined in RFC5322, in *Raw* form. -- **header:{header-field-name}**: `String|null` (immutable) - The value of the *last* header field in the message with the given header field name (matched case-insensitively), or `null` if none. The value is in *Raw* form. -- **header:{header-field-name}:as{header-form}**: - `String|String[]|EmailAddress[]|Date|null` (immutable) - The value of the *last* header field in the message with the given header field name (matched case-insensitively), or `null` if none, decoded according to the parsing algorithm given. +In addition, the client may request/send properties representing individual header fields of the form: + + header:{header-field-name} + +Where `{header-field-name}` means any series of one or more printable ASCII characters (i.e. characters that have values between 33 and 126, inclusive), except colon. The property may also have the following suffixes: + + - **:as{header-form}** + This means the value is in a parsed form, where `{header-form}` is one of the parsed-form names specified above. If not given, the value is in *Raw* form. + + - **:all** + This means the value is an array, with the items corresponding to each instance of the header field, in the order they appear in the message. If this suffix is not used, the result is the value of the **last** instance of the header field (i.e. identical to the **last** item in the array if :all is used). + +If both suffixes are used, they MUST be specified in the order above. Header field names are matched **case-insensitively**. If no header fields exist in the message with the requested name, the value is `null`. Otherwise, the value is typed according to the requested form, or an array of that type if :all is used. + +As a simple example, if the client requests a property called `header:subject`, this means find the *last* header field in the message named "subject" (matched case-insensitively) and return the value in *Raw* form. + +For a more complex example, consider the client requesting a property called `header:Resent-To:asAddresses:all`. This means: + +1. Find *all* header fields named Resent-To (matched + case-insensitively). If none, the value is `null`, and you're done. +2. Otherwise, for each instance parse the header field value in the + *Addresses* form. + +The result is of type `EmailAddress[][]` – each item in the array corresponds to the parsed value (which is itself an array) of the Resent-To header field instance. The following convenience properties are also specified for the **Email** object: -- **messageId**: `String[]` (immutable) - The value is identical to the value of *header:Message-ID:asMessageIds*. +- **messageId**: `String[]|null` (immutable) + The value is identical to the value of *header:Message-ID:asMessageIds*. For messages conforming to RFC5322 this will be an array with a single entry. - **inReplyTo**: `String[]|null` (immutable) The value is identical to the value of *header:In-Reply-To:asMessageIds*. - **references**: `String[]|null` (immutable) @@ -179,7 +198,7 @@ The following convenience properties are also specified for the **Email** object The value is identical to the value of *header:Reply-To:asAddresses*. - **subject**: `String|null` (immutable) The value is identical to the value of *header:Subject:asText*. -- **sentAt**: `Date` (immutable; default on creation: current time on server) +- **sentAt**: `Date|null` (immutable; default on creation: current server time) The value is identical to the value of *header:Date:asDate*. ### Body parts