Example #1
0
        protected virtual void ParseBody()
        {
            string strFullConentType = _headers["Content-Type"];

            if (strFullConentType == null)
            {
                strFullConentType = "";
            }

            //string strContentTypeValue	= null;

            Hashtable parametrs;

            MimeEntry.ParseHeader(strFullConentType, out _contentType, out parametrs);

            // Step 2. Parse Messagy Body [1/23/2004]
            if (!_contentType.StartsWith("multipart/"))
            {
                _charSet = (string)parametrs["charset"];

                if (_charSet == null)
                {
                    _charSet = Encoding.Default.HeaderName;
                }

                string ContentEncoding = _headers["Content-Transfer-Encoding"];

                if (ContentEncoding == null)
                {
                    ContentEncoding = "8bit";
                }

                string strDisposition = _headers["Content-Disposition"];

                if (strDisposition != null)
                {
                    Hashtable DispositionParameters;
                    string    DispositionType;
                    MimeEntry.ParseHeader(strDisposition, out DispositionType, out DispositionParameters);

                    DispositionType = DispositionType.ToLower();

                    if (DispositionType == "attachment")
                    {
                        this._disposition = Disposition.Attachment;
                    }
                    else if (DispositionType == "inline")
                    {
                        this._disposition = Disposition.Inline;
                    }

                    _fileName = (string)DispositionParameters["filename"];
                    if (_fileName != null)
                    {
                        _fileName = Rfc822HeaderCollection.DeocodeHeaderValue(_fileName);
                    }
                }

                //string BodyString = Encoding.Default.GetString(this._BinaryData.GetBuffer(),this._BodyOffset,(int)(this._BinaryData.Length  - this._BodyOffset));
                Encoding encoding = null;
                try
                {
                    encoding = Encoding.GetEncoding(CharSet);
                }
                catch
                {
                    encoding = Encoding.Default;
                }


                string BodyString = encoding.GetString(this._BinaryData.GetBuffer(), this._BodyOffset, (int)(this._BinaryData.Length - this._BodyOffset));

                //string BodyString = Encoding.ASCII.GetString(this._BinaryData.GetBuffer(),this._BodyOffset,(int)(this._BinaryData.Length  - this._BodyOffset));
                //string BodyString2 = Encoding.UTF8.GetString(this._BinaryData.GetBuffer(),this._BodyOffset,(int)(this._BinaryData.Length  - this._BodyOffset));

                switch (ContentEncoding.ToLower())
                {
                case "quoted-printable":
                    _body = encoding.GetBytes(MimeEntry.QDecode(encoding, BodyString));
                    break;

                case "7bit":
                    //_body = Encoding.ASCII.GetBytes(BodyString);
                    _body = encoding.GetBytes(BodyString);
                    break;

                default:
                case "8bit":
                    _body = encoding.GetBytes(BodyString);
                    break;

                case "base64":
                    BodyString = BodyString.Trim();

                    if (BodyString.Length > 0)
                    {
                        int base64FixCount = 0;

                        // Fix If Base 64 is broken
                        while (true)
                        {
                            try
                            {
                                _body = Convert.FromBase64String(BodyString);
                                break;
                            }
                            catch (System.FormatException)
                            {
                                // Remove not supported chars
                                if (base64FixCount == 0)
                                {
                                    BodyString = Regex.Replace(BodyString, "[^a-zA-Z0-9+/=]+", string.Empty);
                                }
                                else if (base64FixCount == 1)
                                {
                                    BodyString += "=";
                                }
                                else
                                {
                                    BodyString = BodyString.Substring(0, BodyString.Length - 1);
                                }

                                if (BodyString.Length == 0 || base64FixCount == 25)                                         // Max 25 Attempts to fix chars
                                {
                                    _body = new byte[] { };
                                    break;
                                }

                                base64FixCount++;
                            }
                        }
                    }
                    else
                    {
                        _body = new byte[] {}
                    };
                    break;

                case "binary":
                    _body = encoding.GetBytes(BodyString);
                    break;
                    //default:
                    //    throw new Pop3ServerIncorectEMailFormatException("Not supported content-encoding " + ContentEncoding + " !");
                }
            }
            else
            {
                DataParseStatus parseStatus = _mimeEntries.ParseMimeEntries(_BinaryData.GetBuffer(), (int)_BinaryData.Length, ref _BodyOffset, this.Headers);
            }
        }
