Download Reference Manual
The Developer's Library for D
About Wiki Forums Source Search Contact

Mime Design

This page is intended to help with the design of a generic Mime module in order to replace the similar offerings in net.http, as well as add support for email.

Goals

  • Generic Mime module supports for the following rfcs: 2045, 2046, 2047, 2822
  • Fast (as not to impact performance with existing HttpMessage? and friends)
  • Support for 2047 decoding, unfolding, base64, quoted-printable

Solution/Design

Mime Headers

There's basically two methods of access that are required:

  1. Easy access to a header value: headers["content-type"].value would be an example.
  2. Easily access the order of, remove, and add headers (again with respect to order),
module tango.net.Mime;

class Headers
{
   class Header
   {
      char[] name();                          // name of header
      char[] raw();                           // raw un-encoded value of header
      char[] decoded();                       // unfolded, 2047 decoded value of header
      Header opIndex(uint index);             // access header by index of this header name (ie: received[3].raw)
      Header add(char[] name, char[] value)   // append new header after this header (encode on write)
      void remove();                          // remove this header
   }

   this(Conduit);                         // parse from conduit
   uint length();                         // number of headers
   Header opIndex(char[] key);            // access header by name (ie: headers["content-type"].raw)
   Header opIndex(uint key);              // access header by index (ie: headers[0].raw)
   Header add(char[] name, char[] value); // append a new header with name/value (auto-encode on write)
}

Mime Body

There are a few things required for this module:

  1. Be able to modify the mime message (remove/add/modify parts)
  2. Be able to support base64 and quoted-printable encodings
  3. Be able to save modified messages to a conduit

Basic outline:

class Body
{
    this(Conduit);                // Parse from Conduit
    Headers header;               // Part headers
    Body[] children;              // Children Parts
    char[] raw;                   // raw data
    char[] decoded;               // data decoded from base64/quoted-printable
}

Discussion

Comments
Author Message

Posted: 03/06/08 06:26:03 -- Modified: 03/06/08 06:26:58 by
darrylb

Because there seems to be a lack of replies here, let me see if I can't stir up some conversation.

This design was a result of a conversation with Nietsnie and myself. What I was thinking, was that there are two things you are going to want to do with a MIME header:

-Get the values for a particular header, in their presentation order, regardless of whether there were any intervening headers in the source.

-Iterate through all the keys and values for all MIME pairs, with positioning and ordering mattering.

In either of those cases, you may also want to add/remove pairs/keys/values at any point.

The first would be handled via the character string index:

headers['subject'][0]

The second via the integer indexing:

headers[0][0]

Hopefully that makes some sense to the reader, and comments on any other types of desired use can be put here. :)