public static void ParseHeader(ref Header header) { string hdr = System.Text.Encoding.ASCII.GetString(header.OriginalData); hdr = System.Text.RegularExpressions.Regex.Match(hdr, @"[\s\S]+?((?=\r?\n\r?\n)|\Z)").Value; hdr = Parser.Unfold(hdr); hdr = Codec.RFC2047Decode(hdr); System.Text.RegularExpressions.Match m = System.Text.RegularExpressions.Regex.Match(hdr, @"(?<=((\r?\n)|\n)|\A)\S+:(.|(\r?\n[\t ]))+(?=((\r?\n)\S)|\Z)"); while(m.Success) { string name = FormatFieldName(m.Value.Substring(0, m.Value.IndexOf(':'))); string value = m.Value.Substring(m.Value.IndexOf(":") + 1); if (name.Equals("received")) header.Trace.Add(Parser.ParseTrace(m.Value.Trim(' '))); else if (name.Equals("to")) header.To = Parser.ParseAddresses(value); else if (name.Equals("cc")) header.Cc = Parser.ParseAddresses(value); else if (name.Equals("bcc")) header.Bcc = Parser.ParseAddresses(value); else if (name.Equals("reply-to")) header.ReplyTo = Parser.ParseAddress(value); else if (name.Equals("from")) header.From = Parser.ParseAddress(value); else if (name.Equals("sender")) header.Sender = Parser.ParseAddress(value); else if (name.Equals("content-type")) header.ContentType = Parser.GetContentType(m.Value); else if (name.Equals("content-disposition")) header.ContentDisposition = Parser.GetContentDisposition(m.Value); header.HeaderFields.Add(name, value); header.HeaderFieldNames.Add(name, m.Value.Substring(0, m.Value.IndexOf(':'))); m = m.NextMatch(); } }
/// <summary> /// Parses the header. /// </summary> /// <param name="header">The header.</param> public static void ParseHeader(ref Header header) { #if !PocketPC string hdr = System.Text.Encoding.GetEncoding("iso-8859-1").GetString(header.OriginalData, 0, header.OriginalData.Length); #else string hdr = Pop3Client.PPCEncode.GetString(header.OriginalData, 0, header.OriginalData.Length); #endif hdr = System.Text.RegularExpressions.Regex.Match(hdr, @"[\s\S]+?((?=\r?\n\r?\n)|\Z)").Value; hdr = Parser.Unfold(hdr); //hdr = hdr); System.Text.RegularExpressions.Match m = System.Text.RegularExpressions.Regex.Match(hdr, @"(?<=((\r?\n)|\n)|\A)\S+:(.|(\r?\n[\t ]))+(?=((\r?\n)\S)|\Z)"); while (m.Success) { string name = FormatFieldName(m.Value.Substring(0, m.Value.IndexOf(':'))); string value = Codec.RFC2047Decode(m.Value.Substring(m.Value.IndexOf(":") + 1)).Trim('\r', '\n').TrimStart(' '); if (name.Equals("received")) { header.Trace.Add(Parser.ParseTrace(m.Value.Trim(' '))); } else if (name.Equals("to")) { header.To = Parser.ParseAddresses(value); } else if (name.Equals("cc")) { header.Cc = Parser.ParseAddresses(value); } else if (name.Equals("bcc")) { header.Bcc = Parser.ParseAddresses(value); } else if (name.Equals("reply-to")) { header.ReplyTo = Parser.ParseAddress(value); } else if (name.Equals("from")) { header.From = Parser.ParseAddress(value); } else if (name.Equals("sender")) { header.Sender = Parser.ParseAddress(value); } else if (name.Equals("content-type")) { header.ContentType = Parser.GetContentType(m.Value); } else if (name.Equals("content-disposition")) { header.ContentDisposition = Parser.GetContentDisposition(m.Value); } //else //{ header.HeaderFields.Add(name, value); header.HeaderFieldNames.Add(name, m.Value.Substring(0, m.Value.IndexOf(':'))); //} m = m.NextMatch(); if (HeaderFieldParsing != null) { HeaderFieldParsing(null, header); } } }
/// <summary> /// Parses the MIME part. /// </summary> /// <param name="data">The data.</param> /// <returns></returns> public static MimePart ParseMimePart(string data, Message message) { MimePart part = new MimePart(); part.ParentMessage = message; part.OriginalContent = data; try { // Separate header and body. int headerEnd = Regex.Match(data, @".(?=\r?\n\r?\n)").Index + 1; int bodyStart = Regex.Match(data, @"(?<=\r?\n\r?\n).").Index; //TODO: remove this workaround if (bodyStart == 0) { //bodyStart = data.IndexOf("\r\n\r\n"); // Fix for a bug - the bodyStart was -1 (Invalid), MCALADO: 04/07/2008 int indexBody = data.IndexOf("\r\n\r\n"); if (indexBody > 0) { bodyStart = indexBody; } } if (data.Length >= headerEnd) { string header = data.Substring(0, headerEnd); header = Parser.Unfold(header); //header = header); // The bodyStart need to be greather than data.length - MCALADO: 04/07/2008 string body = string.Empty; if (bodyStart < data.Length) { body = data.Substring(bodyStart); } // Store the (maybe still encoded) body. part.TextContent = body; // Parse header fields and their parameters. Match m = Regex.Match(header, @"(?<=((\r?\n)|\n)|\A)\S+:(.|(\r?\n[\t ]))+(?=((\r?\n)\S)|\Z)"); while (m.Success) { if (m.Value.ToLower().StartsWith("content-type:")) { part.ContentType = Parser.GetContentType(m.Value); } else if (m.Value.ToLower().StartsWith("content-disposition:")) { part.ContentDisposition = Parser.GetContentDisposition(m.Value); } part.HeaderFields.Add(FormatFieldName(m.Value.Substring(0, m.Value.IndexOf(':'))), Codec.RFC2047Decode(m.Value.Substring(m.Value.IndexOf(':') + 1).Trim(' ', '\r', '\n'))); part.HeaderFieldNames.Add(FormatFieldName(m.Value.Substring(0, m.Value.IndexOf(':'))), Codec.RFC2047Decode(m.Value.Substring(0, m.Value.IndexOf(':')).Trim(' ', '\r', '\n'))); m = m.NextMatch(); } // Build the part tree. // This is a container part. if (part.ContentType.Type.ToLower().Equals("multipart")) { Parser.ParseSubParts(ref part, message); } // This is a nested message. else if (part.ContentType.Type.ToLower().Equals("message")) { // TODO } // This is a leaf of the part tree // Check necessary for single part emails (fix from alex294 on CodePlex) // Why would we consider the body only to the first string? Doesn't make sense - and fails //else if (part.ContentType.Type.ToLower().Equals("text")) //{ // int BodyEnd = body.IndexOf(' '); // if (BodyEnd > 0) // { // part.TextContent = body.Substring(0, BodyEnd); // } //} DecodePartBody(ref part); try { BodyParsed(null, message); } catch (Exception) { // event is not supported. } } } catch (Exception ex) { throw new ParsingException(ex.Message); } return(part); }
public static MimeTypedAndEncodedContent ParseMimeTypedAndEncodedContent(string data) { MimeTypedAndEncodedContent part = new MimeTypedAndEncodedContent(); // Separate header and body. int headerEnd = Regex.Match(data, @".(?=\r?\n\r?\n)").Index + 1; int bodyStart = Regex.Match(data, @"(?<=\r?\n\r?\n).").Index - 1; string header = data.Substring(0,headerEnd); header = Parser.Unfold(header); header = Codec.RFC2047Decode(header); string body = data.Substring(bodyStart); // Parse header fields and their parameters. Match m = Regex.Match(header, @"(?<=((\r?\n)|\n)|\A)\S+:(.|(\r?\n[\t ]))+(?=((\r?\n)\S)|\Z)"); while (m.Success) { if (m.Value.ToLower().StartsWith("content-type:")) part.ContentType = Parser.GetContentType(m.Value); else if (m.Value.ToLower().StartsWith("content-disposition:")) part.ContentDisposition = Parser.GetContentDisposition(m.Value); part.HeaderFields.Add(FormatFieldName(m.Value.Substring(0, m.Value.IndexOf(':'))), m.Value.Substring(m.Value.IndexOf(':') + 1)); m = m.NextMatch(); } // Is it QP encoded text ? if (part.ContentTransferEncoding.Equals(ContentTransferEncoding.QuotedPrintable)) { // Get the destination charset, or default to us-ascii. string charset = "us-ascii"; if (part.Charset != null && part.Charset.Length > 0) charset = part.Charset; // Decode part.TextContent = Codec.FromQuotedPrintable(body, charset); //part.BinaryContent = System.Text.Encoding.GetEncoding(charset).GetBytes(part.TextContent); } // Is it a Base64 encoded content ? else if (part.ContentTransferEncoding.Equals(ContentTransferEncoding.Base64)) { part.TextContent = body; //part.BinaryContent = Convert.FromBase64String(part.TextContent); } // Is it plain text or binary data ? else //if (part.ContentTransferEncoding.Equals(ContentTransferEncoding.SevenBits) || part.ContentTransferEncoding.Equals(ContentTransferEncoding.SevenBits)) { // Get the destination charset, or default to us-ascii. string charset = "us-ascii"; if (part.Charset != null && part.Charset.Length > 0) charset = part.Charset; // Extract part.TextContent = body; //part.BinaryContent = System.Text.Encoding.GetEncoding(charset).GetBytes(part.TextContent); } // Now we have the decoded content and it's type. Let's take appropriate action. if (part.ContentType.Type.Equals("multipart")) { MultipartContainer multipart = Parser.ParseMultipartContainer(part); multipart.Track = DispatchTrack.MultipartContainer; return multipart; } else if (part.ContentType.Type.Equals("message")) { // TODO } //else if (part.ContentType.Type.Equals("multipart")) return part; }
private static void ParseMessage(ref Message message, X509Certificate2Collection certificates) { // Header parsing work string msg = System.Text.Encoding.ASCII.GetString(message.OriginalData); string header = msg.Substring(0,Regex.Match(msg, @"\r?\n\r?\n").Index); header = Parser.Unfold(header); header = Codec.RFC2047Decode(header); Match m = Regex.Match(header, @"(?<=((\r?\n)|\n)|\A)\S+:(.|(\r?\n[\t ]))+(?=((\r?\n)\S)|\Z)"); while (m.Success) { string name = FormatFieldName(m.Value.Substring(0, m.Value.IndexOf(':'))); string value = m.Value.Substring(m.Value.IndexOf(":") + 1); if (name.Equals("received")) message.Trace.Add(Parser.ParseTrace(m.Value.Trim(' '))); else if (name.Equals("to")) message.To = Parser.ParseAddresses(value); else if (name.Equals("cc")) message.Cc = Parser.ParseAddresses(value); else if (name.Equals("bcc")) message.Bcc = Parser.ParseAddresses(value); else if (name.Equals("reply-to")) message.ReplyTo = Parser.ParseAddress(value); else if (name.Equals("from")) message.From = Parser.ParseAddress(value); else if (name.Equals("sender")) message.Sender = Parser.ParseAddress(value); else if (name.Equals("content-type")) message.ContentType = Parser.GetContentType(m.Value); else if (name.Equals("content-disposition")) message.ContentDisposition = Parser.GetContentDisposition(m.Value); else if (name.Equals("domainkey-signature")) message.Signatures.DomainKeys = Signature.Parse(m.Value,message); message.HeaderFields.Add(name,value); message.HeaderFieldNames.Add(name, m.Value.Substring(0, m.Value.IndexOf(':'))); m = m.NextMatch(); } // Body parsing work if (message.ContentType.MimeType != null && message.ContentType.MimeType.IndexOf("multipart/signed") != -1) message.IsSigned = true; if (message.ContentType.MimeType != null && message.ContentType.MimeType.IndexOf("multipart/encrypted") != -1) message.IsEncrypted = true; //MimeTypedAndEncodedContent part = Parser.ParseMimeTypedAndEncodedContent(msg);//, certificates); /*if (part.ContentType.MimeType!=null && part.ContentType.MimeType.IndexOf("multipart/") != -1) { Parser.ParseMultipart(ref message, part, certificates); Parser.DistributeParts(ref message); Parser.SetBodies(ref message); } else if (part.ContentDisposition.Disposition.Equals("attachment")) { message.AllMimeParts.Add(part); message.Attachments.Add(part); } else { message.AllMimeParts.Add(part); if (part.ContentType.MimeType!=null && part.ContentType.MimeType.ToLower().IndexOf("text/html") != -1) { if (part.ContentTransferEncoding == ContentTransferEncoding.Base64) message.BodyHtml.Text = System.Text.Encoding.GetEncoding(part.Charset).GetString(System.Convert.FromBase64String(part.TextContent.Substring(0, part.TextContent.IndexOf("\r\n\r\n")))); else message.BodyHtml.Text = part.TextContent; } else if (part.ContentType.MimeType != null && part.ContentType.MimeType.ToLower().IndexOf("text/plain") != -1) { if (part.ContentTransferEncoding == ContentTransferEncoding.Base64) message.BodyText.Text = System.Text.Encoding.GetEncoding(part.Charset).GetString(System.Convert.FromBase64String(part.TextContent.Substring(0, part.TextContent.IndexOf("\r\n\r\n")))); else message.BodyText.Text = part.TextContent; } else { message.BodyText.Text = System.Text.Encoding.ASCII.GetString(message.BodyBinary); } } if (!ActiveUp.Base.InternalLicense.Status.IsRegistered || ActiveUp.Base.InternalLicense.IsLite()) { if (message.BodyHtml.Text.Length > 0 && message.BodyHtml.Text.IndexOf(ActiveUp.Base.InternalLicense.UnRegisteredHtmlSent) == -1 && message.BodyHtml.Text.IndexOf(ActiveUp.Base.InternalLicense.SponsorHtmlSent) == -1 && message.BodyHtml.Text.IndexOf(ActiveUp.Base.InternalLicense.UnRegisteredHtmlReceived) == -1) message.BodyHtml.Text = ActiveUp.Base.InternalLicense.UnRegisteredHtmlReceived + "<br><br>" + message.BodyHtml.Text; if ((message.BodyText.Text.Length > 0 || message.BodyHtml.Text.Length == 0) && message.BodyText.Text.IndexOf(ActiveUp.Base.InternalLicense.UnRegisteredTextSent) == -1 && message.BodyText.Text.IndexOf(ActiveUp.Base.InternalLicense.SponsorTextSent) == -1 && message.BodyText.Text.IndexOf(ActiveUp.Base.InternalLicense.UnRegisteredTextReceived) == -1) message.BodyText.Text = ActiveUp.Base.InternalLicense.UnRegisteredTextReceived + "\n\n" + message.BodyText.Text; } else if (ActiveUp.Base.InternalLicense.IsSponsored()) { if (message.BodyHtml.Text.Length > 0 && message.BodyHtml.Text.IndexOf(ActiveUp.Base.InternalLicense.SponsorHtmlSent) == -1 && message.BodyHtml.Text.IndexOf(ActiveUp.Base.InternalLicense.SponsorHtmlReceived) == -1 && message.BodyHtml.Text.IndexOf(ActiveUp.Base.InternalLicense.UnRegisteredHtmlSent) == -1) message.BodyHtml.Text += "<br><br>" + ActiveUp.Base.InternalLicense.SponsorHtmlReceived; if ((message.BodyText.Text.Length > 0 || message.BodyHtml.Text.Length == 0) && message.BodyText.Text.IndexOf(ActiveUp.Base.InternalLicense.SponsorTextSent) == -1 && message.BodyText.Text.IndexOf(ActiveUp.Base.InternalLicense.SponsorTextReceived) == -1 && message.BodyHtml.Text.IndexOf(ActiveUp.Base.InternalLicense.UnRegisteredTextSent) == -1) message.BodyText.Text += "\n\n" + ActiveUp.Base.InternalLicense.SponsorTextReceived; }*/ }