Example #2
0
        public DataParseStatus ParseHeaders(byte[] buffer, int size, ref int unparsed)
        {
            int headerKeyBegin = -1;
            int hederKeyEnd    = -1;
            int finalCLRNCount = -1;
            int currIndex      = unparsed;

            Encoding defaultEncoding = Encoding.Default;

            do
            {
                string strHeader = String.Empty;

                bool flag1 = false;

                bool isHeaderKeyUTF8   = false;
                bool isHeaderValueUTF8 = false;

                string strHeaderValue = null;

                if (base.Count == 0)
                {
                    while (currIndex < size && (buffer[currIndex] == 32 ||                 /*[space]*/
                                                buffer[currIndex] == 9))
                    {
                        currIndex++;
                    }

                    if (currIndex == size)
                    {
                        return(DataParseStatus.NeedMoreData);
                    }
                }

                headerKeyBegin = currIndex;
                for (; currIndex < size && buffer[currIndex] != 58 /*:*/ && buffer[currIndex] != 10; currIndex++)
                {
                    if (buffer[currIndex] > 32 /*[space]*/)
                    {
                        hederKeyEnd = currIndex;
                        //isHeaderKeyUTF8 = !isHeaderKeyUTF8 ? (buffer[currIndex] > 127) : true;
                    }
                }

                if (currIndex == size)
                {
                    return(DataParseStatus.NeedMoreData);
                }

                while (true)
                {
                    string strHeaderValueTmp = String.Empty;
                    int    headerValueBegin  = -1;
                    int    headerValueEnd    = -1;

                    for (finalCLRNCount = (base.Count != 0 || hederKeyEnd >= 0) ? 0 : 1; currIndex < size && finalCLRNCount < 2 && (buffer[currIndex] <= 32 /*[space]*/ || buffer[currIndex] == 58); currIndex++)
                    {
                        if (buffer[currIndex] == 10)
                        {
                            finalCLRNCount++;
                            flag1 = (currIndex + 1 < size) ? ((buffer[currIndex + 1] != 32 /*[space]*/) ? (buffer[currIndex + 1] == 9) : true) : false;
                        }
                    }

                    if (finalCLRNCount != 2 && (finalCLRNCount != 1 || flag1))
                    {
                        if (currIndex == size)
                        {
                            return(DataParseStatus.NeedMoreData);
                        }

                        headerValueBegin = currIndex;
                        for (; currIndex < size && buffer[currIndex] != 10; currIndex++)
                        {
                            if (buffer[currIndex] > 32 /*[space]*/)
                            {
                                headerValueEnd = currIndex;
                                //isHeaderValueUTF8 = !isHeaderValueUTF8 ? (buffer[currIndex] > 127) : true;
                            }
                        }

                        if (currIndex == size)
                        {
                            return(DataParseStatus.NeedMoreData);
                        }

                        for (finalCLRNCount = 0; currIndex < size && finalCLRNCount < 2 && (buffer[currIndex] == 13 || buffer[currIndex] == 10); currIndex++)
                        {
                            if (buffer[currIndex] == 10)
                            {
                                finalCLRNCount++;
                            }
                        }

                        if (currIndex == size && finalCLRNCount < 2)
                        {
                            return(DataParseStatus.NeedMoreData);
                        }
                    }

                    if (headerValueBegin >= 0 && headerValueBegin > hederKeyEnd && headerValueEnd >= headerValueBegin)
                    {
                        if (isHeaderValueUTF8)
                        {
                            strHeaderValueTmp = Encoding.UTF8.GetString(buffer, headerValueBegin, headerValueEnd - headerValueBegin + 1);
                        }
                        else
                        {
                            strHeaderValueTmp = defaultEncoding.GetString(buffer, headerValueBegin, headerValueEnd - headerValueBegin + 1);
                        }
                    }
                    strHeaderValue = (strHeaderValue != null) ? String.Concat(strHeaderValue, " ", strHeaderValueTmp) : strHeaderValueTmp;
                    if (currIndex >= size ||
                        finalCLRNCount != 1 ||
                        buffer[currIndex] != 32 /*[space]*/ && buffer[currIndex] != 9)
                    {
                        break;
                    }
                    currIndex++;
                }

                if (headerKeyBegin >= 0 && hederKeyEnd >= headerKeyBegin)
                {
                    if (isHeaderKeyUTF8)
                    {
                        strHeader = Encoding.UTF8.GetString(buffer, headerKeyBegin, hederKeyEnd - headerKeyBegin + 1);
                    }
                    else
                    {
                        strHeader = Encoding.ASCII.GetString(buffer, headerKeyBegin, hederKeyEnd - headerKeyBegin + 1);
                    }
                }
                if (strHeader.Length > 0)
                {
                    string strValue = DeocodeHeaderValue(strHeaderValue);
                    base.Add(strHeader, strValue);

                    if (strHeader == "Content-Type")
                    {
                        string strContentType;

                        Hashtable parametrs;
                        MimeEntry.ParseHeader(strValue, out strContentType, out parametrs);

                        string strCharset = (string)parametrs["charset"];

                        if (!string.IsNullOrEmpty(strCharset))
                        {
                            try
                            {
                                defaultEncoding = Encoding.GetEncoding(strCharset);
                            }
                            catch
                            {
                                defaultEncoding = Encoding.Default;
                            }
                        }
                    }
                }
                unparsed = currIndex;
            }while (finalCLRNCount != 2);

            //this.IsReadOnly = true;

            return(DataParseStatus.Done);
        }
