Пример #1
0
        private void ProcessSingleBody()
        {
            string[] lines = _body.Split('\n');

            _partBuilder.Length = 0;
            if (_content_type.ToLower().IndexOf("/html") < 0)
            {
                ProcessSinglePlainBody(lines);
            }
            else
            {
                ProcessSingleHtmlBody(lines);
            }

            if (_bodyBuilder.Length > 0 || _htmlBodyBuilder.Length > 0)
            {
                string cte = _content_transfer_encoding;
                if (Utils.StartsWith(cte, "quoted-printable", true))
                {
                    string body = _bodyBuilder.ToString();
                    _bodyBuilder.Length = 0;
                    _bodyBuilder.Append(MIMEParser.DecodeQuotedPrintable(_charset, body));
                    body = _htmlBodyBuilder.ToString();
                    _htmlBodyBuilder.Length = 0;
                    _htmlBodyBuilder.Append(MIMEParser.DecodeQuotedPrintable(_charset, body));
                }
                else if (Utils.StartsWith(cte, "base64", true))
                {
                    string body = _bodyBuilder.ToString();
                    _bodyBuilder.Length = 0;
                    _bodyBuilder.Append(MIMEParser.DecodeBase64(_charset, body));
                    body = _htmlBodyBuilder.ToString();
                    _htmlBodyBuilder.Length = 0;
                    _htmlBodyBuilder.Append(MIMEParser.DecodeBase64(_charset, body));
                }
                else
                {
                    string body = _bodyBuilder.ToString();
                    _bodyBuilder.Length = 0;
                    _bodyBuilder.Append(MIMEParser.TranslateRawStringInCharset(_charset, body));
                    body = _htmlBodyBuilder.ToString();
                    _htmlBodyBuilder.Length = 0;
                    _htmlBodyBuilder.Append(MIMEParser.TranslateRawStringInCharset(_charset, body));
                    for (int i = 0; i < _parts.Count; ++i)
                    {
                        MessagePart attachment = (MessagePart)_parts[i];
                        attachment.Name = MIMEParser.TranslateRawStringInCharset(_charset, attachment.Name);
                    }
                }
            }
        }
Пример #2
0
 private static string DecodeLine(string line, MessagePartEncoding MIME_encoding, string bodyCharset)
 {
     if (MIME_encoding == MessagePartEncoding.QuotedPrintable)
     {
         line = MIMEParser.DecodeQuotedPrintable(bodyCharset, line);
     }
     else if (MIME_encoding == MessagePartEncoding.Base64)
     {
         line = MIMEParser.DecodeBase64(bodyCharset, line);
     }
     else
     {
         line = MIMEParser.TranslateRawStringInCharset(bodyCharset, line);
     }
     return(line);
 }
Пример #3
0
        private static string EscapeSinglePeriodsAndTranslateToCharset(string body, string charset)
        {
            string[] lines;
            lines = body.Split('\n');
            bool areSinglePeriods = false;

            for (int i = 0; i < lines.Length; ++i)
            {
                if (lines[i].StartsWith("."))
                {
                    lines[i]         = lines[i].Insert(0, ".");
                    areSinglePeriods = true;
                }
            }
            StringBuilder bodyBuilder = StringBuilderPool.Alloc();

            try
            {
                if (areSinglePeriods)
                {
                    for (int i = 0; i < lines.Length; ++i)
                    {
                        bodyBuilder.Append(lines[i]);
                        bodyBuilder.Append('\n');
                    }
                    body = bodyBuilder.ToString();
                }
                bodyBuilder.Length = 0;
                byte[] bytes = MIMEParser.GetEncodingExceptionSafe(charset).GetBytes(body);
                for (int i = 0; i < bytes.Length; ++i)
                {
                    bodyBuilder.Append((char)bytes[i]);
                }
                return(bodyBuilder.ToString());
            }
            finally
            {
                StringBuilderPool.Dispose(bodyBuilder);
            }
        }
