Handling Emails with Unusual or Unconventional MIME Structure
In rare cases, an email’s MIME might be structured in a way that is highly unusual and doesn’t follow conventions. In other words, the nested MIME structure of an email should follow conventions that make it possible to semantically understand the purpose of each MIME part — such as an attachment, or an image to be included in the HTML body, or a signature, etc.For example, the defacto standard MIME structure for an email containing one attachment (which happens to be a .zip archive), and both plain-text and HTML alternative bodies, and a single JPG image reference from the HTML, is this:
multipart/mixed multipart/alternative text/plain multipart/related text/html image/jpeg application/zipYou can examine the MIME structure of any email less than 5MB in size by using Chilkat’s online tool at Examine MIME Structure.
If an email’s MIME structure is highly unusual, then it’s likely necessary to use the Chilkat.Mime class for processing. Chilkat MIME provides a lower-level API for MIME. For example, Chilkat recently encountered some emails with the following MIME structures:
multipart/mixed multipart/signed multipart/mixed multipart/alternative text/plain text/html message/rfc822 application/pkcs7-signature multipart/alternative text/plain text/html
and
multipart/mixed multipart/signed multipart/mixed multipart/alternative text/plain text/html application/pdf application/pdf application/pkcs7-signature multipart/alternative text/plain text/html
To process more arbitrary MIME such as the above, one could write a recursive function such as this one in C#:
private void recursivelyTraverseMime(Chilkat.Mime mime)
{
// If this MIME part is multipart, then recursively process the sub-parts.
if (mime.NumParts > 0)
{
for (int i = 0; i < mime.NumParts; i++)
{
recursivelyTraverseMime(mime.GetPart(i));
}
return;
}
// If we get here, then this part is not multipart..
// Process according to the Content-Type and/or Disposition
textBox1.AppendText(mime.ContentType + ", Disposition = " + mime.Disposition + "\r\n");
if (mime.ContentType.Equals("message/rfc822"))
{
// This MIME sub-part's body contains another MIME message..
Chilkat.Mime mime2 = new Chilkat.Mime();
Chilkat.BinData bd = new Chilkat.BinData();
// Get the body of this sub-part and load it into mime2.
mime.GetBodyBd(bd);
if (mime2.LoadMimeBd(bd))
{
recursivelyTraverseMime(mime2);
}
}
else if (mime.Disposition.Equals("attachment"))
{
// Semantically, this is intended to be an attachment...
// Perhaps you wish to get the content of the attachment..
if (mime.ContentType.StartsWith("text/"))
{
string text = mime.GetBodyDecoded();
}
else
{
byte[] data = mime.GetBodyBinary();
}
}
else if (mime.ContentType.Equals("text/plain"))
{
// This is a plain-text email body.
string plainTextBody = mime.GetBodyDecoded();
}
else if (mime.ContentType.Equals("text/html"))
{
// This is an HTML email body.
string htmlBody = mime.GetBodyDecoded();
}
// Continue with other ContentType's you wish to handle...
}
private void recursiveTraverseToolStripMenuItem_Click(object sender, EventArgs e)
{
Chilkat.Mime mime = new Chilkat.Mime();
if (!mime.LoadMimeFile("c:/aaworkarea/samples/testV0.eml"))
{
MessageBox.Show("Failed to load MIME file.");
return;
}
recursivelyTraverseMime(mime);
}
admin
0
Tags :