Example #3
0
        public static string DeocodeHeaderValue(string headerValue)
        {
            // Cool Encoding [2/13/2004]
            MatchCollection matchList = Regex.Matches(headerValue, @"(?<encodedword>=\?(?<charset>[^?]+)\?(?<encoding>[^?]+)\?(?<encodedtext>[^?]+)\?=)");

            if (matchList.Count > 0)
            {
                // Fix: White space between adjacent 'encoded-word's is not displayed
                // [2007-07-03] TODO (=?ISO-8859-1?Q?a?= =?ISO-8859-1?Q?b?=)   ->  (ab)
                // [2007-07-03] TODO (=?ISO-8859-1?Q?a?=  =?ISO-8859-1?Q?b?=)   ->  (ab)
                // [2007-07-03] TODO (=?ISO-8859-1?Q?a?=\r\n  =?ISO-8859-1?Q?b?=)   ->  (ab)
                headerValue = Regex.Replace(headerValue, @"\?=[ ]+=\?", @"?==?");

                System.Text.StringBuilder strBilder = new System.Text.StringBuilder(headerValue);

                foreach (Match matchItem in matchList)
                {
                    string strEncodedWord = matchItem.Groups["encodedword"].Value;

                    string strCharset     = matchItem.Groups["charset"].Value;
                    string strEncoding    = matchItem.Groups["encoding"].Value;
                    string strEncodedText = matchItem.Groups["encodedtext"].Value;


                    if (matchItem.Groups["spaceceprator"].Success)
                    {
                        strBilder.Replace(strEncodedWord + matchItem.Groups["spaceceprator"].Value, strEncodedWord);
                    }

                    System.Text.Encoding encoder = System.Text.Encoding.GetEncoding(strCharset);

                    string DecodedString = null;

                    if (strEncoding.ToUpper() == "Q")
                    {
                        // FIX: The 8-bit hexadecimal value 20 (e.g., ISO-8859-1 SPACE) may be
                        // represented as "_" (underscore, ASCII 95.).  (This character may
                        // not pass through some internetwork mail gateways, but its use
                        // will greatly enhance readability of "Q" encoded data with mail
                        // readers that do not support this encoding.)

                        DecodedString = MimeEntry.QDecode(encoder, strEncodedText.Replace('_', ' '));
                    }
                    else if (strEncoding.ToUpper() == "B")
                    {
                        int base64FixCount = 0;

                        while (true)
                        {
                            try
                            {
                                byte[] FromBase64String = Convert.FromBase64String(strEncodedText);
                                DecodedString = encoder.GetString(FromBase64String);
                                break;
                            }
                            catch (System.FormatException)
                            {
                                // Remove not supported chars
                                if (base64FixCount == 0)
                                {
                                    strEncodedText = Regex.Replace(strEncodedText, "[^a-zA-Z0-9+/=]+", string.Empty);
                                }
                                else if (base64FixCount == 1)
                                {
                                    strEncodedText += "=";
                                }
                                else
                                {
                                    strEncodedText = strEncodedText.Substring(0, strEncodedText.Length - 1);
                                }

                                if (strEncodedText.Length == 0 || base64FixCount == 25)                                 // Max 25 Attempts to fix chars
                                {
                                    DecodedString = null;
                                    break;
                                }

                                base64FixCount++;
                            }
                        }
                    }

                    if (DecodedString != null)
                    {
                        strBilder.Replace(strEncodedWord, DecodedString);
                    }
                }

                return(strBilder.ToString());
            }

//			if(headerValue.StartsWith("=?"))
//			{
//				string[] parts = headerValue.Substring(2).Split(new char[]{'?'});
//
//				string encoderName	= parts[0];
//				string type			= parts[1];
//				string datax		= parts[2];
//
//				System.Text.Encoding encoder = System.Text.Encoding.GetEncoding(encoderName);
//				if(type.ToUpper() == "Q")
//				{
//					return MimeEntry.QDecode(encoder,datax);
//				}
//				else if(type.ToUpper() == "B")
//				{
//					return encoder.GetString(Convert.FromBase64String(datax));
//				}
//			}

            return(headerValue);
        }