Пример #4
0
        /**
         * builds MIME mail/news body for plaintext bodies
         */
        public static string BuildMIMEBody(string body, string bodyCharset, string bodyEncoding,
                                           out string boundary, params string[] fullnames)
        {
            string newBoundary = "----++Omea_Parts_Splitter" + new Random().NextDouble().ToString().Substring(1);

            StringBuilder bodyBuilder = StringBuilderPool.Alloc();

            try
            {
                // add MIME help string
                bodyBuilder.Append("This is a multi-part message in MIME format.\r\n");

                // encode and add body
                bodyEncoding = bodyEncoding.ToLower();
                bodyBuilder.Append(newBoundary);
                bodyBuilder.Append("\r\nContent-Type: text/plain");
                if (bodyCharset.Length > 0)
                {
                    bodyBuilder.Append("; charset=");
                    bodyBuilder.Append(bodyCharset);
                }
                if (bodyEncoding == "quoted-printable")
                {
                    bodyBuilder.Append("\r\nContent-Transfer-Encoding: quoted-printable\r\n\r\n");
                    string[] lines = body.Split('\n');
                    foreach (string line in lines)
                    {
                        bodyBuilder.Append(MIMEParser.EncodeQuotedPrintable(bodyCharset, line.TrimEnd('\r')));
                        bodyBuilder.Append("\r\n");
                    }
                }
                else if (bodyEncoding == "base64")
                {
                    body = MIMEParser.EncodeBase64(bodyCharset, body);
                    bodyBuilder.Append("\r\nContent-Transfer-Encoding: base64\r\n");

                    /**
                     * split base64 body onto several lines
                     */
                    string line;
                    int    i       = 0;
                    int    lineLen = _UULinePreferredLen * 4 / 3;
                    while (i < body.Length)
                    {
                        line = body.Substring(i, (lineLen <= body.Length - i) ? lineLen : body.Length - i);
                        bodyBuilder.Append("\r\n");
                        bodyBuilder.Append(line);
                        i += line.Length;
                    }
                }
                else
                {
                    bodyBuilder.Append("\r\nContent-Transfer-Encoding: 8bit\r\n\r\n");
                    bodyBuilder.Append(EscapeSinglePeriodsAndTranslateToCharset(body, bodyCharset));
                }

                // encode and add attachments
                byte[] bytes = new byte[_UULinePreferredLen];
                foreach (string fullname in fullnames)
                {
                    FileStream fs = OpenAttachment(fullname);
                    if (fs != null)
                    {
                        string filename = Path.GetFileName(fullname);
                        if (MIMEParser.Has8BitCharacters(filename))
                        {
                            filename = MIMEParser.CreateBase64MIMEString(bodyCharset, filename);
                        }
                        bodyBuilder.Append("\r\n");
                        bodyBuilder.Append(newBoundary);
                        string contentType = MIMEContentTypes.GetContentType(Path.GetExtension(fullname));
                        if (contentType == null)
                        {
                            bodyBuilder.Append("\r\nContent-Type: application/octet-stream; name=\"");
                        }
                        else
                        {
                            bodyBuilder.Append("\r\nContent-Type: ");
                            bodyBuilder.Append(contentType);
                            bodyBuilder.Append("; name=\"");
                        }
                        bodyBuilder.Append(filename);
                        bodyBuilder.Append("\"\r\nContent-Transfer-Encoding: base64\r\nContent-Disposition: attachment; filename=\"");
                        bodyBuilder.Append(filename);
                        bodyBuilder.Append("\"\r\n");
                        int read;
                        while ((read = fs.Read(bytes, 0, bytes.Length)) > 0)
                        {
                            bodyBuilder.Append("\r\n");
                            bodyBuilder.Append(MIMEParser.EncodeBase64(bytes, read));
                        }
                    }
                }

                // finish multipart message
                bodyBuilder.Append("\r\n");
                bodyBuilder.Append(newBoundary);
                bodyBuilder.Append("--");

                // ignore the "--" prefix
                boundary = newBoundary.Substring(2);
                return(bodyBuilder.ToString());
            }
            finally
            {
                StringBuilderPool.Dispose(bodyBuilder);
            }
        }
