public void TestArgumentExceptions() { var iter = new MimeIterator(new MimeMessage { Body = new TextPart("plain") }); Assert.Throws <ArgumentNullException> (() => new MimeIterator(null)); Assert.Throws <InvalidOperationException> (() => { var x = iter.Depth; }); Assert.Throws <InvalidOperationException> (() => { var x = iter.Current; }); Assert.Throws <InvalidOperationException> (() => { var x = iter.Parent; }); Assert.Throws <InvalidOperationException> (() => { var x = iter.PathSpecifier; }); Assert.Throws <ArgumentNullException> (() => iter.MoveTo(null)); Assert.Throws <ArgumentException> (() => iter.MoveTo(string.Empty)); Assert.Throws <FormatException> (() => iter.MoveTo("xyz")); }
public void TestMoveTo() { var expectedTypes = new Type[] { typeof(Multipart), typeof(TextPart), typeof(MimePart), typeof(MessagePart), typeof(Multipart), typeof(TextPart), typeof(MimePart), typeof(Multipart), typeof(MimePart), typeof(MessagePart), typeof(Multipart), typeof(TextPart), typeof(MultipartAlternative), typeof(TextPart), typeof(TextPart) }; var expectedPathSpecifiers = new List <string> { "0", "1", "2", "3", "3.0", "3.1", "3.2", "4", "4.1", "4.2", "4.2.0", "4.2.1", "4.2.2", "4.2.2.1", "4.2.2.2" }; var paths = new string[] { "3.1", "3.2", "4", "4.2.1", "4.2.2.2", "4.2", "3.2" }; var expectedDepths = new int[] { 0, 1, 1, 1, 2, 3, 3, 1, 2, 2, 3, 4, 4, 5, 5 }; var expectedParents = new List <MimeEntity> { null }; var message = CreateImapExampleMessage(expectedParents); var iter = new MimeIterator(message); foreach (var path in paths) { int i = expectedPathSpecifiers.IndexOf(path); Assert.IsTrue(iter.MoveTo(expectedPathSpecifiers[i]), "MoveTo {0}", expectedPathSpecifiers[i]); Assert.AreEqual(expectedPathSpecifiers[i], iter.PathSpecifier, "PathSpecifier {0}", expectedPathSpecifiers[i]); Assert.AreEqual(expectedParents[i], iter.Parent, "Parent {0}", expectedPathSpecifiers[i]); Assert.IsInstanceOf(expectedTypes[i], iter.Current, "Type {0}", expectedPathSpecifiers[i]); Assert.AreEqual(expectedDepths[i], iter.Depth, "Depth {0}", expectedPathSpecifiers[i]); } }
public static void ExtractMainParts(this MailMessageData mail, MimeMessage message) { var htmlStream = new MemoryStream(); var textStream = new MemoryStream(); Action <MimeEntity> loadRealAttachment = (part) => { if ((part.ContentDisposition != null && !string.IsNullOrEmpty(part.ContentDisposition.FileName)) || part.ContentType != null && !string.IsNullOrEmpty(part.ContentType.Name)) { mail.LoadAttachments(new List <MimeEntity> { part }); } }; Action <MimePart> setBodyOrAttachment = (part) => { var entity = part as TextPart; if (htmlStream == null || textStream == null) { throw new Exception("Streams are not initialized"); } if ((entity == null || htmlStream.Length != 0 && entity.IsHtml || textStream.Length != 0 && !entity.IsHtml)) { loadRealAttachment(part); } else { if (mail.Introduction.Length < 200 && (!entity.IsHtml && !string.IsNullOrEmpty(entity.Text))) { if (string.IsNullOrEmpty(mail.Introduction)) { mail.Introduction = (entity.Text.Length > 200 ? entity.Text.Substring(0, 200) : entity.Text); } else { var need = 200 - mail.Introduction.Length; mail.Introduction += (entity.Text.Length > need ? entity.Text.Substring(0, need) : entity.Text); } mail.Introduction = mail.Introduction.Replace("\r\n", " ").Replace("\n", " ").Trim(); } var body = ConvertToHtml(entity); if (entity.IsHtml) { using (var sw = new StreamWriter(htmlStream, Encoding.UTF8, 1024, true)) { sw.Write(body); sw.Flush(); htmlStream.Seek(0, SeekOrigin.Begin); } } else { using (var sw = new StreamWriter(textStream, Encoding.UTF8, 1024, true)) { sw.Write(body); sw.Flush(); textStream.Seek(0, SeekOrigin.Begin); } } } }; var newPathIndex = ""; using (var sw = new StreamWriter(mail.HtmlBodyStream, Encoding.UTF8, 1024, true)) { using (var iter = new MimeIterator(message)) { while (string.IsNullOrEmpty(newPathIndex) ? iter.MoveNext() : iter.MoveTo(newPathIndex)) { if (!string.IsNullOrEmpty(newPathIndex)) { newPathIndex = ""; } var multipart = iter.Parent as Multipart; var part = iter.Current as MimePart; var subMessage = iter.Current as MessagePart; if (subMessage != null) { if ((subMessage.ContentDisposition != null && !string.IsNullOrEmpty(subMessage.ContentDisposition.FileName)) || subMessage.ContentType != null && !string.IsNullOrEmpty(subMessage.ContentType.Name)) { mail.LoadAttachments(new List <MimeEntity> { subMessage }, true); } else { subMessage.ContentDisposition = new ContentDisposition { Disposition = ContentDisposition.Attachment, FileName = "message.eml" }; mail.LoadAttachments(new List <MimeEntity> { subMessage }, true); } float pathIndex; if (float.TryParse(iter.PathSpecifier, out pathIndex)) { pathIndex++; newPathIndex = ((int)pathIndex).ToString(); continue; } } if (part == null || iter.Parent is MessagePart) { continue; } if (part.IsAttachment) { if (part is TnefPart) { var tnefPart = iter.Current as TnefPart; if (tnefPart != null) { mail.LoadAttachments(tnefPart.ExtractAttachments(), true); } } else { mail.LoadAttachments(new List <MimeEntity> { part }, multipart == null || !multipart.ContentType.MimeType.ToLowerInvariant().Equals("multipart/related")); } } else if (multipart != null) { switch (multipart.ContentType.MimeType.ToLowerInvariant()) { case "multipart/report": if (part is TextPart) { var entity = part as TextPart; if (entity == null) { entity = new TextPart(TextFormat.Plain); entity.SetText(Encoding.UTF8, part.ToString()); } var body = ConvertToHtml(entity); if (mail.HtmlBodyStream.Length == 0) { sw.Write(body); } else { sw.Write("<hr /><br/>"); sw.Write(body); } sw.Flush(); } else if (part is MessageDeliveryStatus) { var entity = new TextPart(TextFormat.Plain); var mds = (MessageDeliveryStatus)part; using (var memory = new MemoryStream()) { mds.Content.DecodeTo(memory); var text = Encoding.ASCII.GetString(memory.GetBuffer(), 0, (int)memory.Length) .Replace("\r\n", "\n"); entity.SetText(Encoding.UTF8, text); } var body = ConvertToHtml(entity); if (mail.HtmlBodyStream.Length == 0) { sw.Write(body); } else { sw.Write("<hr /><br/>"); sw.Write(body); } sw.Flush(); } else { loadRealAttachment(part); } break; case "multipart/mixed": if (part is TextPart) { var entity = part as TextPart; var body = ConvertToHtml(entity); if (mail.HtmlBodyStream.Length == 0) { sw.Write(body); } else { sw.Write("<hr /><br/>"); sw.Write(body); } sw.Flush(); } else { if (part.ContentType != null && part.ContentType.MediaType.Equals("image", StringComparison.InvariantCultureIgnoreCase) && part.ContentDisposition != null && part.ContentDisposition.Disposition.Equals(ContentDisposition.Inline, StringComparison.InvariantCultureIgnoreCase)) { if (string.IsNullOrEmpty(part.ContentId)) { part.ContentId = Guid.NewGuid().ToString("N").ToLower(); } mail.LoadAttachments(new List <MimeEntity> { part }); sw.Write("<hr /><br/>"); sw.Write("<img src=\"cid:{0}\">", part.ContentId); sw.Flush(); } else { loadRealAttachment(part); } } break; case "multipart/alternative": if (part is TextPart) { setBodyOrAttachment(part); } else { loadRealAttachment(part); } break; case "multipart/related": if (part is TextPart) { setBodyOrAttachment(part); } else if (!string.IsNullOrEmpty(part.ContentId) || part.ContentLocation != null) { mail.LoadAttachments(new List <MimeEntity> { part }); } else { loadRealAttachment(part); } break; default: if (part is TextPart) { setBodyOrAttachment(part); } else { loadRealAttachment(part); } break; } } else { if (part is TextPart) { setBodyOrAttachment(part); } else { loadRealAttachment(part); } } } } if (htmlStream.Length != 0) { if (mail.HtmlBodyStream.Length > 0) { sw.Write("<hr /><br/>"); sw.Flush(); } htmlStream.CopyTo(sw.BaseStream); } else if (textStream.Length != 0) { if (mail.HtmlBodyStream.Length == 0) { mail.TextBodyOnly = true; } else { sw.Write("<hr /><br/>"); sw.Flush(); } textStream.CopyTo(sw.BaseStream); } htmlStream.Dispose(); textStream.Dispose(); } if (mail.HtmlBodyStream.Length != 0) { return; } mail.HtmlBody = "<body><pre> </pre></body>"; mail.Introduction = ""; mail.TextBodyOnly = true; }