Example #4
0
        protected void SaveMimeEntry(System.IO.StreamWriter	writer, MimeEntry	entry)
        {
            if(entry.ContentDisposition==Disposition.Attachment)
                return;

            // Step 2. Process Mime Entry [5/11/2004]

            string ContentType = entry.Headers["Content-Type"];
            Hashtable	ContentTypeParametrs = ParseHeaderLine(ContentType);
            string ContentTypeBoundary = (string)ContentTypeParametrs["boundary"];

            //			if(ContentType==null)
            //				ContentType = "Content-Type: text/html; charset=\"utf-8\"";

            if(entry.Body!=null &&ContentTypeBoundary==null)
            {
                writer.Write("\r\n------=_NextPart_000_0000_01C26874.EA4F5D40\r\n");
                SaveHeaders(writer,entry.Headers);

                //				if(ContentType.IndexOf("text/html")!=-1)
                //				{
                //					writer.Write(Convert.ToBase64String(Encoding.UTF8.GetBytes(entry.BodyText)));
                //				}

                if(ContentType==null)
                {
                    ContentType = "Content-Type: text/html; charset=\"utf-8\"";
                    writer.Write(Convert.ToBase64String(Encoding.UTF8.GetBytes(entry.BodyText)));
                }
                else
                    writer.Write(Convert.ToBase64String(entry.Body));
            }

            foreach(MimeEntry	childEntry in entry.MimeEntries)
            {
                SaveMimeEntry(writer,childEntry);
            }
        }