Пример #5
0
        private void ProcessMutipartBody()
        {
            /**
             * extract boundary from content-type
             */
            string boundary      = string.Empty;
            int    boundaryBegin = _content_type.ToLower().IndexOf("boundary=");

            if (boundaryBegin > 0)
            {
                boundaryBegin += 9;
                int boundaryEnd = _content_type.IndexOfAny(_boundaryDelimiters, boundaryBegin);
                if (boundaryEnd < 0)
                {
                    boundaryEnd = _content_type.Length;
                }
                if (boundaryEnd > boundaryBegin)
                {
                    boundary = _content_type.Substring(
                        boundaryBegin, boundaryEnd - boundaryBegin).Replace("\"", string.Empty).Trim();
                }
            }
            if (boundary.Length == 0)
            {
                _bodyBuilder.Append("Bad multipart message: the \"Content-Type\" header doesn't contain valid boundary. Message source follows as plain text.\r\n\r\n");
                _bodyBuilder.Append(_body);
                return;
            }
            boundary = "--" + boundary;
            string finishingBoundary = boundary + "--";

            string[]            lines         = _body.Split('\n');
            string              line          = string.Empty;
            int                 i             = 0;
            bool                inHeaders     = true;
            bool                isHtmlBody    = false;
            bool                isAttachment  = false;
            bool                isInline      = false;
            bool                isAlternative = false;
            MessagePartEncoding MIME_encoding = MessagePartEncoding.None;
            string              bodyCharset   = string.Empty;
            string              filename      = string.Empty;
            string              altBoundary   = string.Empty;
            string              contentId     = string.Empty;

            _partBuilder.Length = 0;

            /**
             * search for the first boundary
             */
            for ( ; i < lines.Length; ++i)
            {
                line = lines[i].TrimEnd('\r');
                if (line.StartsWith(boundary))
                {
                    ++i;
                    break;
                }
            }

            for ( ; i < lines.Length && !line.StartsWith(finishingBoundary); ++i)
            {
                line = lines[i].TrimEnd('\r');

                /**
                 * if not in headers then process next part
                 */
                if (!inHeaders)
                {
                    /**
                     * if filename not present process body
                     */
                    if (filename.Length == 0)
                    {
                        if (isHtmlBody)
                        {
                            i = ProcessHTMLBody(lines, i, boundary, MIME_encoding, bodyCharset);
                        }
                        else
                        {
                            i = ProcessBody(lines, i, boundary, MIME_encoding, bodyCharset);

                            /**
                             * if body is nested multipart/alternative then parse it in its turn
                             */
                            if (isAlternative && altBoundary.Length > 0)
                            {
                                MultiPartBodyParser parser = new MultiPartBodyParser(
                                    _bodyBuilder.ToString(), "multipart/alternative; boundary=" +
                                    altBoundary, _content_transfer_encoding, _charset);
                                _bodyBuilder.Length     = 0;
                                _htmlBodyBuilder.Length = 0;
                                _parts.AddRange(parser.GetParts());
                            }
                        }
                    }
                    else

                    /**
                     * if filename present then we are to extract attacment
                     */
                    {
                        i = ProcessAttachment(lines, i, boundary, MIME_encoding);
                        if (MIMEParser.IsMIMEString(filename))
                        {
                            filename = MIMEParser.DecodeMIMEString(filename);
                        }
                        string      partStr    = _partBuilder.ToString();
                        MessagePart attachment = null;
                        switch (MIME_encoding)
                        {
                        case MessagePartEncoding.QuotedPrintable:
                        {
                            attachment = new MessagePart(MIMEParser.DecodeQuotedPrintable(partStr), filename);
                            break;
                        }

                        case MessagePartEncoding.Base64:
                        {
                            byte[] bytes = MIMEParser.DecodeBase64(partStr);
                            if (bytes != null)
                            {
                                attachment = new MessagePart(bytes, filename);
                            }
                            break;
                        }

                        default:
                        {
                            attachment = new MessagePart(
                                MIMEParser.GetEncodingExceptionSafe(bodyCharset).GetBytes(partStr), filename);
                            break;
                        }
                        }
                        if (attachment != null)
                        {
                            if (isInline)
                            {
                                attachment.PartType = MessagePartTypes.Inline;
                            }
                            else
                            {
                                if (contentId.Length > 0)
                                {
                                    attachment.PartType  = MessagePartTypes.Embedded;
                                    attachment.ContentId = contentId;
                                }
                            }
                            _parts.Add(attachment);
                        }
                        _partBuilder.Length = 0;
                    }

                    /**
                     * reset encoding, charset, filename, alternative boundary, content-id and flags
                     */
                    MIME_encoding = MessagePartEncoding.None;
                    bodyCharset   = _charset;
                    filename      = altBoundary = contentId = string.Empty;
                    inHeaders     = true;
                    isHtmlBody    = isAttachment = isInline = false;
                }
                else
                {
                    if (line.Length == 0)
                    {
                        inHeaders = false;
                    }
                    else
                    {
                        string lowerLine = line.ToLower();
                        if (lowerLine.StartsWith("content-type:"))
                        {
                            string content_type = lowerLine.Substring(14);
                            if (content_type.StartsWith("multipart/alternative") ||
                                content_type.StartsWith("multipart/related"))
                            {
                                isAlternative = true;
                            }
                            else if (content_type.StartsWith("application/") || content_type.StartsWith("image/"))
                            {
                                isAttachment = true;
                            }
                            else
                            {
                                if (content_type.StartsWith("text/html"))
                                {
                                    isHtmlBody = true;
                                }
                                bodyCharset = DetectCharset(lowerLine, line, _charset);
                            }
                        }
                        else if (lowerLine.StartsWith("content-transfer-encoding:"))
                        {
                            string encoding = lowerLine.Substring(27);
                            if (encoding.StartsWith("quoted-printable"))
                            {
                                MIME_encoding = MessagePartEncoding.QuotedPrintable;
                            }
                            else if (encoding.StartsWith("base64"))
                            {
                                MIME_encoding = MessagePartEncoding.Base64;
                            }
                        }
                        else if (lowerLine.StartsWith("content-disposition:"))
                        {
                            string headerValue = lowerLine.Substring(21);
                            if (headerValue.StartsWith("attachment"))
                            {
                                isAttachment = true;
                            }
                            else if (headerValue.StartsWith("inline"))
                            {
                                isInline = true;
                            }
                        }
                        else if (lowerLine.StartsWith("content-id:"))
                        {
                            contentId = line.Substring(12).Replace("<", "").Replace(">", "");
                        }
                        if ((isAttachment || isInline) && filename.Length == 0)
                        {
                            int nameBegin;
                            if ((nameBegin = lowerLine.IndexOf("filename=")) > 0)
                            {
                                filename = line.Substring(nameBegin + 9).Replace("\"", string.Empty).Trim();
                            }
                            if ((nameBegin = lowerLine.IndexOf("name=")) > 0)
                            {
                                filename = line.Substring(nameBegin + 5).Replace("\"", string.Empty).Trim();
                            }
                        }
                        if (isAlternative && altBoundary.Length == 0)
                        {
                            if ((boundaryBegin = lowerLine.IndexOf("boundary=")) > 0)
                            {
                                altBoundary = line.Substring(boundaryBegin + 9).Replace("\"", string.Empty).Trim();
                            }
                        }
                    }
                }
            }
        }