Version 16 of mime

Updated 2006-12-02 09:52:05

http://tcllib.sourceforge.net/doc/mime.html

 package require mime  ;# http://purl.org/tcl/home/software/tcllib/

Based upon the Tcl MIME package from Marshall T. Rose. See http://www.purl.org/NET/akupries/soft/mail/ for the original.

The original has a hard dependency upon Trf. The variant in Tcllib converts that into a soft dependency. In other words, it tries to use Trf to gain performance but will fall back to pure tcl if that package is not present.


Can we delete the following warning? We are waaaay beyond tcllib1.2!

WARNING

RED ALERT

There are very serious performance issues with the current (tcllib1.2) version of ::mime, to quote from this

[L1 ] thread by Cameron Laird, Jeff Hobbs, Frank Pilhofer and others

        Typical results:
             100 (654):  12207 microseconds per iteration
             1000 (1554):  28418 microseconds per iteration
             10000 (10554):  682226 microseconds per iteration
             100000 (100557):  57002148 microseconds per iteration       

        Interpretation:  a modest item of barely over 100,000 bytes
             requires 57 seconds (!) to parse.  By the time we get
             to the multi-megabyte traffic typical for my customers
             ... well, it's an ugly sight.

In short: it's completely useless for 1 MByte+ multipart messages PS.


LV Anyone have some examples of using this package to parse a mail message in a file? Answer: that's the mission of "Reading messages that might be MIME-encoded".


Andreas Kupries: One issue with performance (splitting a large string at each character created thousands of Tcl_Obj's containing all the same character, gobbling up memory like mad) was solved for Tcl 8.4a3, by Donal Fellows.

Note that this performance improvement was also one of the Changes in Tcl/Tk 8.3.3.


Things to explain: performance issues (large messages: headers, split, buffering); package (including fix-up); examples; exception-(mis)handling; magic arrays; ...

CL has found two principal difficulties in trying to use mime with 8.0 or early 8.1: the "format %c ..." change (explain) and the incompatibility in interpretation of "\n" vs. {\n} to regsub (explain).


One of the difficulties in explaining mime is its flexibility. It can do many, many things, and it's hard to know where to begin explaining it. In a case like this, I like a few examples--feel free to think of them as a cookbook of recipes for starting points. How, for instance, can you use Tcl to automate emission of a message which includes an attachment?


One definite fault of 0.8 is that it only reports some of the filenames of attachments it detects (explain Content-Disposition alternative). CL has code that repairs this, but has yet to check it in.


The distribution documentation deserves many more examples. Until CL makes the time to update it, we'll keep several of them here. Notice that individual mail items might well have originated as return values from the pop3 package.

    package require mime

    set item {From [email protected] Tue May 29 11:49:26 EDT 2001
    Date: Tue, 29 May 2001 11:03:02 -0500
    From: Cameron Laird <[email protected]>
    To: [email protected],[email protected]
    Subject: some subject
    Message-ID: <[email protected]>

    This is only a test.}

        # A production version deserves exception-handling.
    set token [mime::initialize -string $item]

    puts "The subject is '[mime::getheader $token Subject]'."

Address parsing is an area where many, MANY square wheels have been reinvented, in part because RFC 822 (and updates ... ) are so poorly understood. Here's an example of a correct usage:

        # Take $item from above.
    set token [mime::initialize -string $item]

    set to [mime::getheader $token To]
    puts "The (unparsed) recipients are '$to'."
    set parsed [mime::parseaddress $to]
    foreach element $parsed {
        array set array $element
        puts "One deliverable address is $array(address)."
    }  

This prints

    The (unparsed) recipients are '[email protected],[email protected]'.
    One deliverable address is [email protected].
    One deliverable address is [email protected].        




Here is an example and functional script for use by anybody [L2 ]. It is an SMTP email authenticator. It turns out that to authenticate a user in SMTP requires MIME format. The script will display a gui asking for the username, password, and server (port will always be 25, unless the programmer changes that or modifies the script for their own use). After receiving this information (and pressing the "Ok" button or <Return>) the script attempts to authenticate the user. Jeff Gosnell


JMN 2006-03-30 Actually the above statement re MIME & SMTP-AUTH is a little misleading. It's more correctly stated that SMTP-AUTH uses base64 encoding for the AUTH types LOGIN and PLAIN. You don't need a MIME package to do SMTP Authentication. In fact if you happen to have a message on disk that is already in MIME format - you still don't necessarily need a MIME package to submit it to an SMTP server. This might be the case for example when using TCL to pick up a maildrop file and forward it somewhere. The MIME package has some useful features such as mime::parseaddress that can help when handling mail - but if you care about memory consumption and performance don't run the whole message text through the MIME parser unnecessarily.


Background information on MIME is available [L3 ].


RFC822 items can be big, and correspondingly expensive to manipulate. tcllib's mime package parses any presented item completely. What if one only wants, say, the "Subject:" of the item, while needing performance? In principle, there ought to be a "lazy" evaluation that intelligently scans the few header lines necessary to determine this value.

A comp.lang.tcl thread [anyone have a reference here?] discusses this. One highlight is that Don Libes's "mail notification tools (i.e., biff)" page on tkbiff points to code which directly models such a requirement.


As this is noted nowhere, user mime::word_encode to encode your headers according to your needs. As an example we are using "set subject_encoded mime::word_encode "iso8859-1" base64 $subject to make sure the subject is encoded as well .

OpenACS has a complex_send procedure that makes use of a lot of the mime functionality. It is contained in [L4 ].


Category Package, subset tcllib