Example #5
0
        internal DataParseStatus ParseMimeEntries(byte[] buffer, int size, ref int unparsed, Rfc822HeaderCollection headers)
        {
            string strFullConentType	= headers["Content-Type"];
            if(strFullConentType==null)
                strFullConentType="";

            string strContentTypeValue	= null;

            Hashtable	parametrs;
            MimeEntry.ParseHeader(strFullConentType, out strContentTypeValue, out parametrs);

            if(!strContentTypeValue.StartsWith("multipart/", true, CultureInfo.InvariantCulture))
            {
                // Simple Email [1/27/2004]
                MemoryStream strmEntry = new MemoryStream();
                strmEntry.Write(buffer, unparsed, size - unparsed);

                this.Add(new MimeEntry(strmEntry,headers));
            }
            else
            {
                // Parse Multipart Value
                string boundaryID = (string)parametrs["boundary"];

                // Step 1. Unpack multipart [2/10/2004]
                StreamLineReader	lineReader = new StreamLineReader (buffer, unparsed, size);
                byte[] lineData = lineReader.ReadLine();

                // Step 1.1 Search first entry
                while(lineData!=null)
                {
                    string strLine = System.Text.Encoding.Default.GetString(lineData);
                    if(strLine.StartsWith("--" + boundaryID))
                    {
                        lineData = lineReader.ReadLine();
                        break;
                    }
                    lineData = lineReader.ReadLine();
                }

                // Step 1.2 Start reading entries
                MemoryStream strmEntry = new MemoryStream();

                while(lineData!=null)
                {
                    string strLine = System.Text.Encoding.Default.GetString(lineData);
                    if(strLine.StartsWith("--" + boundaryID) && strmEntry.Length > 0)
                    {
                        // Step 1.3 Add Entry
                        try
                        {
                            MimeEntry newEntry = new MimeEntry(strmEntry);
                            this.Add(newEntry);
                        }
                        catch (Pop3ServerIncorectEMailFormatException ex)
                        {
                            // Skeep Broken Entry
                            if (ex.InnerException != null)
                                throw;
                        }

                        strmEntry.SetLength(0);
                    }
                    else
                    {
                        strmEntry.Write(lineData,0,lineData.Length);
                        strmEntry.Write(new byte[]{(byte)'\r',(byte)'\n'},0,2);
                    }

                    lineData = lineReader.ReadLine();
                }
            }

            return DataParseStatus.Done;
        }
Example #6
0
 internal void Add(MimeEntry newItem)
 {
     this.List.Add(newItem);
 }
Example #7
0
        internal DataParseStatus ParseMimeEntries(byte[] buffer, int size, ref int unparsed, Rfc822HeaderCollection headers)
        {
            string strFullConentType = headers["Content-Type"];

            if (strFullConentType == null)
            {
                strFullConentType = "";
            }

            string strContentTypeValue = null;

            Hashtable parametrs;

            MimeEntry.ParseHeader(strFullConentType, out strContentTypeValue, out parametrs);

            if (!strContentTypeValue.StartsWith("multipart/", true, CultureInfo.InvariantCulture))
            {
                // Simple Email [1/27/2004]
                MemoryStream strmEntry = new MemoryStream();
                strmEntry.Write(buffer, unparsed, size - unparsed);

                this.Add(new MimeEntry(strmEntry, headers));
            }
            else
            {
                // Parse Multipart Value
                string boundaryID = (string)parametrs["boundary"];

                // Step 1. Unpack multipart [2/10/2004]
                StreamLineReader lineReader = new StreamLineReader(buffer, unparsed, size);
                byte[]           lineData   = lineReader.ReadLine();

                // Step 1.1 Search first entry
                while (lineData != null)
                {
                    string strLine = System.Text.Encoding.Default.GetString(lineData);
                    if (strLine.StartsWith("--" + boundaryID))
                    {
                        lineData = lineReader.ReadLine();
                        break;
                    }
                    lineData = lineReader.ReadLine();
                }

                // Step 1.2 Start reading entries
                MemoryStream strmEntry = new MemoryStream();

                while (lineData != null)
                {
                    string strLine = System.Text.Encoding.Default.GetString(lineData);
                    if (strLine.StartsWith("--" + boundaryID) && strmEntry.Length > 0)
                    {
                        // Step 1.3 Add Entry
                        try
                        {
                            MimeEntry newEntry = new MimeEntry(strmEntry);
                            this.Add(newEntry);
                        }
                        catch (Pop3ServerIncorectEMailFormatException ex)
                        {
                            // Skeep Broken Entry
                            if (ex.InnerException != null)
                            {
                                throw;
                            }
                        }

                        strmEntry.SetLength(0);
                    }
                    else
                    {
                        strmEntry.Write(lineData, 0, lineData.Length);
                        strmEntry.Write(new byte[] { (byte)'\r', (byte)'\n' }, 0, 2);
                    }

                    lineData = lineReader.ReadLine();
                }
            }


            return(DataParseStatus.Done);
        }
Example #8
0
 internal void Add(MimeEntry newItem)
 {
     this.List.Add(newItem);
 }