RFC 5322
Internet Message Format
RFC 5322: Internet Message Format ๐ Part 1 of 11 ๐
Okay bestie, let's start with the title block ๐. This one is the Internet Message Format, written by P. Resnick, Ed. from Qualcomm Incorporated. It's a Standards Track doc in the Network Working Group, dated October 2008. It's also a glow-up of older work: it obsoletes RFC 2822 and updates RFC 4021 ๐ฆโจ
Status of This Memo ๐
So this is an Internet standards track protocol spec for the Internet community, and it's literally asking for discussion and suggestions for improvements ๐ฌ. If you want the current standardization state and status of this protocol, check the current edition of the "Internet Official Protocol Standards" (STD 1) ๐. Distribution of this memo is unlimited ๐.
Abstract ๐ธ
This doc specifies the Internet Message Format (IMF), which is a syntax for text messages sent between computer users inside the whole "electronic mail" world ๐. It's a revision of Request For Comments (RFC) 2822. That one had already replaced Request For Comments (RFC) 822, "Standard for the Format of ARPA Internet Text Messages" ๐ฐ๏ธ. This version updates everything so it matches current practice, and it folds in the small changes that were specified in other RFCs. It's giving upgrade arc ๐
Table of Contents ๐๏ธ
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.1. Scope . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.2. Notational Conventions . . . . . . . . . . . . . . . . . . 5
1.2.1. Requirements Notation . . . . . . . . . . . . . . . . 5
1.2.2. Syntactic Notation . . . . . . . . . . . . . . . . . . 5
1.2.3. Structure of This Document . . . . . . . . . . . . . . 5
2. Lexical Analysis of Messages . . . . . . . . . . . . . . . . . 6
2.1. General Description . . . . . . . . . . . . . . . . . . . 6
2.1.1. Line Length Limits . . . . . . . . . . . . . . . . . . 7
2.2. Header Fields . . . . . . . . . . . . . . . . . . . . . . 8
2.2.1. Unstructured Header Field Bodies . . . . . . . . . . . 8
2.2.2. Structured Header Field Bodies . . . . . . . . . . . . 8
2.2.3. Long Header Fields . . . . . . . . . . . . . . . . . . 8
2.3. Body . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
3. Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
3.1. Introduction . . . . . . . . . . . . . . . . . . . . . . . 10
3.2. Lexical Tokens . . . . . . . . . . . . . . . . . . . . . . 10
3.2.1. Quoted characters . . . . . . . . . . . . . . . . . . 10
3.2.2. Folding White Space and Comments . . . . . . . . . . . 11
3.2.3. Atom . . . . . . . . . . . . . . . . . . . . . . . . . 12
3.2.4. Quoted Strings . . . . . . . . . . . . . . . . . . . . 13
3.2.5. Miscellaneous Tokens . . . . . . . . . . . . . . . . . 14
3.3. Date and Time Specification . . . . . . . . . . . . . . . 14
3.4. Address Specification . . . . . . . . . . . . . . . . . . 16
3.4.1. Addr-Spec Specification . . . . . . . . . . . . . . . 17
3.5. Overall Message Syntax . . . . . . . . . . . . . . . . . . 18
3.6. Field Definitions . . . . . . . . . . . . . . . . . . . . 19
3.6.1. The Origination Date Field . . . . . . . . . . . . . . 22
3.6.2. Originator Fields . . . . . . . . . . . . . . . . . . 22
3.6.3. Destination Address Fields . . . . . . . . . . . . . . 23
3.6.4. Identification Fields . . . . . . . . . . . . . . . . 25
3.6.5. Informational Fields . . . . . . . . . . . . . . . . . 27
3.6.6. Resent Fields . . . . . . . . . . . . . . . . . . . . 28
3.6.7. Trace Fields . . . . . . . . . . . . . . . . . . . . . 30
3.6.8. Optional Fields . . . . . . . . . . . . . . . . . . . 30
4. Obsolete Syntax . . . . . . . . . . . . . . . . . . . . . . . 31
4.1. Miscellaneous Obsolete Tokens . . . . . . . . . . . . . . 32
4.2. Obsolete Folding White Space . . . . . . . . . . . . . . . 33
4.3. Obsolete Date and Time . . . . . . . . . . . . . . . . . . 33
4.4. Obsolete Addressing . . . . . . . . . . . . . . . . . . . 35
4.5. Obsolete Header Fields . . . . . . . . . . . . . . . . . . 35
4.5.1. Obsolete Origination Date Field . . . . . . . . . . . 36
4.5.2. Obsolete Originator Fields . . . . . . . . . . . . . . 36
4.5.3. Obsolete Destination Address Fields . . . . . . . . . 37
4.5.4. Obsolete Identification Fields . . . . . . . . . . . . 37
4.5.5. Obsolete Informational Fields . . . . . . . . . . . . 37
4.5.6. Obsolete Resent Fields . . . . . . . . . . . . . . . . 38
4.5.7. Obsolete Trace Fields . . . . . . . . . . . . . . . . 38
4.5.8. Obsolete optional fields . . . . . . . . . . . . . . . 38
5. Security Considerations . . . . . . . . . . . . . . . . . . . 38
6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 39
Appendix A. Example Messages . . . . . . . . . . . . . . . . . 43
Appendix A.1. Addressing Examples . . . . . . . . . . . . . . . 44
Appendix A.1.1. A Message from One Person to Another with
Simple Addressing . . . . . . . . . . . . . . . . 44
Appendix A.1.2. Different Types of Mailboxes . . . . . . . . . . . 45
Appendix A.1.3. Group Addresses . . . . . . . . . . . . . . . . . 45
Appendix A.2. Reply Messages . . . . . . . . . . . . . . . . . . 46
Appendix A.3. Resent Messages . . . . . . . . . . . . . . . . . 47
Appendix A.4. Messages with Trace Fields . . . . . . . . . . . . 48
Appendix A.5. White Space, Comments, and Other Oddities . . . . 49
Appendix A.6. Obsoleted Forms . . . . . . . . . . . . . . . . . 50
Appendix A.6.1. Obsolete Addressing . . . . . . . . . . . . . . . 50
Appendix A.6.2. Obsolete Dates . . . . . . . . . . . . . . . . . . 50
Appendix A.6.3. Obsolete White Space and Comments . . . . . . . . 51
Appendix B. Differences from Earlier Specifications . . . . . 52
Appendix C. Acknowledgements . . . . . . . . . . . . . . . . . 53
7. References . . . . . . . . . . . . . . . . . . . . . . . . . . 55
7.1. Normative References . . . . . . . . . . . . . . . . . . . 55
7.2. Informative References . . . . . . . . . . . . . . . . . . 55
1. Introduction โจ
1.1. Scope ๐ฏ
This doc specifies the Internet Message Format (IMF) again, same syntax for text messages between computer users in the "electronic mail" framework ๐. This specification is an update to [RFC2822], which itself superseded [RFC0822]. It's updated to match current practice and it pulls in incremental changes from other RFCs, like [RFC1123] ๐ง
This doc specifies a syntax only for text messages ๐. It makes zero provision for sending images, audio, or other kinds of structured data in electronic mail. There are extensions out there, like the MIME document series ([RFC2045], [RFC2046], [RFC2049]), that describe how to send that kind of data through email. They either extend the syntax here or structure messages so they still conform to this syntax. Those mechanisms are outside the scope of this spec ๐ซ
In email, messages have an envelope and contents ๐ฎ. The envelope has whatever info is needed for transmission and delivery. (See [RFC5321] for a discussion of the envelope.) The contents are the object that gets delivered to the recipient. This specification only covers the format and some of the semantics of the contents. It says nothing about the info in the envelope ๐
Some message systems might use info from the contents to build the envelope ๐. This spec is meant to make it easy for programs to grab that info.
This specification is intended as a definition of what message content format gets passed between systems ๐. Some message systems store messages locally in this format, which skips the need for translation between formats. Others use formats that differ from this one. Either way, local storage is outside the scope of this specification ๐
Note: This specification is not intended to dictate the internal formats used by sites, the specific message system features that they are expected to support, or any of the characteristics of user interface programs that create or read messages. In addition, this document does not specify an encoding of the characters for either transport or storage; that is, it does not specify the number of bits used or how those bits are specifically transferred over the wire or stored on disk. ๐
1.2. Notational Conventions ๐
1.2.1. Requirements Notation ๐
This doc sometimes uses words that appear in capital letters ๐ . When the terms "MUST", "SHOULD", "RECOMMENDED", "MUST NOT", "SHOULD NOT", and "MAY" show up capitalized, they're being used to mark particular requirements of this specification. A discussion of what these terms mean is in [RFC2119] ๐ซถ
1.2.2. Syntactic Notation ๐งฉ
This spec uses the Augmented Backus-Naur Form (ABNF) [RFC5234] notation for the formal definitions of message syntax ๐. Characters get specified either by a decimal value (like %d65 for uppercase A and %d97 for lowercase A) or by a case-insensitive literal value in quotation marks (like "A" for either uppercase or lowercase A) ๐ฆ
1.2.3. Structure of This Document ๐บ๏ธ
Okay so this document is split into a bunch of sections, let's go through them ๐
Section 1 is the short intro, and you're literally reading it rn ๐ฆ
Section 2 lays out the general description of a message and its parts. It's an overview to help you get the vibe of the principles used in the later parts of the document. Any examples in this section MUST NOT be taken as specification of the formal syntax of any part of a message. Examples are not the rules, bestie ๐
Section 3 is where the formal ABNF rules live for the structure of each part of a message (the syntax), and it describes how those parts relate to their meaning in a message (the semantics). So it has the actual structural rules, plus descriptions of the parts and how to interpret them. It also analyses the syntax and semantics of subparts that have a specific structure. The syntax in section 3 represents messages as they MUST be created. Section 3 also has notes that flag if any of the options in the syntax SHOULD be used over the others โจ
Sections 2 and 3 both describe messages that are legal to generate for purposes of this spec ๐
Section 4 specifies an "obsolete" syntax, and section 3 has references to these obsolete syntactic elements. These are elements that showed up in earlier versions of this spec or were widely used in Internet messages before. They MUST be interpreted by parsers of messages in order to be conformant to this specification. However, since items in this syntax were determined to be non-interoperable or to cause significant problems for recipients, they MUST NOT be generated by creators of conformant messages ๐
Section 5 details the security considerations to take into account when implementing this specification ๐
Appendix A lists examples of different sorts of messages. These aren't exhaustive, but they give a broad overview of certain syntactic forms ๐ธ
Appendix B lists the differences between this specification and earlier specifications for Internet messages ๐ง
Appendix C contains the acknowledgements ๐ซถ
2. Lexical Analysis of Messages โจ
2.1. General Description
At the most basic level, a message is a series of characters. A message that is conformant with this specification is composed of characters with values in the range of 1 through 127, interpreted as US-ASCII [ANSI.X3-4.1986] characters. For brevity, this document sometimes calls this range simply "US-ASCII characters" ๐
Note: This document specifies that messages are made up of characters in the US-ASCII range of 1 through 127. There are other documents, specifically the MIME document series ([RFC2045], [RFC2046], [RFC2047], [RFC2049], [RFC4288], [RFC4289]), that extend this specification to allow for values outside of that range. Discussion of those mechanisms is not within the scope of this specification ๐
Messages are divided into lines of characters. A line is a series of characters delimited by the two characters carriage-return and line-feed. That is, the carriage return (CR) character (ASCII value 13) followed immediately by the line feed (LF) character (ASCII value 10). (The carriage return/line feed pair is usually written in this document as "CRLF".) ๐
A message consists of header fields (collectively called "the header section of the message") followed, optionally, by a body. The header section is a sequence of lines of characters with special syntax as defined in this specification. The body is simply a sequence of characters that follows the header section, and it's separated from the header section by an empty line (i.e., a line with nothing preceding the CRLF) ๐
Note: Common parlance and earlier versions of this specification use the term "header" to refer either to the entire header section or to an individual header field. To avoid ambiguity, this document does not use the terms "header" or "headers" in isolation. Instead it always uses "header field" for the individual field and "header section" for the entire collection ๐
2.1.1. Line Length Limits ๐
There are two limits this specification places on the number of characters in a line. Each line of characters MUST be no more than 998 characters, and SHOULD be no more than 78 characters, excluding the CRLF ๐ฅ
The 998 character limit exists because many implementations that send, receive, or store IMF messages simply cannot handle more than 998 characters on a line. Receiving implementations would do well to handle an arbitrarily large number of characters in a line for robustness sake. However, there are so many implementations that (in compliance with the transport requirements of [RFC5321]) do not accept messages containing more than 1000 characters including the CR and LF per line, so it is important for implementations not to create such messages ๐ญ
The more conservative 78 character recommendation is there to accommodate the many user interface implementations that display these messages. Those may truncate, or disastrously wrap, the display of more than 78 characters per line, even though such implementations are non-conformant to the intent of this specification (and that of [RFC5321] if they actually cause information to be lost). Again, even though this limitation is put on messages, it is incumbent upon implementations that display messages to handle an arbitrarily large number of characters in a line (certainly at least up to the 998 character limit) for the sake of robustness ๐
2.2. Header Fields ๐
Header fields are lines beginning with a field name, followed by a colon (":"), followed by a field body, and terminated by CRLF. A field name MUST be composed of printable US-ASCII characters (i.e., characters that have values between 33 and 126, inclusive), except colon. A field body may be composed of printable US-ASCII characters as well as the space (SP, ASCII value 32) and horizontal tab (HTAB, ASCII value 9) characters (together known as the white space characters, WSP). A field body MUST NOT include CR and LF except when used in "folding" and "unfolding", as described in section 2.2.3. All field bodies MUST conform to the syntax described in sections 3 and 4 of this specification ๐ฆ
2.2.1. Unstructured Header Field Bodies ๐ธ
Some field bodies in this specification are defined simply as "unstructured" (which section 3.2.5 defines as any printable US-ASCII characters plus white space characters), with no further restrictions. These are referred to as unstructured field bodies. Semantically, unstructured field bodies are simply treated as a single line of characters with no further processing (except for "folding" and "unfolding" as described in section 2.2.3) โจ
2.2.2. Structured Header Field Bodies ๐ง
Some field bodies in this specification have a syntax that is more restrictive than the unstructured field bodies described above. These are referred to as "structured" field bodies. Structured field bodies are sequences of specific lexical tokens, as described in sections 3 and 4 of this specification. Many of these tokens are allowed (according to their syntax) to be introduced or ended with comments (as described in section 3.2.2), as well as the white space characters. Those white space characters are subject to "folding" and "unfolding" as described in section 2.2.3. Semantic analysis of structured field bodies is given along with their syntax ๐
2.2.3. Long Header Fields ๐
Each header field is logically a single line of characters comprising the field name, the colon, and the field body. For convenience, however, and to deal with the 998/78 character limitations per line, the field body portion of a header field can be split into a multiple-line representation. This is called "folding". The general rule is that wherever this specification allows for folding white space (not simply WSP characters), a CRLF may be inserted before any WSP ๐
For example, the header field:
Subject: This is a test
can be represented as:
Subject: This
is a test
Note: Though structured field bodies are defined in such a way that folding can take place between many of the lexical tokens (and even within some of the lexical tokens), folding SHOULD be limited to placing the CRLF at higher-level syntactic breaks. For instance, if a field body is defined as comma-separated values, it is recommended that folding occur after the comma separating the structured items, in preference to other places where the field could be folded, even if it is allowed elsewhere ๐
The process of moving from this folded multiple-line representation of a header field to its single line representation is called "unfolding". Unfolding is accomplished by simply removing any CRLF that is immediately followed by WSP. Each header field should be treated in its unfolded form for further syntactic and semantic evaluation. An unfolded header field has no length restriction and therefore may be indeterminately long ๐ฎ
2.3. Body ๐ท
The body of a message is simply lines of US-ASCII characters. There are only two limitations on the body:
- CR and LF MUST only occur together as CRLF; they MUST NOT appear independently in the body.
- Lines of characters in the body MUST be limited to 998 characters, and SHOULD be limited to 78 characters, excluding the CRLF.
Note: As was stated earlier, there are other documents, specifically the MIME documents ([RFC2045], [RFC2046], [RFC2049], [RFC4288], [RFC4289]), that extend (and limit) this specification to allow for different sorts of message bodies. Again, these mechanisms are beyond the scope of this document ๐
3. Syntax ๐
3.1. Introduction ๐ฆ
The syntax as given in this section defines the legal syntax of Internet messages. Messages that are conformant to this specification MUST conform to the syntax in this section. If there are options in this section where one option SHOULD be generated, that is indicated either in the prose or in a comment next to the syntax โจ
For the defined expressions, a short description of the syntax and use is given, followed by the syntax in ABNF, followed by a semantic analysis. The following primitive tokens, which are used but otherwise unspecified, are taken from the "Core Rules" of [RFC5234], Appendix B.1: CR, LF, CRLF, HTAB, SP, WSP, DQUOTE, DIGIT, ALPHA, and VCHAR ๐
In some of the definitions, there will be non-terminals whose names start with "obs-". These "obs-" elements refer to tokens defined in the obsolete syntax in section 4. In all cases, these productions are to be ignored for the purposes of generating legal Internet messages, and they MUST NOT be used as part of such a message. However, when interpreting messages, these tokens MUST be honored as part of the legal syntax. In this sense, section 3 defines a grammar for the generation of messages, with "obs-" elements that are to be ignored, while section 4 adds grammar for the interpretation of messages ๐ง
3.2. Lexical Tokens ๐
Okay so this is where the lexer comes in ๐ . These rules define the underlying lexical analyzer, the little helper that chops the message into tokens and feeds them up to the higher-level parsers. This section covers the tokens used in structured header field bodies ๐ง.
Bestie, read this part extra carefully ๐. The white space tokens and comment tokens from section 3.2.2 get used inside the lower-level tokens here, and those lower-level tokens become pieces of the higher-level tokens later. So white space and comments can show up inside the higher-level tokens even when a definition doesn't spell it out. iykyk ๐ซถ
3.2.1. Quoted characters ๐ธ
Some characters are reserved for special jobs, like marking where a token starts and ends. So if you want to use them as plain data, there's a quoting mechanism ๐
quoted-pair = ("\" (VCHAR / WSP)) / obs-qp
Wherever a quoted-pair shows up, it gets read as just the character by itself. The "" that's part of a quoted-pair is semantically "invisible" ๐ป
The "" character may appear in a message where it is not part of a quoted-pair. A "" character that does not appear in a quoted-pair is not semantically invisible. The only places in this specification where quoted-pair currently appears are ccontent, qcontent, and in obs-dtext in section 4.
3.2.2. Folding White Space and Comments ๐ฆ
White space can pop up between tons of elements in header field bodies, including white space used for folding (see section 2.2.3). Strings of characters in parentheses can also be treated as comments inside structured field bodies. Here's how the folding white space (FWS) and comment stuff works ๐
Strings of characters enclosed in parentheses count as comments, as long as they don't appear within a "quoted-string" (section 3.2.4). Comments can nest ๐ช
There are a bunch of spots where comments and FWS can be tucked in freely. To handle that, the spec defines a "CFWS" token for every place where comments and/or FWS can show up. But this part is important: wherever CFWS appears, it MUST NOT be inserted in a way that makes any line of a folded header field made up entirely of WSP characters and nothing else ๐ซ
FWS = ([*WSP CRLF] 1*WSP) / obs-FWS
; Folding white space
ctext = %d33-39 / ; Printable US-ASCII
%d42-91 / ; characters not including
%d93-126 / ; "(", ")", or "\"
obs-ctext
ccontent = ctext / quoted-pair / comment
comment = "(" *([FWS] ccontent) [FWS] ")"
CFWS = (1*([FWS] comment) [FWS]) / FWS
Throughout this specification, wherever FWS shows up, it marks a spot where folding (described in section 2.2.3) may take place. Whenever folding appears in a message (that's a header field body containing a CRLF followed by any WSP), unfolding (removing the CRLF) happens before any further semantic analysis of that header field under this spec. So any CRLF that appears in FWS is semantically "invisible" ๐ซฅ
A comment is normally used in a structured field body to give some human-readable info โจ Since a comment can contain FWS, folding is allowed inside it too. Also, since quoted-pair is allowed in a comment, the parentheses and backslash characters can show up in a comment as long as they appear as a quoted-pair. Semantically, the enclosing parentheses aren't part of the comment; the comment is whatever sits between them. As we said earlier, the "" in any quoted-pair and the CRLF in any FWS inside the comment are semantically "invisible," so they aren't part of the comment either ๐
Runs of FWS, comment, or CFWS that sit between lexical tokens in a structured header field are semantically interpreted as a single space character ๐
3.2.3. Atom โ๏ธ
Lots of productions in structured header field bodies are just strings of certain basic characters. These are called atoms ๐
Some structured header field bodies also allow the period character (".", ASCII value 46) within runs of atext. For those, there's an extra "dot-atom" token ๐ง
The "specials" token doesn't appear anywhere else in this specification. It's just the visible (non-control, non-white space) characters that don't appear in atext. It's only provided because it's handy for implementers using tools that lexically analyze messages. Each of the characters in specials can be used to indicate a tokenization point in lexical analysis.
atext = ALPHA / DIGIT / ; Printable US-ASCII
"!" / "#" / ; characters not including
"$" / "%" / ; specials. Used for atoms.
"&" / "'" /
"*" / "+" /
"-" / "/" /
"=" / "?" /
"^" / "_" /
"`" / "{" /
"|" / "}" /
"~"
atom = [CFWS] 1*atext [CFWS]
dot-atom-text = 1*atext *("." 1*atext)
dot-atom = [CFWS] dot-atom-text [CFWS]
specials = "(" / ")" / ; Special characters that do
"<" / ">" / ; not appear in atext
"[" / "]" /
":" / ";" /
"@" / "\" /
"," / "." /
DQUOTE
Both atom and dot-atom are interpreted as a single unit, made up of the string of characters that comprise it. Semantically, the optional comments and FWS surrounding the rest of the characters aren't part of the atom. The atom is only the run of atext characters in an atom, or the atext and "." characters in a dot-atom ๐ฏ
3.2.4. Quoted Strings ๐
Strings that include characters other than the ones allowed in atoms can be written in a quoted string format, where the characters are surrounded by quote (DQUOTE, ASCII value 34) characters ๐
qtext = %d33 / ; Printable US-ASCII
%d35-91 / ; characters not including
%d93-126 / ; "\" or the quote character
obs-qtext
qcontent = qtext / quoted-pair
quoted-string = [CFWS]
DQUOTE *([FWS] qcontent) [FWS] DQUOTE
[CFWS]
A quoted-string is treated as a unit. Semantically, it's identical to an atom ๐ซถ Since a quoted-string is allowed to contain FWS, folding is permitted. Also, since quoted-pair is allowed in a quoted-string, the quote and backslash characters can appear in one as long as they show up as a quoted-pair.
Semantically, neither the optional CFWS outside the quote characters nor the quote characters themselves are part of the quoted-string. The quoted-string is what's contained between the two quote characters. As we said earlier, the "" in any quoted-pair and the CRLF in any FWS/CFWS inside the quoted-string are semantically "invisible," so they aren't part of the quoted-string either ๐ป
3.2.5. Miscellaneous Tokens ๐งฉ
There are three more tokens. word and phrase are for combos of atoms and/or quoted-strings, and unstructured is for unstructured header fields and some places within structured header fields ๐
word = atom / quoted-string
phrase = 1*word / obs-phrase
unstructured = (*([FWS] VCHAR) *WSP) / obs-unstruct
3.3. Date and Time Specification ๐
Date and time values show up in several header fields, so this section lays out the syntax for a full date and time specification. Folding white space is allowed all over the date-time specification, but it is RECOMMENDED that a single space be used in each place that FWS appears (whether it's required or optional). Some older implementations won't interpret longer sequences of folding white space correctly ๐
date-time = [ day-of-week "," ] date time [CFWS]
day-of-week = ([FWS] day-name) / obs-day-of-week
day-name = "Mon" / "Tue" / "Wed" / "Thu" /
"Fri" / "Sat" / "Sun"
date = day month year
day = ([FWS] 1*2DIGIT FWS) / obs-day
month = "Jan" / "Feb" / "Mar" / "Apr" /
"May" / "Jun" / "Jul" / "Aug" /
"Sep" / "Oct" / "Nov" / "Dec"
year = (FWS 4*DIGIT FWS) / obs-year
time = time-of-day zone
time-of-day = hour ":" minute [ ":" second ]
hour = 2DIGIT / obs-hour
minute = 2DIGIT / obs-minute
second = 2DIGIT / obs-second
zone = (FWS ( "+" / "-" ) 4DIGIT) / obs-zone
The day is the numeric day of the month. The year is any numeric year 1900 or later ๐๏ธ
The time-of-day specifies the number of hours, minutes, and optionally seconds since midnight of the date indicated โฐ
The date and time-of-day SHOULD express local time ๐ก
The zone specifies the offset from Coordinated Universal Time (UTC, formerly referred to as "Greenwich Mean Time") that the date and time-of-day represent. The "+" or "-" indicates whether the time-of-day is ahead of (i.e., east of) or behind (i.e., west of) Universal Time. The first two digits indicate the number of hours difference from Universal Time, and the last two digits indicate the number of additional minutes difference from Universal Time. (Hence, +hhmm means +(hh * 60 + mm) minutes, and -hhmm means -(hh * 60 + mm) minutes.) The form "+0000" SHOULD be used to indicate a time zone at Universal Time. Though "-0000" also indicates Universal Time, it is used to indicate that the time was generated on a system that may be in a local time zone other than Universal Time and that the date-time contains no information about the local time zone ๐
A date-time specification MUST be semantically valid ๐ฏ That means the day-of-week (if included) MUST be the day implied by the date, the numeric day-of-month MUST be between 1 and the number of days allowed for the specified month (in the specified year), the time-of-day MUST be in the range 00:00:00 through 23:59:60 (the number of seconds allowing for a leap second; see [RFC1305]), and the last two digits of the zone MUST be within the range 00 through 59. No vibes-only dates allowed ๐ซ๐
3.4. Address Specification โจ
Addresses are how everyone knows who's sending and who's receiving ๐ They show up in several header fields, and an address can be either one individual mailbox or a whole group of mailboxes ๐ซถ
address = mailbox / group
mailbox = name-addr / addr-spec
name-addr = [display-name] angle-addr
angle-addr = [CFWS] "<" addr-spec ">" [CFWS] /
obs-angle-addr
group = display-name ":" [group-list] ";" [CFWS]
display-name = phrase
mailbox-list = (mailbox *("," mailbox)) / obs-mbox-list
address-list = (address *("," address)) / obs-addr-list
group-list = mailbox-list / CFWS / obs-group-list
okay so a mailbox is where mail gets received ๐ฌ It's a conceptual thing, so it doesn't have to be a file sitting on a disk. Some sites literally print the mail and drop it on the addressee's desk ๐จ๏ธ Iconic, honestly.
Normally a mailbox has two parts: (1) an optional display name, which is the name of the recipient (a person or a system) that a mail app can show to the user ๐, and (2) an addr-spec address wrapped in angle brackets, < and >. There's also a simple alternate form where the addr-spec shows up all alone, no name and no angle brackets. The Internet addr-spec address is described in section 3.4.1 ๐ง
Note: Some legacy implementations used the simple form, where the addr-spec appears without the angle brackets, but they put the recipient's name in parentheses as a comment after the addr-spec. Since the meaning of a comment is unspecified, implementations SHOULD use the full name-addr form of the mailbox, instead of the legacy form, to specify the display name associated with a mailbox. Also, because some legacy implementations interpret the comment, comments generally SHOULD NOT be used in address fields to avoid confusing those implementations. ๐
When you want to treat several mailboxes as one unit, like a distribution list, that's where the group construct comes in ๐ It lets the sender name a group of recipients. You give the group a display name, add a colon, then a comma-separated list of any number of mailboxes (zero and one count too), and end with a semicolon. Because the list can be empty, a group is also a cute way to tell recipients the message went to one or more named sets of people, without actually revealing the individual addresses of any of them ๐
3.4.1. Addr-Spec Specification โจ
An addr-spec is a specific Internet identifier. It's got a locally interpreted string, then the at-sign character (@, ASCII value 64), then an Internet domain ๐ฆ That locally interpreted string is either a quoted-string or a dot-atom. If the string can be written as a dot-atom (meaning it has no characters other than atext characters, or dots surrounded by atext characters), then the dot-atom form SHOULD be used and the quoted-string form SHOULD NOT be used ๐
Comments and folding white space SHOULD NOT be used around the "@" in the addr-spec, bestie ๐ซถ
Note: A liberal syntax for the domain portion of addr-spec is given here. However, the domain portion contains addressing information specified by and used in other protocols (e.g., [RFC1034], [RFC1035], [RFC1123], [RFC5321]). It is therefore incumbent upon implementations to conform to the syntax of addresses for the context in which they are used. ๐ฅ
addr-spec = local-part "@" domain
local-part = dot-atom / quoted-string / obs-local-part
domain = dot-atom / domain-literal / obs-domain
domain-literal = [CFWS] "[" *([FWS] dtext) [FWS] "]" [CFWS]
dtext = %d33-90 / ; Printable US-ASCII
%d94-126 / ; characters not including
obs-dtext ; "[", "]", or "\"
The domain part tells you where the mail actually gets delivered ๐ In the dot-atom form, it's read as an Internet domain name (either a host name or a mail exchanger name), as described in [RFC1034], [RFC1035], and [RFC1123]. In the domain-literal form, the domain is read as the literal Internet address of a particular host. Either way, how addressing gets used and how messages travel to a host is covered in separate documents, like [RFC5321]. Those mechanisms are outside the scope of this document, so we're not going there today ๐ธ
The local-part is a domain-dependent string. In an address, the host just reads it as the name of a particular mailbox ๐
3.5. Overall Message Syntax โจ
A message is header fields, optionally followed by a message body ๐ Lines in a message MUST be a maximum of 998 characters excluding the CRLF, but it is RECOMMENDED that lines be limited to 78 characters excluding the CRLF. (See section 2.1.1 for explanation.) In a message body, all of the characters listed in the text rule MAY be used, but using US-ASCII control characters (values 1 through 8, 11, 12, and 14 through 31) is discouraged, since how receivers display them isn't guaranteed ๐ญ
message = (fields / obs-fields)
[CRLF body]
body = (*(*998text CRLF) *998text) / obs-body
text = %d1-9 / ; Characters excluding CR
%d11 / ; and LF
%d12 /
%d14-127
The header fields carry most of the semantic info and are defined in section 3.6 ๐ง The body is basically just a series of lines of text that this spec doesn't interpret at all โจ
3.6. Field Definitions โจ
This is where all the header fields get defined ๐ Every header field has the same general shape: a field name, then a colon, then the field body. The exact syntax for each header field is spelled out in the subsections that follow ๐
Note: In the ABNF syntax for each field in the subsequent sections, each field name is followed by the required colon. However, for brevity, the colon sometimes isn't mentioned in the textual description of the syntax. It is, nonetheless, required. ๐
Here's the tea: header fields are NOT guaranteed to show up in any particular order ๐ซ They can appear in any order, and they've been known to get shuffled around when they travel across the Internet. For this spec, though, header fields SHOULD NOT be reordered when a message is transported or transformed. Even more important, the trace header fields and resent header fields MUST NOT be reordered, and they SHOULD be kept in blocks prepended to the message. See sections 3.6.6 and 3.6.7 for more info ๐ฅ
The only required header fields are the origination date field and the originator address field(s). Everything else is syntactically optional, so you can relax a little ๐ More details are in the table right after this definition โจ
fields = *(trace
*optional-field /
*(resent-date /
resent-from /
resent-sender /
resent-to /
resent-cc /
resent-bcc /
resent-msg-id))
*(orig-date /
from /
sender /
reply-to /
to /
cc /
bcc /
message-id /
in-reply-to /
references /
subject /
comments /
keywords /
optional-field)
The table below shows how many times each field may occur in the header section of a message, plus any special rules for using those fields ๐ An asterisk ("*") next to a value in the minimum or maximum column means there's a special restriction in the Notes column. Read it carefully, it's the fine print ๐
+----------------+--------+------------+----------------------------+
| Field | Min | Max number | Notes |
| | number | | |
+----------------+--------+------------+----------------------------+
| trace | 0 | unlimited | Block prepended - see |
| | | | 3.6.7 |
| resent-date | 0* | unlimited* | One per block, required if |
| | | | other resent fields are |
| | | | present - see 3.6.6 |
| resent-from | 0 | unlimited* | One per block - see 3.6.6 |
| resent-sender | 0* | unlimited* | One per block, MUST occur |
| | | | with multi-address |
| | | | resent-from - see 3.6.6 |
| resent-to | 0 | unlimited* | One per block - see 3.6.6 |
| resent-cc | 0 | unlimited* | One per block - see 3.6.6 |
| resent-bcc | 0 | unlimited* | One per block - see 3.6.6 |
| resent-msg-id | 0 | unlimited* | One per block - see 3.6.6 |
| orig-date | 1 | 1 | |
| from | 1 | 1 | See sender and 3.6.2 |
| sender | 0* | 1 | MUST occur with |
| | | | multi-address from - see |
| | | | 3.6.2 |
| reply-to | 0 | 1 | |
| to | 0 | 1 | |
| cc | 0 | 1 | |
| bcc | 0 | 1 | |
| message-id | 0* | 1 | SHOULD be present - see |
| | | | 3.6.4 |
| in-reply-to | 0* | 1 | SHOULD occur in some |
| | | | replies - see 3.6.4 |
| references | 0* | 1 | SHOULD occur in some |
| | | | replies - see 3.6.4 |
| subject | 0 | 1 | |
| comments | 0 | unlimited | |
| keywords | 0 | unlimited | |
| optional-field | 0 | unlimited | |
+----------------+--------+------------+----------------------------+
The exact meaning of each field gets unpacked in the sections that come next ๐
3.6.1. The Origination Date Field โจ
okay so the origination date field is literally just the field name "Date" followed by a date-time specification ๐
orig-date = "Date:" date-time CRLF
this one tells everyone the date and time when the creator of the message said "yep, I'm done, ready to go" ๐ aka the moment someone pushes "send" or "submit" in an app. but here's the tea ๐ซ: it's specifically not about when the message actually gets transported! it's about when the human (or other creator) finished it and got it into its final form, ready for transport. ๐งณ
for example, a portable computer user who isn't connected to a network might queue a message for delivery. the origination date is meant to hold the date and time they queued it, not the time they finally connected to the network to send it. the way that makes sense, bestie ๐ญ๐
3.6.2. Originator Fields ๐ฆ
the originator fields of a message are the from field, the sender field (when it applies), and optionally the reply-to field. the from field is the field name "From" plus a comma-separated list of one or more mailbox specifications. if the from field has more than one mailbox specification in the mailbox-list, then the sender field (field name "Sender" and one single mailbox specification) MUST appear in the message ๐จ and in either case, an optional reply-to field MAY also be included, with the field name "Reply-To" and a comma-separated list of one or more addresses ๐
from = "From:" mailbox-list CRLF
sender = "Sender:" mailbox CRLF
reply-to = "Reply-To:" address-list CRLF
the originator fields show the mailbox(es) of where the message came from ๐ธ the "From:" field is for the author(s), meaning the mailbox(es) of the person(s) or system(s) responsible for writing the message. the "Sender:" field is for the mailbox of the agent actually responsible for transmitting it. like, if a secretary sends a message for their boss, the secretary's mailbox goes in "Sender:" and the actual author's mailbox goes in "From:" ๐ผโจ if the originator can be shown by one mailbox and the author and transmitter are the same person, the "Sender:" field SHOULD NOT be used. otherwise, both fields SHOULD appear. no cap, that's the whole logic ๐ง
Note: the transmitter information is always present ๐ซถ the absence of the "Sender:" field is sometimes mistakenly taken to mean the agent responsible for transmission hasn't been specified. nope! it just means the transmitter is the same as the author, so it isn't redundantly copied into "Sender:". ๐
the originator fields also give you the info you need when replying ๐ when the "Reply-To:" field is there, it shows the address(es) where the author suggests replies should go. without "Reply-To:", replies SHOULD by default go to the mailbox(es) in the "From:" field, unless the person writing the reply says otherwise ๐ฌ
in all cases, the "From:" field SHOULD NOT contain any mailbox that doesn't belong to the author(s) of the message ๐ซ see also section 3.6.3 for more on forming the destination addresses for a reply ๐
3.6.3. Destination Address Fields ๐
the destination fields of a message are three possible fields, all the same shape: the field name, which is either "To", "Cc", or "Bcc", followed by a comma-separated list of one or more addresses (mailbox or group syntax) ๐
to = "To:" address-list CRLF
cc = "Cc:" address-list CRLF
bcc = "Bcc:" [address-list / CFWS] CRLF
these fields tell you who the recipients are ๐ซถ each destination field can have one or more addresses, and the addresses show the intended recipients. the only difference between the three fields is how each one gets used ๐ฆ
the "To:" field holds the address(es) of the primary recipient(s) of the message ๐
the "Cc:" field (where "Cc" means "Carbon Copy", like making a copy on a typewriter with carbon paper) holds the addresses of others who should get the message, even though the content might not be aimed at them ๐จ๏ธ
the "Bcc:" field (where "Bcc" means "Blind Carbon Copy") holds addresses of recipients whose addresses must stay hidden from the other recipients ๐ฅท there are three ways this gets used. first, when a message with a "Bcc:" field is about to be sent, the "Bcc:" line gets removed, even though everyone (including the "Bcc:" people) still gets a copy. second, the people on "To:" and "Cc:" each get a copy with the "Bcc:" line removed like before, but the people on the "Bcc:" line get their own separate copy that still has a "Bcc:" line. (when there are several addresses in "Bcc:", some implementations actually send a separate copy to each recipient, with a "Bcc:" containing only that person's address ๐คซ) finally, since a "Bcc:" field can have no addresses at all, it can be sent empty to tell recipients that blind copies went out to someone ๐ which method to use with "Bcc:" is implementation dependent, but check the "Security Considerations" section of this document for a discussion of each ๐
when a message is a reply to another message, the mailboxes of the original authors (from the "From:" field) or the mailboxes in "Reply-To:" (if it exists) MAY appear in the "To:" field of the reply, since those are normally the primary recipients ๐ if the original message had destination fields, it's often nice to send a copy of the reply to everyone on it, plus the author โจ when that happens, addresses from the original "To:" and "Cc:" fields MAY appear in the reply's "Cc:" field, since they're usually secondary recipients now ๐ if the original had a "Bcc:" field, addresses from it MAY appear in the reply's "Bcc:" field, but they SHOULD NOT appear in the "To:" or "Cc:" fields ๐ โโ๏ธ
Note: some mail applications have automatic reply commands that copy the original destination addresses into the reply's destination addresses ๐ how those commands behave is implementation dependent and beyond the scope of this document. in particular, whether to include the original destination addresses when the original message had a "Reply-To:" field isn't addressed here ๐คทโโ๏ธ
3.6.4. Identification Fields ๐โจ
Okay so, even though the table in section 3.6 lists these as optional, every message SHOULD have a Message-ID: field ๐. Reply messages SHOULD also have In-Reply-To: and References: fields as appropriate, and we'll get into exactly when below ๐งต.
The Message-ID: field holds one single unique message identifier. The References: and In-Reply-To: fields each hold one or more unique message identifiers, and those can be separated by CFWS ๐ซถ.
The msg-id syntax is basically a stripped-down addr-spec wrapped in the angle bracket characters < and > ๐
. Unlike addr-spec, the left side of the "@" only allows the dot-atom-text form, and there's no internal CFWS anywhere in the message identifier. No drama, just clean syntax ๐.
Note: Just like addr-spec, there's a liberal syntax for the right side of the "@" in a msg-id. But later in this section, using a domain on the right side is RECOMMENDED. The syntax of domain constructs is defined by and used in other protocols (for example, [RFC1034], [RFC1035], [RFC1123], [RFC5321]). So it's on implementations to conform to the address syntax of whatever context they're used in ๐ธ.
message-id = "Message-ID:" msg-id CRLF
in-reply-to = "In-Reply-To:" 1*msg-id CRLF
references = "References:" 1*msg-id CRLF
msg-id = [CFWS] "<" id-left "@" id-right ">" [CFWS]
id-left = dot-atom-text / obs-id-left
id-right = dot-atom-text / no-fold-literal / obs-id-right
no-fold-literal = "[" *dtext "]"
The Message-ID: field gives a unique identifier for one particular version of one particular message ๐ฆ. The host that generates it is what guarantees the uniqueness (more on that below). This ID is meant to be machine readable, and it doesn't have to mean anything to humans ๐ค. Each message identifier belongs to exactly one version of a message, so every new revision of a message gets a brand new ID โจ.
Note: Lots of messages get "changed" without becoming a new message. For example, when messages enter the transport system, they often get extra header fields stuck on, like trace fields (described in section 3.6.7) and resent fields (described in section 3.6.6). Adding those doesn't change who the message is, so the originalMessage-ID:field stays put ๐ง. What matters is what the sender actually means (is this the same message or a different one?), not whatever syntactic differences show up (or don't) in the message. That's the thing that decides whetherMessage-ID:changes ๐.
The In-Reply-To: and References: fields are for making a reply to a message ๐ฌ. They hold the message identifier of the original message, plus the IDs of other messages (like when you're replying to a message that was itself a reply). In-Reply-To: can point at the message (or messages) your new message is responding to, while References: can help track a whole "thread" of conversation ๐งตโจ.
When you make a reply, the In-Reply-To: and References: fields of the result get built like this:
The In-Reply-To: field will contain the contents of the Message-ID: field of the message this one is replying to (the "parent message"). If there's more than one parent message, then In-Reply-To: will contain the contents of all of the parents' Message-ID: fields. And if none of the parent messages have a Message-ID: field, then the new message won't have an In-Reply-To: field at all ๐.
The References: field will contain the contents of the parent's References: field (if it has one), followed by the contents of the parent's Message-ID: field (if it has one). If the parent doesn't have a References: field but does have an In-Reply-To: field with a single message identifier, then References: will contain the parent's In-Reply-To: contents, followed by the parent's Message-ID: contents (if any). And if the parent has none of References:, In-Reply-To:, or Message-ID:, then the new message won't have a References: field ๐
.
Note: Some implementations parseReferences:to display the "thread of the discussion". They assume every new message is a reply to a single parent, so they can walk backwards throughReferences:to find each message's parent. Because of that, trying to build aReferences:field for a reply with multiple parents is discouraged. How to do it isn't defined in this document ๐ญ.
The message identifier (msg-id) itself MUST be a globally unique identifier for a message. The generator of the message identifier MUST guarantee that the msg-id is unique ๐ฅ. There are several algorithms that can do this. Since msg-id has a similar syntax to addr-spec (identical, except quoted strings, comments, and folding white space aren't allowed), a solid method is to put the domain name (or a domain literal IP address) of the host where the message identifier was created on the right side of the "@" (since domain names and IP addresses are normally unique). Then put the current absolute date and time, along with some other currently unique (maybe sequential) identifier available on the system (like a process id number), on the left side ๐. Other algorithms work too, but it is RECOMMENDED that the right side contain some domain identifier (either the host's own, or some other one) so the generator can guarantee the uniqueness of the left side within that domain's scope ๐.
Semantically, the angle bracket characters aren't actually part of the msg-id. The msg-id is just what sits between the two angle brackets ๐.
3.6.5. Informational Fields ๐
The informational fields are all optional ๐ท. The Subject: and Comments: fields are unstructured fields as defined in section 2.2.1, so they can hold text or folding white space. The Keywords: field holds a comma-separated list of one or more words or quoted-strings ๐.
subject = "Subject:" unstructured CRLF
comments = "Comments:" unstructured CRLF
keywords = "Keywords:" phrase *("," phrase) CRLF
These three fields are meant to contain only human-readable info about the message ๐ฅฐ. Subject: is the most common one, and it's a short string saying what the message is about โจ. When you're replying, the field body MAY start with the string "Re: " (short for the Latin "in re", meaning "in the matter of") followed by the contents of the original message's Subject: field body ๐. If you do that, only one instance of the literal string "Re: " ought to be used, because using other strings or more than one instance can lead to undesirable consequences ๐. Comments: is for any extra comments on the body text of the message ๐ฌ. And Keywords: holds a comma-separated list of important words and phrases that might be useful to the recipient ๐๐.
3.6.6. Resent Fields ๐
Okay bestie, so whenever a user reintroduces a message into the transport system, resent fields SHOULD be added ๐ And every single time that happens, a brand-new set of resent fields SHOULD be added too โจ All of the resent fields for one particular resend SHOULD be grouped together ๐ซถ Each new set gets prepended, so the most recent set sits earlier in the message than the older ones ๐ธ The iconic part is that no other fields in the message get changed when resent fields are added ๐
Every resent field is basically a twin of a regular field somewhere else in the syntax ๐ฏ Like, "Resent-Date:" matches "Date:" and "Resent-To:" matches "To:". Same vibes, and the syntax for the field body is identical to the one for the field it copies ๐
When resent fields are used, "Resent-From:" and "Resent-Date:" MUST be sent ๐ฅ "Resent-Message-ID:" SHOULD be sent ๐ฆ And "Resent-Sender:" SHOULD NOT be used if it would be identical to "Resent-From:", because why would you repeat yourself ๐
resent-date = "Resent-Date:" date-time CRLF
resent-from = "Resent-From:" mailbox-list CRLF
resent-sender = "Resent-Sender:" mailbox CRLF
resent-to = "Resent-To:" address-list CRLF
resent-cc = "Resent-Cc:" address-list CRLF
resent-bcc = "Resent-Bcc:" [address-list / CFWS] CRLF
resent-msg-id = "Resent-Message-ID:" msg-id CRLF
Resent fields are how a message says "hey, a user reintroduced me into the transport system" ๐ง The whole goal is that the final recipient sees the message as if the original sender sent it directly, with all of the original fields still exactly the same ๐ Each set of resent fields matches one resending event. So if a message gets resent multiple times, every set tells you about one individual resend ๐ Resent fields are strictly informational ๐ They MUST NOT be used in the normal processing of replies or other such automatic actions on messages ๐ซ
Note: Reintroducing a message into the transport system with resent fields is a different operation from "forwarding" ๐ "Forwarding" has two meanings. In one sense, a mail reading program can be told by a user to forward a copy of a message to someone else, which makes the forwarded message the body of a brand-new message. A forwarded message in this sense doesn't look like it came from the original sender at all. It's an entirely new message from the forwarder. In the other sense, a mail transport program gets a message and passes it along to a different destination for final delivery. Resent header fields are not meant for either type of forwarding ๐
The resent originator fields show the mailbox of the person or system that resent the message ๐ฎ Just like the regular originator fields, there are two forms. There's the simple "Resent-From:" form, which holds the mailbox of the individual doing the resending. Then there's the more complex form, where one individual (named in the "Resent-Sender:" field) resends a message on behalf of one or more others (named in the "Resent-From:" field) ๐ญ
Note: When you reply to a resent message, replies work exactly like they would for any other message ๐ฌ They use the original "From:", "Reply-To:", "Message-ID:", and other fields. The resent fields are only informational and MUST NOT be used in the normal processing of replies ๐ โโ๏ธ
"Resent-Date:" shows the date and time that the resender dispatched the resent message ๐ Like "Date:", it is not the date and time the message was actually transported ๐
"Resent-To:", "Resent-Cc:", and "Resent-Bcc:" work exactly like "To:", "Cc:", and "Bcc:", respectively. The only difference is that they list the recipients of the resent message, not the recipients of the original message ๐ฌ
"Resent-Message-ID:" gives the resent message its own unique identifier ๐
3.6.7. Trace Fields ๐ต๏ธโโ๏ธ
The trace fields are a group of header fields. They consist of an optional "Return-Path:" field and one or more "Received:" fields ๐ค๏ธ The "Return-Path:" header field has a pair of angle brackets that enclose an optional addr-spec. The "Received:" field has a list of tokens that could be empty, followed by a semicolon and a date-time specification. Each token must be a word, angle-addr, addr-spec, or a domain. Further restrictions on the syntax of the trace fields are applied by specifications that provide for their use, such as [RFC5321] ๐
trace = [return]
1*received
return = "Return-Path:" path CRLF
path = angle-addr / ([CFWS] "<" [CFWS] ">" [CFWS])
received = "Received:" *received-token ";" date-time CRLF
received-token = word / angle-addr / addr-spec / domain
A full discussion of how Internet mail uses trace fields is in [RFC5321] ๐ For the purposes of this specification, trace fields are strictly informational. Any formal interpretation of them is outside the scope of this document ๐
3.6.8. Optional Fields ๐
Fields can show up in messages that this document doesn't otherwise specify โจ They MUST conform to the syntax of an optional-field. That means it's a field name made of printable US-ASCII characters, except SP and colon, followed by a colon, followed by any text that conforms to the unstructured syntax ๐งฉ
The field names of any optional field MUST NOT be identical to any field name specified elsewhere in this document ๐ โโ๏ธ No copying the official names, bestie ๐
optional-field = field-name ":" unstructured CRLF
field-name = 1*ftext
ftext = %d33-57 / ; Printable US-ASCII
%d59-126 ; characters not including
; ":".
For the purposes of this specification, any optional field is uninterpreted ๐ฆ
4. Obsolete Syntax ๐ฐ๏ธ
Earlier versions of this specification allowed different syntax, usually more liberal than what this version allows ๐ท There have also been syntactic elements that showed up in Internet messages but whose interpretations were never documented ๐ต๏ธโโ๏ธ Even so, these syntactic forms MUST NOT be generated according to the grammar in section 3, but they MUST be accepted and parsed by a conformant receiver ๐ซถ This section documents many of these elements. If you take the grammar in section 3 and add the definitions in this section, you get the grammar to use when interpreting messages ๐
Note: This section identifies syntactic forms that any implementation MUST reasonably interpret ๐ That said, there are definitely Internet messages that don't conform even to the extra syntax given here. A form not appearing in any section of this document is not an excuse for programs to crash, or for malformed data to be irretrievably lost by any implementation. It's up to the implementation to handle messages robustly ๐ช
One big difference between the obsolete (interpreting) syntax and the current (generating) syntax is this: in structured header field bodies (anything between the colon and the CRLF of a structured header field), white space characters, including folding white space, and comments could be freely inserted between any syntactic tokens. That allowed many complex forms that were hard for some implementations to parse ๐
Another key difference is that the rule in section 3.2.2 about lines made up entirely of white space, in comments and folding white space, doesn't apply here. See the discussion of folding white space in section 4.2 below ๐ซง
Finally, certain characters that used to be allowed in messages appear in this section ๐ The NUL character (ASCII value 0) was once allowed, but it's no longer allowed, for compatibility reasons. Similarly, US-ASCII control characters other than CR, LF, SP, and HTAB (ASCII values 1 through 8, 11, 12, 14 through 31, and 127) were allowed to show up in header field bodies. CR and LF were allowed to appear in messages other than as CRLF, and that use is shown here too ๐ง
Other differences in syntax and semantics are noted in the following sections ๐
4.1. Miscellaneous Obsolete Tokens ๐งธ
These syntactic elements are used elsewhere in the obsolete syntax or in the main syntax ๐ Bare CR, bare LF, and NUL get added to obs-qp, obs-body, and obs-unstruct. US-ASCII control characters get added to obs-qp, obs-unstruct, obs-ctext, and obs-qtext. The period character gets added to obs-phrase. The obs-phrase-list gives you a (potentially empty) comma-separated list of phrases that can include "null" elements. In other words, you could have two or more commas in a row with nothing in between, or commas at the very beginning or end of the list ๐
Note: The "period" (or "full stop") character (".") in obs-phrase wasn't allowed in any earlier version of this specification or any other spec ๐ Period, like every other character from specials, wasn't allowed in phrase, because it made it hard to tell phrases apart from parts of an addr-spec (see section 4.4). It shows up here because people use the period all the time in the display-name portion of addresses, especially for initials in names, so it has to be interpreted properly ๐
obs-NO-WS-CTL = %d1-8 / ; US-ASCII control
%d11 / ; characters that do not
%d12 / ; include the carriage
%d14-31 / ; return, line feed, and
%d127 ; white space characters
obs-ctext = obs-NO-WS-CTL
obs-qtext = obs-NO-WS-CTL
obs-utext = %d0 / obs-NO-WS-CTL / VCHAR
obs-qp = "\" (%d0 / obs-NO-WS-CTL / LF / CR)
obs-body = *((*LF *CR *((%d0 / text) *LF *CR)) / CRLF)
obs-unstruct = *((*LF *CR *(obs-utext *LF *CR)) / FWS)
obs-phrase = word *(word / "." / CFWS)
obs-phrase-list = [phrase / CFWS] *("," [phrase / CFWS])
Bare CR and bare LF show up in messages with two different meanings ๐ญ A lot of the time, bare CR or bare LF gets used wrongly instead of CRLF as a line separator. Other times, bare CR and bare LF are just used as US-ASCII control characters with their traditional ASCII meanings ๐ซ
4.2. Obsolete Folding White Space ๐ช
In the obsolete syntax, any amount of folding white space MAY be inserted wherever the obs-FWS rule is allowed ๐ธ That makes it possible to have two consecutive "folds" in a line, which means a line that makes up part of a folded header field could be made up entirely of white space ๐คฏ
obs-FWS = 1*WSP *(CRLF 1*WSP)
4.3. Obsolete Date and Time โจ
okay so the obsolete date format is very throwback ๐ง It lets you use a 2 digit year in the date field, and it has a whole list of alphabetic time zone names that earlier versions of this spec used. It also lets comments and folding white space sit between lots of the tokens. literally so extra ๐
obs-day-of-week = [CFWS] day-name [CFWS]
obs-day = [CFWS] 1*2DIGIT [CFWS]
obs-year = [CFWS] 2*DIGIT [CFWS]
obs-hour = [CFWS] 2DIGIT [CFWS]
obs-minute = [CFWS] 2DIGIT [CFWS]
obs-second = [CFWS] 2DIGIT [CFWS]
obs-zone = "UT" / "GMT" / ; Universal Time
; North American UT
; offsets
"EST" / "EDT" / ; Eastern: - 5/ - 4
"CST" / "CDT" / ; Central: - 6/ - 5
"MST" / "MDT" / ; Mountain: - 7/ - 6
"PST" / "PDT" / ; Pacific: - 8/ - 7
;
%d65-73 / ; Military zones - "A"
%d75-90 / ; through "I" and "K"
%d97-105 / ; through "Z", both
%d107-122 ; upper and lower case
Okay now the years, this part is kind of a mood ๐ธ If a two digit year is between 00 and 49, you add 2000, so it lands somewhere between 2000 and 2049. If a two digit year is between 50 and 99, or if you get any three digit year at all, you add 1900 instead. Bestie, remember that rule ๐ซถ
"UT" and "GMT" both mean "Universal Time" and "Greenwich Mean Time", and they are both semantically identical to "+0000" ๐
The remaining three character zones are the US time zones ๐บ๐ธ The first letter is "E", "C", "M", or "P", which stands for "Eastern", "Central", "Mountain", or "Pacific". The second letter is either "S" for "Standard" time or "D" for "Daylight Savings" (or summer) time. Here's how they're interpreted:
EDT is semantically equivalent to -0400
EST is semantically equivalent to -0500
CDT is semantically equivalent to -0500
CST is semantically equivalent to -0600
MDT is semantically equivalent to -0600
MST is semantically equivalent to -0700
PDT is semantically equivalent to -0700
PST is semantically equivalent to -0800
The 1 character military time zones were defined in a non-standard way in [RFC0822], so their meaning is unpredictable, which is so chaotic ๐ The original definitions have "A" through "I" equivalent to "+0100" through "+0900", respectively. "K", "L", and "M" are equivalent to "+1000", "+1100", and "+1200", respectively. "N" through "Y" are equivalent to "-0100" through "-1200", and "Z" is equivalent to "+0000". Because of the error in [RFC0822], they SHOULD all be considered equivalent to "-0000" unless there is out-of-band information confirming their meaning ๐
Other multi-character (usually between 3 and 5) alphabetic time zones have shown up in Internet messages too. Any such time zone whose meaning is not known SHOULD be considered equivalent to "-0000" unless there is out-of-band information confirming their meaning ๐ง
4.4. Obsolete Addressing ๐
There are four main differences in addressing, so let's go through them ๐ฆ First, mailbox addresses were allowed to have a route portion before the addr-spec when enclosed in "<" and ">". The route is a comma-separated list of domain names, each one preceded by "@", and the list ends with a colon. Second, CFWS were allowed between the period-separated elements of local-part and domain, which means dot-atom wasn't used. local-part was also allowed to contain a quoted-string as well as an atom. Third, mailbox-list and address-list were allowed to have "null" members. That means you could have two or more commas in a row with nothing between them, or commas at the very beginning or end of the list ๐ญ Finally, US-ASCII control characters and quoted-pairs were allowed in domain literals, and they're added here.
obs-angle-addr = [CFWS] "<" obs-route addr-spec ">" [CFWS]
obs-route = obs-domain-list ":"
obs-domain-list = *(CFWS / ",") "@" domain
*("," [CFWS] ["@" domain])
obs-mbox-list = *([CFWS] ",") mailbox *("," [mailbox / CFWS])
obs-addr-list = *([CFWS] ",") address *("," [address / CFWS])
obs-group-list = 1*([CFWS] ",") [CFWS]
obs-local-part = word *("." word)
obs-domain = atom *("." atom)
obs-dtext = obs-NO-WS-CTL / quoted-pair
When you're interpreting addresses, the route portion SHOULD be ignored ๐ซถ
4.5. Obsolete Header Fields ๐
Syntactically, the big difference with the obsolete field syntax is that it lets you have multiple occurrences of any of the fields, and they can show up in any order ๐ Also, any amount of white space is allowed before the ":" at the end of the field name.
obs-fields = *(obs-return /
obs-received /
obs-orig-date /
obs-from /
obs-sender /
obs-reply-to /
obs-to /
obs-cc /
obs-bcc /
obs-message-id /
obs-in-reply-to /
obs-references /
obs-subject /
obs-comments /
obs-keywords /
obs-resent-date /
obs-resent-from /
obs-resent-send /
obs-resent-rply /
obs-resent-to /
obs-resent-cc /
obs-resent-bcc /
obs-resent-mid /
obs-optional)
Except for destination address fields (described in section 4.5.3), the interpretation of multiple occurrences of fields is unspecified ๐คทโโ๏ธ Also, the interpretation of trace fields and resent fields that do not occur in blocks prepended to the message is unspecified as well. Unless otherwise noted in the following sections, the interpretation of other fields is identical to the interpretation of their non-obsolete counterparts in section 3 โจ
4.5.1. Obsolete Origination Date Field
obs-orig-date = "Date" *WSP ":" date-time CRLF
4.5.2. Obsolete Originator Fields
obs-from = "From" *WSP ":" mailbox-list CRLF
obs-sender = "Sender" *WSP ":" mailbox CRLF
obs-reply-to = "Reply-To" *WSP ":" address-list CRLF
4.5.3. Obsolete Destination Address Fields ๐
obs-to = "To" *WSP ":" address-list CRLF
obs-cc = "Cc" *WSP ":" address-list CRLF
obs-bcc = "Bcc" *WSP ":"
(address-list / (*([CFWS] ",") [CFWS])) CRLF
When multiple occurrences of destination address fields show up in a message, they SHOULD be treated as if the address list in the first occurrence of the field is combined with the address lists of the subsequent occurrences, by adding a comma and concatenating them ๐ง
4.5.4. Obsolete Identification Fields ๐ชช
The obsolete "In-Reply-To:" and "References:" fields are different from the current syntax because they allow phrase (words or quoted strings) to appear. The obsolete forms of the left and right sides of msg-id allow interspersed CFWS, which makes them syntactically identical to local-part and domain, respectively.
obs-message-id = "Message-ID" *WSP ":" msg-id CRLF
obs-in-reply-to = "In-Reply-To" *WSP ":" *(phrase / msg-id) CRLF
obs-references = "References" *WSP ":" *(phrase / msg-id) CRLF
obs-id-left = local-part
obs-id-right = domain
For purposes of interpretation, the phrases in the "In-Reply-To:" and "References:" fields are ignored ๐
Semantically, none of the optional CFWS in the local-part and the domain is part of the obs-id-left and obs-id-right, respectively ๐
4.5.5. Obsolete Informational Fields ๐
obs-subject = "Subject" *WSP ":" unstructured CRLF
obs-comments = "Comments" *WSP ":" unstructured CRLF
obs-keywords = "Keywords" *WSP ":" obs-phrase-list CRLF
4.5.6. Obsolete Resent Fields ๐
The obsolete syntax adds a "Resent-Reply-To:" field, which is made up of the field name, the optional comments and folding white space, the colon, and a comma-separated list of addresses ๐
obs-resent-from = "Resent-From" *WSP ":" mailbox-list CRLF
obs-resent-send = "Resent-Sender" *WSP ":" mailbox CRLF
obs-resent-date = "Resent-Date" *WSP ":" date-time CRLF
obs-resent-to = "Resent-To" *WSP ":" address-list CRLF
obs-resent-cc = "Resent-Cc" *WSP ":" address-list CRLF
obs-resent-bcc = "Resent-Bcc" *WSP ":"
(address-list / (*([CFWS] ",") [CFWS])) CRLF
obs-resent-mid = "Resent-Message-ID" *WSP ":" msg-id CRLF
obs-resent-rply = "Resent-Reply-To" *WSP ":" address-list CRLF
As with other resent fields, the "Resent-Reply-To:" field is to be treated as trace information only ๐
4.5.7. Obsolete Trace Fields ๐ค๏ธ
The obs-return and obs-received are given here again as template definitions, just like return and received in section 3. Their full syntax is given in [RFC5321] ๐ซ
obs-return = "Return-Path" *WSP ":" path CRLF
obs-received = "Received" *WSP ":" *received-token CRLF
4.5.8. Obsolete optional fields ๐
obs-optional = field-name *WSP ":" unstructured CRLF
5. Security Considerations โจ
okay bestie, security time, and this part is lowkey important ๐ฅ. when you show messages on a terminal or terminal emulator, you have to be careful. powerful terminals will act on escape sequences and other combos of US-ASCII control characters, and that can go badly. they can remap your keyboard or change other settings in ways that lead to denial of service or even damaged data ๐. they can also trigger (sometimes programmable) answerback messages, which means a message could make commands run on the recipient's behalf ๐ญ. terminals can affect attached devices too, like printers ๐จ๏ธ. message viewers may want to strip the dangerous terminal escape sequences before display. BUT other escape sequences show up in messages for useful reasons (see [ISO.2022.1994], [RFC2045], [RFC2046], [RFC2047], [RFC2049], [RFC4288], [RFC4289]), so you shouldn't strip them indiscriminately ๐ โโ๏ธ.
non-text objects in messages bring extra security issues too. the details live in [RFC2045], [RFC2046], [RFC2047], [RFC2049], [RFC4288], and [RFC4289] ๐ซถ.
now the big one: the Bcc: (blind carbon copy) field, described in section 3.6.3 ๐. lots of implementations use it so you can send to people without showing their addresses to everyone else. but if you mess this up, you can leak confidential info, and even just knowing that an address exists can eventually lead to security problems ๐ฑ. for example, with the first method in section 3.6.3 (where the Bcc: line is removed from the message), blind recipients don't get any explicit sign that they got a blind copy. the only hint is that their address isn't in the header section. so one of the blind addressees could hit reply-all to all the shown recipients and accidentally reveal that they got the message ๐. with the second method in section 3.6.3, the blind recipient's address shows up in the Bcc: field of a separate copy of the message. if that Bcc: field includes all of the blind addressees, then every Bcc: recipient can see all of them ๐ญ. even if you send each Bcc: recipient their own message with only their address, implementations still need to be careful when processing replies, following section 3.6.3, so they don't accidentally reveal the blind recipient to other recipients ๐ซฃ.
6. IANA Considerations ๐
this document updates the registrations that showed up in [RFC4021] that referred to the definitions in [RFC2822] ๐ฆ. IANA has updated the Permanent Message Header Field Repository with the following header fields, following the procedures in [RFC3864] ๐ .
Header field name: Date
Applicable protocol: Mail
Status: standard
Author/Change controller: IETF
Specification document(s): This document (section 3.6.1)
Header field name: From
Applicable protocol: Mail
Status: standard
Author/Change controller: IETF
Specification document(s): This document (section 3.6.2)
Header field name: Sender
Applicable protocol: Mail
Status: standard
Author/Change controller: IETF
Specification document(s): This document (section 3.6.2)
Header field name: Reply-To
Applicable protocol: Mail
Status: standard
Author/Change controller: IETF
Specification document(s): This document (section 3.6.2)
Header field name: To
Applicable protocol: Mail
Status: standard
Author/Change controller: IETF
Specification document(s): This document (section 3.6.3)
Header field name: Cc
Applicable protocol: Mail
Status: standard
Author/Change controller: IETF
Specification document(s): This document (section 3.6.3)
Header field name: Bcc
Applicable protocol: Mail
Status: standard
Author/Change controller: IETF
Specification document(s): This document (section 3.6.3)
Header field name: Message-ID
Applicable protocol: Mail
Status: standard
Author/Change controller: IETF
Specification document(s): This document (section 3.6.4)
Header field name: In-Reply-To
Applicable protocol: Mail
Status: standard
Author/Change controller: IETF
Specification document(s): This document (section 3.6.4)
Header field name: References
Applicable protocol: Mail
Status: standard
Author/Change controller: IETF
Specification document(s): This document (section 3.6.4)
Header field name: Subject
Applicable protocol: Mail
Status: standard
Author/Change controller: IETF
Specification document(s): This document (section 3.6.5)
Header field name: Comments
Applicable protocol: Mail
Status: standard
Author/Change controller: IETF
Specification document(s): This document (section 3.6.5)
Header field name: Keywords
Applicable protocol: Mail
Status: standard
Author/Change controller: IETF
Specification document(s): This document (section 3.6.5)
Header field name: Resent-Date
Applicable protocol: Mail
Status: standard
Author/Change controller: IETF
Specification document(s): This document (section 3.6.6)
Header field name: Resent-From
Applicable protocol: Mail
Status: standard
Author/Change controller: IETF
Specification document(s): This document (section 3.6.6)
Header field name: Resent-Sender
Applicable protocol: Mail
Status: standard
Author/Change controller: IETF
Specification document(s): This document (section 3.6.6)
Header field name: Resent-To
Applicable protocol: Mail
Status: standard
Author/Change controller: IETF
Specification document(s): This document (section 3.6.6)
Header field name: Resent-Cc
Applicable protocol: Mail
Status: standard
Author/Change controller: IETF
Specification document(s): This document (section 3.6.6)
Header field name: Resent-Bcc
Applicable protocol: Mail
Status: standard
Author/Change controller: IETF
Specification document(s): This document (section 3.6.6)
Header field name: Resent-Reply-To
Applicable protocol: Mail
Status: obsolete
Author/Change controller: IETF
Specification document(s): This document (section 4.5.6)
Header field name: Resent-Message-ID
Applicable protocol: Mail
Status: standard
Author/Change controller: IETF
Specification document(s): This document (section 3.6.6)
Header field name: Return-Path
Applicable protocol: Mail
Status: standard
Author/Change controller: IETF
Specification document(s): This document (section 3.6.7)
Header field name: Received
Applicable protocol: Mail
Status: standard
Author/Change controller: IETF
Specification document(s): This document (section 3.6.7)
Related information: [RFC5321]
Appendix A. Example Messages ๐ง
this section has a selection of messages ๐ธ. they're meant to help you implement this spec, but they're NOT normative, so don't treat them as the rulebook ๐. the examples were carefully reviewed, BUT if an example ever conflicts with the syntax in sections 3 and 4 of this document, the syntax in those sections is the correct one ๐ .
in the text version of this document, messages in this section sit between lines of "----". those "----" lines are not part of the message itself ๐ฉต.
Appendix A.1. Addressing Examples ๐
these are messages that might get sent between two individuals ๐ฅฐ.
Appendix A.1.1. A Message from One Person to Another with Simple Addressing
this could be called a canonical message โจ. it has one author, John Doe, one recipient, Mary Smith, a subject, the date, a message identifier, and a textual message in the body ๐.
From: John Doe <jdoe@machine.example>
To: Mary Smith <mary@example.net>
Subject: Saying Hello
Date: Fri, 21 Nov 1997 09:55:06 -0600
Message-ID: <1234@local.machine.example>
This is a message just to say hello.
So, "Hello".
okay so if John's secretary Michael actually sent it, even though John is the author and replies should go back to him ๐, the sender field gets used ๐โโ๏ธ:
From: John Doe <jdoe@machine.example>
Sender: Michael Jones <mjones@machine.example>
To: Mary Smith <mary@example.net>
Subject: Saying Hello
Date: Fri, 21 Nov 1997 09:55:06 -0600
Message-ID: <1234@local.machine.example>
This is a message just to say hello.
So, "Hello".
Appendix A.1.2. Different Types of Mailboxes
this message has multiple addresses in the destination fields and uses a bunch of different address forms ๐ฆ.
From: "Joe Q. Public" <john.q.public@example.com>
To: Mary Smith <mary@x.test>, jdoe@example.org, Who? <one@y.test>
Cc: <boss@nil.test>, "Giant; \"Big\" Box" <sysservices@example.net>
Date: Tue, 1 Jul 2003 10:52:37 +0200
Message-ID: <5678.21-Nov-1997@example.com>
Hi everyone.
note the display names for Joe Q. Public and Giant; "Big" Box have to be wrapped in double-quotes ๐, because the first has a period and the second has both a semicolon and double-quote characters (those double-quotes show up as quoted-pair constructs) ๐ง. conversely, the display name for Who? doesn't need them, because a question mark is legal in an atom โจ. also notice that jdoe@example.org and boss@nil.test don't have display names at all, and jdoe@example.org uses the simpler address form without angle brackets ๐ซถ.
Appendix A.1.3. Group Addresses ๐
From: Pete <pete@silly.example>
To: A Group:Ed Jones <c@a.test>,joe@where.test,John <jdoe@one.test>;
Cc: Undisclosed recipients:;
Date: Thu, 13 Feb 1969 23:32:54 -0330
Message-ID: <testabcd.1234@silly.example>
Testing.
in this message, the To: field has one group recipient called "A Group", which holds 3 addresses ๐. there's also a Cc: field with an empty group recipient named Undisclosed recipients ๐.
Appendix A.2. Reply Messages โจ
okay so this one is a whole group chat ๐ฌ three messages between John and Mary, and it's a full conversation thread bestie ๐ซถ John texts Mary first, Mary replies, and then John replies to her reply. the main thing to notice is the "Message-ID:", "References:", and "In-Reply-To:" fields in each one, because that's how the thread gets stitched together ๐งตโจ
From: John Doe <jdoe@machine.example>
To: Mary Smith <mary@example.net>
Subject: Saying Hello
Date: Fri, 21 Nov 1997 09:55:06 -0600
Message-ID: <1234@local.machine.example>
This is a message just to say hello.
So, "Hello".
when you reply, the Subject field usually sticks around, just with "Re: " slapped on the front ๐ that's the thing section 3.6.5 talks about, and it's giving organized ๐
From: Mary Smith <mary@example.net>
To: John Doe <jdoe@machine.example>
Reply-To: "Mary Smith: Personal Account" <smith@home.example>
Subject: Re: Saying Hello
Date: Fri, 21 Nov 1997 10:01:10 -0600
Message-ID: <3456@example.net>
In-Reply-To: <1234@local.machine.example>
References: <1234@local.machine.example>
This is a reply to your hello.
ok, now watch the Reply-To: field in Mary's message ๐๐ฆ when John replies to her, the reply should go to the address in "Reply-To:" instead of the one in "From:". so Mary's personal account gets it, not her work one ๐
To: "Mary Smith: Personal Account" <smith@home.example>
From: John Doe <jdoe@machine.example>
Subject: Re: Saying Hello
Date: Fri, 21 Nov 1997 11:00:00 -0600
Message-ID: <abcd.1234@local.machine.test>
In-Reply-To: <3456@example.net>
References: <1234@local.machine.example> <3456@example.net>
This is a reply to your reply.
Appendix A.3. Resent Messages
ok so we're gonna start with that same hello message we've been using forever ๐ธ
From: John Doe <jdoe@machine.example>
To: Mary Smith <mary@example.net>
Subject: Saying Hello
Date: Fri, 21 Nov 1997 09:55:06 -0600
Message-ID: <1234@local.machine.example>
This is a message just to say hello.
So, "Hello".
now say Mary gets this and wants to forward a copy to Jane ๐ง she wants three things: (a) it has to look like it came straight from John, (b) if Jane replies, the reply goes back to John, and (c) all the original info survives, like when it was first sent to Mary, the message identifier, and who it was originally addressed to ๐ซถ the way to do that is to prepend resent fields to the message, and that's it, that's the whole trick โจ
Resent-From: Mary Smith <mary@example.net>
Resent-To: Jane Brown <j-brown@other.example>
Resent-Date: Mon, 24 Nov 1997 14:22:01 -0800
Resent-Message-ID: <78910@example.net>
From: John Doe <jdoe@machine.example>
To: Mary Smith <mary@example.net>
Subject: Saying Hello
Date: Fri, 21 Nov 1997 09:55:06 -0600
Message-ID: <1234@local.machine.example>
This is a message just to say hello.
So, "Hello".
and if Jane wants to pass it along to somebody else? she just stacks her own set of resent header fields on top of the above and sends it ๐ฅ (quick note: for brevity, the trace fields aren't shown here, so don't panic if they're missing ๐)
Appendix A.4. Messages with Trace Fields
so every time a message goes through the transport system, as described in [RFC5321], trace fields get prepended to it ๐ here's what they might look like. heads up, the first one has some folding white space because those lines can get super long ๐
Received: from x.y.test
by example.net
via TCP
with ESMTP
id ABC12345
for <mary@example.net>; 21 Nov 1997 10:05:43 -0600
Received: from node.example by x.y.test; 21 Nov 1997 10:01:22 -0600
From: John Doe <jdoe@node.example>
To: Mary Smith <mary@example.net>
Subject: Saying Hello
Date: Fri, 21 Nov 1997 09:55:06 -0600
Message-ID: <1234@local.node.example>
This is a message just to say hello.
So, "Hello".
Appendix A.5. White Space, Comments, and Other Oddities
okay this one is chaotic and I'm obsessed ๐๐ white space, including folding white space, and comments can be stuffed into basically every token of a field. so we're taking the example from A.1.3 and absolutely going wild with it ๐
From: Pete(A nice \) chap) <pete(his account)@silly.test(his host)>
To:A Group(Some people)
:Chris Jones <c@(Chris's host.)public.example>,
joe@example.org,
John <jdoe@one.test> (my dear friend); (the end of the group)
Cc:(Empty list)(start)Hidden recipients :(nobody(that I know)) ;
Date: Thu,
13
Feb
1969
23:32
-0330 (Newfoundland Time)
Message-ID: <testabcd.1234@silly.test>
Testing.
it's aesthetically displeasing, I won't lie ๐ญ but it's perfectly legal, and that's the iconic part ๐ here's what's going on:
- In "From:", there are comments everywhere, including one with a ")" that shows up as part of a quoted-pair ๐
- In "To:", there's no white space after the ":", plus a comment and folding white space after the group name. Chris Jones's address has a "." inside a comment, and there's folding white space before and after "joe@example.org,". ๐
- In "Cc:", there are multiple nested comments, and a comment sitting right after the ":" that follows "Cc" ๐งถ
- In the date, there's folding white space (with no comments except at the very end), and the seconds are just missing from the time ๐ฐ๏ธ
- In "Message-ID:", there's white space before the identifier, but none inside it ๐ฆ
Appendix A.6. Obsoleted Forms
these are examples of the obsolete syntax elements from section 4 of this document, the ones that a generator MUST NOT generate ๐ซ old-school stuff, we don't do that anymore bestie ๐
Appendix A.6.1. Obsolete Addressing
in this one, look at the missing quotes around Joe Q. Public, the route in Mary Smith's address, the two commas in the "To:" field, and the spaces around the "." in the jdoe address ๐ณ it's a whole mess ๐
From: Joe Q. Public <john.q.public@example.com>
To: Mary Smith <@node.test:mary@example.net>, , jdoe@test . example
Date: Tue, 1 Jul 2003 10:52:37 +0200
Message-ID: <5678.21-Nov-1997@example.com>
Hi everyone.
Appendix A.6.2. Obsolete Dates
this message uses an obsolete date format: a non-numeric time zone and a two digit year ๐๏ธ also the day-of-week is missing, but that isn't specific to the obsolete syntax, because it's optional in the current syntax too ๐ธ
From: John Doe <jdoe@machine.example>
To: Mary Smith <mary@example.net>
Subject: Saying Hello
Date: 21 Nov 97 09:55:06 GMT
Message-ID: <1234@local.machine.example>
This is a message just to say hello.
So, "Hello".
Appendix A.6.3. Obsolete White Space and Comments
white space and comments can show up between way more stuff than in the current syntax, and folding lines made up entirely of white space are legal too ๐ it's a lot, but we love a chaotic energy ๐คช
From : John Doe <jdoe@machine(comment). example>
To : Mary Smith
__
<mary@example.net>
Subject : Saying Hello
Date : Fri, 21 Nov 1997 09(comment): 55 : 06 -0600
Message-ID : <1234 @ local(blah) .machine .example>
This is a message just to say hello.
So, "Hello".
the second line of "To:" is the one to watch ๐ it starts with two space characters (the "__" in the example stands for blank spaces), so it counts as folding, the way section 4.2 describes. and the comments and white space all through the addresses, dates, and message identifiers? all part of the obsolete syntax ๐ซ
Appendix B. Differences from Earlier Specifications
okay time for the glow-up history ๐โจ this appendix lists the changes made to the Internet Message Format compared to earlier specs, specifically [RFC0822], [RFC1123], and [RFC2822]. the items marked with an asterisk (*) are things that show up in section 4 of this document, so they can no longer be generated ๐ โโ๏ธ
here's what changed from [RFC0822] and [RFC1123] to [RFC2822] and is still in this document:
- Period allowed in obsolete form of phrase.
- ABNF moved out of document, now in [RFC5234].
- Four or more digits allowed for year.
- Header field ordering (and lack thereof) made explicit.
- Encrypted header field removed.
- Specifically allow and give meaning to "-0000" time zone.
- Folding white space is not allowed between every token.
- Requirement for destinations removed.
- Forwarding and resending redefined.
- Extension header fields no longer specifically called out.
- ASCII 0 (null) removed.*
- Folding continuation lines cannot contain only white space.*
- Free insertion of comments not allowed in date.*
- Non-numeric time zones not allowed.*
- Two digit years not allowed.*
- Three digit years interpreted, but not allowed for generation.*
- Routes in addresses not allowed.*
- CFWS within local-parts and domains not allowed.*
- Empty members of address lists not allowed.*
- Folding white space between field name and colon not allowed.*
- Comments between field name and colon not allowed.
- Tightened syntax of in-reply-to and references.*
- CFWS within msg-id not allowed.*
- Tightened semantics of resent fields as informational only.
- Resent-Reply-To not allowed.*
- No multiple occurrences of fields (except resent and received).*
- Free CR and LF not allowed.*
- Line length limits specified.
- Bcc more clearly specified.
and here's what changed from [RFC2822] itself:
- Assorted typographical/grammatical errors fixed and clarifications made.
- Changed "standard" to "document" or "specification" throughout.
- Made distinction between "header field" and "header section".
- Removed NO-WS-CTL from ctext, qtext, dtext, and unstructured.*
- Moved discussion of specials to the "Atom" section. Moved text to "Overall message syntax" section.
- Simplified CFWS syntax.
- Fixed unstructured syntax.
- Changed date and time syntax to deal with white space in obsolete date syntax.
- Removed quoted-pair from domain literals and message identifiers.*
- Clarified that other specifications limit domain syntax.
- Simplified "Bcc:" and "Resent-Bcc:" syntax.
- Allowed optional-field to appear within trace information.
- Removed no-fold-quote from msg-id. Clarified syntax limitations.
- Generalized "Received:" syntax to fix bugs and move definition out of this document.
- Simplified obs-qp. Fixed and simplified obs-utext (which now only appears in the obsolete syntax). Removed obs-text and obs-char, adding obs-body.
- Fixed obsolete date syntax to allow for more (or less) comments and white space.
- Fixed all obsolete list syntax (obs-domain-list, obs-mbox-list, obs-addr-list, obs-phrase-list, and the newly added obs-group-list).
- Fixed obs-reply-to syntax.
- Fixed obs-bcc and obs-resent-bcc to allow empty lists.
- Removed obs-path.
Appendix C. Acknowledgements ๐
okay so bestie, this is the list of everyone who helped make this doc happen ๐ซถ the people in the DRUMS Working Group of the IETF, the DRUMS chair, the IETF Area Directors, and literally everyone who just emailed in their notes ๐ the editor is SO grateful and thanks them all sincerely โจ the list below has everyone who emailed about this doc and [RFC2822], and the hope is that every contributor made it onto the list ๐
+--------------------+----------------------+---------------------+
| Matti Aarnio | Tanaka Akira | Russ Allbery |
| Eric Allman | Harald Alvestrand | Ran Atkinson |
| Jos Backus | Bruce Balden | Dave Barr |
| Alan Barrett | John Beck | J Robert von Behren |
| Jos den Bekker | D J Bernstein | James Berriman |
| Oliver Block | Norbert Bollow | Raj Bose |
| Antony Bowesman | Scott Bradner | Randy Bush |
| Tom Byrer | Bruce Campbell | Larry Campbell |
| W J Carpenter | Michael Chapman | Richard Clayton |
| Maurizio Codogno | Jim Conklin | R Kelley Cook |
| Nathan Coulter | Steve Coya | Mark Crispin |
| Dave Crocker | Matt Curtin | Michael D'Errico |
| Cyrus Daboo | Michael D Dean | Jutta Degener |
| Mark Delany | Steve Dorner | Harold A Driscoll |
| Michael Elkins | Frank Ellerman | Robert Elz |
| Johnny Eriksson | Erik E Fair | Roger Fajman |
| Patrik Faltstrom | Claus Andre Faerber | Barry Finkel |
| Erik Forsberg | Chuck Foster | Paul Fox |
| Klaus M Frank | Ned Freed | Jochen Friedrich |
| Randall C Gellens | Sukvinder Singh Gill | Tim Goodwin |
| Philip Guenther | Arnt Gulbrandsen | Eric A Hall |
| Tony Hansen | John Hawkinson | Philip Hazel |
| Kai Henningsen | Robert Herriot | Paul Hethmon |
| Jim Hill | Alfred Hoenes | Paul E Hoffman |
| Steve Hole | Kari Hurtta | Marco S Hyman |
| Ofer Inbar | Olle Jarnefors | Kevin Johnson |
| Sudish Joseph | Maynard Kang | Prabhat Keni |
| John C Klensin | Graham Klyne | Brad Knowles |
| Shuhei Kobayashi | Peter Koch | Dan Kohn |
| Christian Kuhtz | Anand Kumria | Steen Larsen |
| Eliot Lear | Barry Leiba | Jay Levitt |
| Bruce Lilly | Lars-Johan Liman | Charles Lindsey |
| Pete Loshin | Simon Lyall | Bill Manning |
| John Martin | Mark Martinec | Larry Masinter |
| Denis McKeon | William P McQuillan | Alexey Melnikov |
| Perry E Metzger | Steven Miller | S Moonesamy |
| Keith Moore | John Gardiner Myers | Chris Newman |
| John W Noerenberg | Eric Norman | Mike O'Dell |
| Larry Osterman | Paul Overell | Jacob Palme |
| Michael A Patton | Uzi Paz | Michael A Quinlan |
| Robert Rapplean | Eric S Raymond | Sam Roberts |
| Hugh Sasse | Bart Schaefer | Tom Scola |
| Wolfgang Segmuller | Nick Shelness | John Stanley |
| Einar Stefferud | Jeff Stephenson | Bernard Stern |
| Peter Sylvester | Mark Symons | Eric Thomas |
| Lee Thompson | Karel De Vriendt | Matthew Wall |
| Rolf Weber | Brent B Welch | Dan Wing |
| Jack De Winter | Gregory J Woodhouse | Greg A Woods |
| Kazu Yamamoto | Alain Zahm | Jamie Zawinski |
| Timothy S Zurcher | | |
+--------------------+----------------------+---------------------+
7. References ๐
7.1. Normative References ๐
These are the must-reads, the foundation everything else is built on ๐
[ANSI.X3-4.1986] American National Standards Institute, "Coded
Character Set - 7-bit American Standard Code for
Information Interchange", ANSI X3.4, 1986.
[RFC1034] Mockapetris, P., "Domain names - concepts and
facilities", STD 13, RFC 1034, November 1987.
[RFC1035] Mockapetris, P., "Domain names - implementation and
specification", STD 13, RFC 1035, November 1987.
[RFC1123] Braden, R., "Requirements for Internet Hosts -
Application and Support", STD 3, RFC 1123,
October 1989.
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119, March 1997.
[RFC5234] Crocker, D. and P. Overell, "Augmented BNF for
Syntax Specifications: ABNF", STD 68, RFC 5234,
January 2008.
7.2. Informative References ๐ฆ
These ones are more like extra reading for when you want the backstory ๐ธ
[RFC0822] Crocker, D., "Standard for the format of ARPA
Internet text messages", STD 11, RFC 822,
August 1982.
[RFC1305] Mills, D., "Network Time Protocol (Version 3)
Specification, Implementation", RFC 1305,
March 1992.
[ISO.2022.1994] International Organization for Standardization,
"Information technology - Character code structure
and extension techniques", ISO Standard 2022, 1994.
[RFC2045] Freed, N. and N. Borenstein, "Multipurpose Internet
Mail Extensions (MIME) Part One: Format of Internet
Message Bodies", RFC 2045, November 1996.
[RFC2046] Freed, N. and N. Borenstein, "Multipurpose Internet
Mail Extensions (MIME) Part Two: Media Types",
RFC 2046, November 1996.
[RFC2047] Moore, K., "MIME (Multipurpose Internet Mail
Extensions) Part Three: Message Header Extensions
for Non-ASCII Text", RFC 2047, November 1996.
[RFC2049] Freed, N. and N. Borenstein, "Multipurpose Internet
Mail Extensions (MIME) Part Five: Conformance
Criteria and Examples", RFC 2049, November 1996.
[RFC2822] Resnick, P., "Internet Message Format", RFC 2822,
April 2001.
[RFC3864] Klyne, G., Nottingham, M., and J. Mogul,
"Registration Procedures for Message Header
Fields", BCP 90, RFC 3864, September 2004.
[RFC4021] Klyne, G. and J. Palme, "Registration of Mail and
MIME Header Fields", RFC 4021, March 2005.
[RFC4288] Freed, N. and J. Klensin, "Media Type
Specifications and Registration Procedures",
BCP 13, RFC 4288, December 2005.
[RFC4289] Freed, N. and J. Klensin, "Multipurpose Internet
Mail Extensions (MIME) Part Four: Registration
Procedures", BCP 13, RFC 4289, December 2005.
[RFC5321] Klensin, J., "Simple Mail Transfer Protocol",
RFC 5321, October 2008.
Author's Address ๐ท
Peter W. Resnick (editor)
Qualcomm Incorporated
5775 Morehouse Drive
San Diego, CA 92121-1714
US
Phone: +1 858 651 4478
EMail: presnick@qualcomm.com
URI: http://www.qualcomm.com/~presnick/
Full Copyright Statement โญ
Copyright (C) The IETF Trust (2008).
This document is subject to the rights, licenses and restrictions
contained in BCP 78, and except as set forth therein, the authors
retain all their rights.
This document and the information contained herein are provided on an
"AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND
THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF
THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
Intellectual Property ๐ฅ
The IETF takes no position on whether any Intellectual Property Rights or other rights that might be claimed to apply to the technology in this document are valid or in scope, or whether any license under those rights might or might not be available. It also doesn't claim to have done any independent search for those rights. Info on how RFC documents handle rights lives in BCP 78 and BCP 79 ๐ง
Copies of IPR disclosures sent to the IETF Secretariat, assurances of licenses, and the results of any attempt to get a general license or permission to use those proprietary rights for implementing or using this spec can be found in the IETF's online IPR repository at:
http://www.ietf.org/ipr
The IETF invites anyone to flag any copyrights, patents, patent applications, or other proprietary rights that might cover technology needed to implement this standard. Send that info to the IETF at:
ietf-ipr@ietf.org
That's the whole doc, bestie ๐ ๐ you made it through all 11 parts! ๐
๐ฆ where this page comes from
- ietf: rfc5322 2008-10
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms