[Top] [All Lists]

Re: Comments on draft-daboo-sieve-mime-00.txt

2004-03-16 20:19:51

I've spent quite a lot of time thinking about this particular extension too
and can't wait to implement it, but have never really felt comfortable with a
set of syntax, and don't feel comfortable with any of the proposals so far; so
here's another to throw into the pool for thought:

I like this proposal. But this is hardly surprising, since it differs only
slightly from some of the alternatives I proposed.

I think MIME consists of two significant parts here; there's a set of new
headers, and then there's the facility for multiple body parts.  Looking at 
list of new headers, most of them seem to fit neatly into our existing tests
(Mime-Version, Content-Id, etc), however the only one that has additional
significant structure is the Content-Type header, which is defined as:

     content := "Content-Type" ":" type "/" subtype
                *(";" parameter)
                ; Matching of media type and subtype
                ; is ALWAYS case-insensitive.

Then looking more generically we've also got:

     disposition := "Content-Disposition" ":"
                    *(";" disposition-parm)

And there's probably others.  So we have this syntax.

     mime-header := header-name ":"
                    *(";" param-name "=" param-value)

So lets provide a tagged argument to the header, exists, address tests that
parses out this structure and allows us to select exactly which bits we want
to test against:

I think this particular extension only belongs on header.

             <header-names: string-list> <key-list: string-list>

    HEADER-PART: ":value" / ":parameter" <param-names: string-list>

:parameter is fine but there's a problem with :value - it is already
defined in a different way by RFC 3431. How about :type instead?

- If we specify ":value" as the optional header-part parameter, then the test
only operates on the header-value.

- If we specify the :parameter optional header-part parameter, then the
string list describes the list of parameter values that we should search in.

Both of these sound good.

- If neither optional parameter is specified, the header test operates on the
entire header value as normal.

Has to be this way for backwards compatibility.

- Other HEADER-PARTS could be defined in the future if we have other headers
with a different defined structure.

Right, but it also seems reasonable that if future attr=value sorts of headers
are defined it will be done with a similar syntax to the ones that already
exist and that the same tests can be brought to bear on them.

If we think :value is too confusing for the "header value when with
parameters" compared to the "whole header value", then perhaps we could use
:valueonly, :noparameters or :mimevalue or something else?

I like :type. It matches up well with "type of disposition" and "media type".

Maybe the prefix
could be like a "namespace" defining the header parsing algorithm to use, and
if we have other headers that have a common structure, we could define other
namespaces that detail the header parsing method to use.

I think this probably goes too far.

The above would test only in the "active body part" which is the top level
body part, which is the email headers, which is what we've all been dealing
with already.  It would NOT recursively look for headers in all child body
parts.  That would be done with the second half of my proposal.  Where a 
doesn't have a mime parser, or was worried about the extra overhead of parsing
the mime structure, it wouldn't support this second part, but could still
support Header-Parts.

The notion of two separate extension is interesting. I personally have no need
to make the distinction, but I have no problem with the split if others
think it is useful.

The second significant half of MIME permits us to recursively define body
parts, which each have a set of headers, and content.  So any solution that we
have needs to cope with the potential recursive nature of the MIME structure. 
So what if we define a new tagged argument for use with all of our existing
tests that specifies that we should recursively look in the body parts too? 
Call it :bodyparts.  So this means that if I write a test that says:

    if header :contains "Content-Type" "text/html"

Then this would only match if the message contains a single body part that is
text/html.  However if I write the following, then this would match if there 
ANY text/html body part anywhere in the legal MIME structure of the message:

    if header :bodyparts :contains "Content-Type" "text/html"

Modulo the name of the parameter (which I don't particularly care about)
this is one of the alternatives I proposed.

With our new mimeheader test this would become more correctly:

    if header :bodyparts :value :contains "Content-Type" "text/html"

Then if we combine this with allof(), we could further define that multiple 
tests within an allof() must apply to the same body part.  So if we say:

    if allof :bodyparts (header :value :contains "Content-Type" "image/jpeg",
                                  size :over 100K)

Then this would catch all messages that contain a image/jpeg body part that 
is over 100K.  However if we say the following, then this would catch any 
message that contained a body part that was image/jpeg and a body part 
(potentially different) which was over 100K in size.:

    if allof (header :bodyparts :value :contains "Content-Type" "image/jpeg",
                size :bodyparts :over 100K)

This then very neatly fits with the body extention, and we get a test like 
this which would test for all messages that contain a text body part that 
contains the word "Spam":

    if allof :bodyparts (header :value :contains "Content-Type" "text",
                                  body :contains "Spam")

For more examples, I'll go through Cyrus examples and show how they would
look for this proposal.  However before I do, I note that many look for an "in
any header value" or an "in any parameter value" concept.  We currently 
found a need for these, and I'm not sure we need them.  If we do, then I'd
propose we have new tests like "anyheader", "anyexists" and a new header-part
of ":anyparameter".

This all sounds reasonable, but as you say, let's wait for the demand before
we add it.