Пример #1
0
        /// <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);
        }