From: Charles Lindsey (chl@clw.cs.man.ac.uk)
Date: Thu Apr 04 2002 - 14:05:45 CST
Here is the full syntax, after the recent spate of changes.
Now that we can see the full syntax of headers all in one place, we can
address the issue of where parameters should be allowed, which some
people have been asking about.
First, two statements which are, I hope, not controversial:
1. There are no parameters after the "unstructured" headers.
2. Section 4 says that
.parameters MAY anywhere our syntax allows, except that
.they SHOULD NOT be used (for now) in headers that did not have
them before this standard (i.e. the MAY applies only to the newly
introduced headers), but
.compliant software MUST accept (and usually ignore) them anywhere our
syntax allows, and
.compliant software SHOULD accept (and ignore) them in all headers
(including those borrowed from other standards).
Now the present state of our draft:
3. Our syntax allows parameters in all unstructured headers that our draft
defines. This causes slight parsing difficulties in headers where a naked
';' can occur in the main part of the header. In fact, that is just the
headers with address-list in them. There is a NOTE pointing out the need
for care when parsing these. In other cases, ignoring everything after a
naked ';' should be easy enough to implement.
4. So we can consider a series of increasingly severe changes we might make:
4a. Leave it as it is.
4b. Disallow parameters in those address-list headers. That would eliminate
Complaints-To
Reply-To
Mail-Copies-To
(though you might exclude Complaints-To and Mail-Copies-To on the
grounds that they are "ours", parsing problems or not)
4c. Disallow parameters in the mailbox-list headers (because people get
confused between the subtle difference between address and mailbox).
That would eliminate
From
Sender
4d. Disallow parameters in all those headers which also appear in RFC
2822 (however, it might be argued that most of these are really "News
headers" which Email has borrowd, but does not really use). That would
eliminate
Date
Message-ID
Keywords
4e. Disallow also the two headers defined in RFC 2156 which can arise
from conversion of Emails from X.400. These really our our headers, and
RFC 2156 had no business filching them. That would eliminate
Expires
Supersedes
And in case you were wondering what is left, the headers which really
are our own are
Newsgroups
Path
Distribution
Followup-To
Posted-And-Mailed
Archive
Control
Approved
Xref
Lines
User-Agent
Injector-Info
Complaints-To
And of these we have actually define useful parameters for
Archive
Injector-Info
(we also had some in Replaces at one time)
And of course all the MIME headers allow parameters.
And finally, here is the collwcted syntax:
Appendix B - Collected Syntax
Appendix B.1 - Characters, Atoms and Folding
In the following syntactic rules, numbers in the left hand margin
indicate rules taken from other documents, specifically:
2 from [RFC 2822] with the exception of those elements described
therein as "obsolete";
3 from [RFC 2373]
4 from [RFC 2234];
5 from [RFC 2045].
Where the number is followed by an asterisk ('*'), it indicates that
the rule in question has been modified for the purposes of this
standard.
4 ALPHA = %x41-5A / ; A-Z
%x61-7A ; a-z
2 CFWS = *([FWS] comment) (([FWS] comment) / FWS )
4 CR = %x0D ; carriage return
4 CRLF = CR LF
4 DIGIT = %x30-39 ; 0-9
4 DQUOTE = %d34 ; quote mark
2 FWS = ([*WSP CRLF] 1*WSP); Folding whitespace
4 HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F"
4 HTAB = %x09 ; horizontal tab
4 LF = %x0A ; line feed
2 NO-WS-CTL = %d1-8 / ; US-ASCII control characters
%d11 / ; which do not include the
%d12 / ; carriage return, line feed,
%d14-31 / ; and whitespace characters
%d127
4 SP = %x20 ; space
4 WSP = SP / HTAB ; Whitespace characters
UTF8-xtra-2-head = %xC2-DF
UTF8-xtra-3-head = %xE0 %xA0-BF / %xE1-EC %x80-BF /
%xED %x80-9F / %xEE-EF %x80-BF
UTF8-xtra-4-head = %xF0 %x90-BF / %xF1-F7 %x80-BF
UTF8-xtra-5-head = %xF8 %x88-BF / %xF9-FB %x80-BF
UTF8-xtra-6-head = %xFC %x84-BF / %xFD %x80-BF
UTF8-xtra-char = UTF8-xtra-2-head 1( UTF8-xtra-tail ) /
UTF8-xtra-3-head 1( UTF8-xtra-tail ) /
UTF8-xtra-4-head 2( UTF8-xtra-tail ) /
UTF8-xtra-5-head 3( UTF8-xtra-tail ) /
UTF8-xtra-6-head 4( UTF8-xtra-tail )
UTF8-xtra-tail = %x80-BF
2 atext = ALPHA / DIGIT /
"!" / "#" / ; Any character except
"$" / "%" / ; controls, SP, and specials.
"&" / "'" / ; Used for atoms
"*" / "+" /
"-" / "/" /
"=" / "?" /
"^" / "_" /
"`" / "{" /
"|" / "}" /
"~"
2 atom = [CFWS] 1*atext [CFWS]
2 ccontent = ctext / quoted-pair / comment
2 comment = "(" *([FWS] ccontent) [FWS] ")"
2* ctext = NO-WS-CTL / ; all of <text> except
%d33-39 / ; SP, HTAB, "(", ")"
%d42-91 / ; and "\"
%d93-126 /
UTF8-xtra-char
2 dcontent = dtext / quoted-pair
2 dot-atom = [CFWS] dot-atom-text [CFWS]
2 dot-atom-text = 1*atext *( "." 1*atext )
2 dtext = NO-WS-CTL / ; Non white space controls
%d33-90 / ; The rest of the US-ASCII
%d94-126 ; characters not including
; "[", "]", or "
2 phrase = 1*word
2 qcontent = qtext / quoted-pair
2* qtext = NO-WS-CTL / ; all of <text> except
%d33 / ; SP, HTAB, "\" and DQUOTE
%d35-91 /
%d93-126 /
UTF8-xtra-char
2 quoted-pair = "\" text
2 quoted-string = [CFWS] DQUOTE
*( [FWS] qcontent ) [FWS]
DQUOTE [CFWS]
2 specials = "(" / ")" / ; Special characters used in
"<" / ">" / ; other parts of the syntax
"[" / "]" /
":" / ";" /
"@" / "\" /
"," / "." /
DQUOTE
strict-qcontent = strict-qtext / strict-quoted-pair
strict-quoted-pair = "\" strict-text
strict-quoted-string
= [CFWS] DQUOTE
*( [FWS] strict-qcontent ) [FWS]
DQUOTE [CFWS]
strict-qtext = NO-WS-CTL / ; qtext restricted to
%d33 / ; US-ASCII
%d35-91 /
%d93-126
strict-text = %d1-9 / ; text restricted to
%d11-12 / ; US-ASCII
%d14-127
2* text = %d1-9 / ; all UTF-8 characters except
%d11-12 / ; US-ASCII NUL, CR and LF
%d14-127 /
UTF8-xtra-char
5 tspecials = "(" / ")" / "<" / ">" / "@" /
"," / ";" / ":" / "\" / DQUOTE /
"/" / "[" / "]" / "?" / "="
2* utext = NO-WS-CTL / ; Non white space controls
%d33-126 / ; The rest of US-ASCII
UTF8-xtra-char
2 word = atom / quoted-string
Appendix B.2 - Basic Forms
2 addr-spec = local-part "@" domain
2 address = mailbox / group
2 address-list = address *( "," address )
2 angle-addr = [CFWS] "<" addr-spec ">" [CFWS]
article = 1*( header CRLF ) separator body
5* attribute = [CFWS] token [CFWS]
body = *( *998text CRLF )
2 display-name = phrase
2 date = day month year
2 date-time = [ day-of-week "," ] date FWS time [CFWS]
2 day = [FWS] 1*2DIGIT
2 day-name = "Mon" / "Tue" / "Wed" / "Thu" /
"Fri" / "Sat" / "Sun"
2 day-of-week = [FWS] day-name
2 domain = dot-atom / domain-literal
2 domain-literal = [CFWS] "[" *([FWS] dcontent) [FWS] "]" [CFWS]
2 group = display-name ":" [ mailbox-list / CFWS ] ";"
[CFWS]
header-name = 1*name-character *( "-" 1*name-character )
2 hour = 2DIGIT
2* local-part = dot-atom / strict-quoted-string
2 mailbox = name-addr / addr-spec
2 mailbox-list = mailbox *( "," mailbox )
2 minute = 2DIGIT
2 month = FWS month-name FWS
2 month-name = "Jan" / "Feb" / "Mar" / "Apr" /
"May" / "Jun" / "Jul" / "Aug" /
"Sep" / "Oct" / "Nov" / "Dec"
2 name-addr = [display-name] angle-addr
name-character = ALPHA / DIGIT
other-header = header-name ":" 1*SP other-content
other-content
= <the content of a header defined by some
other standard>
other-parameter
= <a parameter not defined by this standard>
5 parameter = attribute "=" value
2 second = 2DIGIT
separator = CRLF
2 time = time-of-day FWS zone
2 time-of-day = hour ":" minute [ ":" second ]
5 token = 1*<any (US-ASCII) CHAR except SP, CTLs,
or tspecials>
5 value = [CFWS] token [CFWS] / quoted-string
5* x-token = "x-" token
2 year = 4*DIGIT
2* zone = (( "+" / "-" ) 4DIGIT) / "UT" / "GMT"
Appendix B.3 - Headers
Appendix B.3.1 - Header outlines
header = other-header /
Date-header /
From-header /
Message-ID-header /
Subject-header /
Newsgroups-header /
Path-header /
Reply-To-header /
Sender-header /
Organization-header /
Keywords-header /
Summary-header /
Distribution-header /
Followup-To-header /
Mail-Copies-To-header /
Posted-And-Mailed-header /
References-header /
Expires-header /
Archive-header /
Control-header /
Approved-header /
Supersedes-header /
Xref-header /
Lines-header /
User-Agent-header /
Injector-Info-header /
Complaints-To-header
Approved-content = From-content
Approved-header = "Approved" ":" SP Approved-content
*( ";" other-parameter )
Archive-content = [CFWS] ("no" / "yes" ) [CFWS]
Archive-header = "Archive" ":" SP Archive-content
*( ";" ( Archive-parameter /
other-parameter ) )
Archive-parameter = <a parameter with attribute "filename"
and any value>
Complaints-To-content= address-list
Complaints-To-header = "Complaints-To" ":" SP Complaints-To-content
*( ";" other-parameter )
Control-content = [CFWS] control-message [CFWS]
Control-header = "Control" ":" SP Control-content
*( ";" other-parameter )
Date-content = date-time
Date-header = "Date" ":" SP Date-content
*( ";" other-parameter )
Distribution-content = distribution *( dist-delim distribution )
Distribution-header = "Distribution" ":" SP Distribution-content
*( ";" other-parameter )
Expires-content = date-time
Expires-header = "Expires" ":" SP Expires-content
*( ";" other-parameter )
Followup-To-content = Newsgroups-content / [FWS] "poster" [FWS]
Followup-To-header = "Followup-To" ":" SP Followup-To-content
*( ";" other-parameter )
From-content = mailbox-list
From-header = "From" ":" SP From-content
*( ";" other-parameter )
Injector-Info-content= [CFWS] path-identity [CFWS]
Injector-Info-header = "Injector-Info" ":" SP Injector-Info-content
*( ";" ( Injector-Info-parameter /
other-parameter ) )
Injector-Info-parameter
= posting-host-parameter /
posting-account-parameter /
posting-sender-parameter /
posting-logging-parameter /
posting-date-parameter
Keywords-content = phrase *( "," phrase )
Keywords-header = "Keywords" ":" SP Keywords-content
*( ";" other-parameter )
Lines-content = [CFWS] 1*DIGIT [CFWS]
Lines-header = "Lines" ":" SP Lines-content
*( ";" other-parameter )
Mail-Copies-To-content
= copy-addr / [CFWS] ( "nobody" /
"poster" ) [CFWS]
Mail-Copies-To-header= "Mail-Copies-To" ":" SP Mail-Copies-To-content
*( ";" other-parameter )
Message-ID-content = msg-id
Message-ID-header = "Message-ID" ":" SP Message-ID-content
*( ";" other-parameter )
Newsgroups-content = [FWS] newsgroup-name
*( [FWS] ng-delim [FWS] newsgroup-name )
[FWS]
Newsgroups-header = "Newsgroups" ":" SP Newsgroups-content
*( ";" other-parameter )
Organization-content = 1*( [FWS] utext )
Organization-header = "Organization" ":" SP Organization-content
Path-content = [FWS] *( path-identity [FWS]
path-delimiter [FWS]
) tail-entry [FWS]
Path-header = "Path" ":" SP Path-content
*( ";" other-parameter )
Posted-And-Mailed-content
= [CFWS] ( "yes" / "no" ) [CFWS]
Posted-And-Mailed-header
= "Posted-And-Mailed" ":" SP
Posted-And-Mailed-content
*( ";" other-parameter )
References-content = msg-id *( CFWS msg-id )
References-header = "References" ":" SP References-content
*( ";" other-parameter )
Reply-To-content = address-list
Reply-To-header = "Reply-To" ":" SP Reply-To-content
*( ";" other-parameter )
Sender-content = mailbox
Sender-header = "Sender" ":" SP Sender-content
*( ";" other-parameter )
Subject-content = [ [FWS] back-reference ] pure-subject
Subject-header = "Subject" ":" SP Subject-content
Summary-content = 1*( [FWS] utext )
Summary-header = "Summary" ":" SP Summary-content
Supersedes-content = msg-id
Supersedes-header = "Supersedes" ":" SP Supersedes-content
*( ";" other-parameter )
User-Agent-content = product-token *( CFWS product-token )
User-Agent-header = "User-Agent" ":" SP User-Agent-content
*( ";" other-parameter )
Xref-content = [CFWS] server-name 1*( CFWS location ) [CFWS]
Xref-header = "Xref" ":" SP Xref-content
*( ";" other-parameter )
Appendix B.3.2 - Control-message outlines
control-message = <empty> /
Newgroup-message /
Rmgroup-message /
Mvgroup-message /
Checkgroup-message /
Cancel-message /
Ihave-message /
Sendme-message
Cancel-arguments = CFWS msg-id
Cancel-message = "cancel" Cancel-arguments
Checkgroup-arguments = [ chkscope ] [ chksernr ]
Checkgroup-message = "checkgroups" Checkgroup-arguments
Ihave-arguments = relayer-name
Ihave-message = "ihave" Ihave-arguments
Mvgroup-arguments = CFWS newsgroup-name CFWS newsgroup-name
[ CFWS newgroup-flag ]
Mvgroup-message = "mvgroup" Mvgroup-arguments
Newgroup-arguments = CFWS newsgroup-name [ CFWS newgroup-flag ]
Newgroup-message = "newgroup" Newgroup-arguments
Rmgroup-arguments = CFWS newsgroup-name
Rmgroup-message = "rmgroup" Rmgroup-arguments
Sendme-arguments = Ihave-arguments
Sendme-message = "sendme" Sendme-arguments
Appendix B.3.3 - Other header rules
article-locator = 1*( %x21-27 / %x29-3A / %x3C-7E )
; US-ASCII printable characters
; except'(' and ';'
article-size = 1*DIGIT
back-reference = %x52.65.3A.20
; which is a case-sensitive "Re: "
batch = 1*( batch-header article )
batch-header = "#!" SP rnews SP article-size CRLF
checkgroups-body = *( valid-group CRLF )
chkscope = 1*( CFWS ["!"] newsgroup-name )
chksernr = CFWS "#" 1*DIGIT
combiner-ASCII = DIGIT / ALPHA / "+" / "-" / "_"
combiner-base = combiner-ASCII / combiner-extended
combiner-extended = <any character with a Unicode code value of
0080 or greater and a combining class of 0,
but excluding any character in Unicode
categories Cc, Cf, Cs, Zs, Zl, and Zp>
combiner-mark = <any character with a Unicode code value of
0080 or greater and a combining class other
than 0>
component = 1*component-glyph
component-glyph = combiner-base *combiner-mark
copy-addr = address-list
dist-delim = ","
distribution = [FWS] distribution-name [FWS]
distribution-name = ALPHA 1*distribution-rest
distribution-rest = ALPHA / "+" / "-" / "_"
groupinfo-body = [ newsgroups-tag CRLF ]
newsgroups-line CRLF
3 hex4 = 1*4HEXDIG
3 hexpart = hexseq / hexseq "::" [ hexseq ] /
"::" [ hexseq ]
3 hexseq = hex4 *( ":" hex4)
host-value = dot-atom /
[ dot-atom ":" ]
( IPv4address / IPv6address )
; see [RFC 2373]
2 id-left = dot-atom-text / no-fold-quote
2 id-right = dot-atom-text / no-fold-literal
ihave-body = *( msg-id CRLF )
3 IPv4address = 1*3DIGIT "." 1*3DIGIT "."
1*3DIGIT "." 1*3DIGIT
3 IPv6address = hexpart [ ":" IPv4address ]
location = newsgroup-name ":" article-locator
moderation-flag = %x28.4D.6F.64.65.72.61.74.65.64.29
; case sensitive "(Moderated)"
2 msg-id = [CFWS] "<" id-left "@" id-right ">" [CFWS]
newgroup-flag = "moderated"
newsgroup-description
= utext *( *WSP utext )
newsgroup-name = component *( "." component )
newsgroups-line = newsgroup-name
[ 1*HTAB newsgroup-description ]
[ 1*WSP moderation-flag ]
newsgroups-tag = %x46.6F.72 SP %x79.6F.75.72 SP
%x6E.65.77.73.67.72.6F.75.70.73 SP
%x66.69.6C.65.3A
; case sensitive
; "For your newsgroups file:"
ng-delim = ","
2* no-fold-literal = "[" *( dtext / "\[" / "\]" / "\\" ) "]"
2* no-fold-quote = DQUOTE
*( strict-qtext / "\\" / "\" DQUOTE )
qspecial
*( strict-qtext / "\\" / "\" DQUOTE )
DQUOTE
path-delimiter = "/" / "?" / "%" / "," / "!"
path-identity = ( ALPHA / DIGIT )
*( ALPHA / DIGIT / "-" / "." / ":" / "_" )
posting-account-parameter
= <a parameter with attribute "posting-account"
and any value>
posting-date-parameter
= <a parameter with attribute "posting-date"
and value some date-time>
posting-host-parameter
= <a parameter with attribute "posting-host"
and value some host-value>
posting-logging-parameter
= <a parameter with attribute "logging-data"
and any value>
posting-sender-parameter
= <a parameter with attribute "sender"
and value some sender-value>
product-token = value [ "/" product-version ]
product-version = value
pure-subject = 1*( [FWS] utext )
qspecial = "(" / ")" / ; same as specials except
"<" / ">" / ; "\" and DQUOTE quoted
"[" / "]" /
":" / ";" /
"@" / "\\" /
"," / "." /
"\" DQUOTE
relayer-name = path-identity
rnews = %x72.6E.65.77.73 ; case sensitive "rnews"
sender-value = mailbox / "verified"
sendme-body = ihave-body
server-name = path-identity
tail-entry = 1*( ALPHA / DIGIT / "-" / "." / ":" / "_" )
valid-group = newsgroups-line
Charles H. Lindsey ---------At Home, doing my own thing------------------------
Tel: +44 161 436 6131 Fax: +44 161 436 6133 Web: http://www.cs.man.ac.uk/~chl
Email: chl@clw.cs.man.ac.uk Snail: 5 Clerewood Ave, CHEADLE, SK8 3JU, U.K.
PGP: 2C15F1A9 Fingerprint: 73 6D C2 51 93 A0 01 E7 65 E8 64 7E 14 A4 AB A5