Message.cs
资源名称:Email.rar [点击查看]
上传用户:hncsjykj
上传日期:2022-08-09
资源大小:461k
文件大小:39k
源码类别:
Email客户端
开发平台:
C#
- /******************************************************************************
- Copyright 2003-2004 Hamid Qureshi and Unruled Boy
- OpenPOP.Net is free software; you can redistribute it and/or modify
- it under the terms of the Lesser GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
- OpenPOP.Net is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- Lesser GNU General Public License for more details.
- You should have received a copy of the Lesser GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- /*******************************************************************************/
- /*
- *Name: OpenPOP.MIMEParser.Message
- *Function: Message Parser
- *Author: Hamid Qureshi
- *Created: 2003/8
- *Modified: 2004/6/16 18:34 GMT+8 by Unruled Boy
- *Description:
- *Changes:
- * 2004/6/16 18:34 GMT+8 by Unruled Boy
- * 1.fixed a loop in message body decoding by .
- * 2004/5/17 14:20 GMT+8 by Unruled Boy
- * 1.Again, fixed something but do not remember :(
- * 2004/5/11 17:00 GMT+8 by Unruled Boy
- * 1.Fixed a bug in parsing ContentCharset
- * 2.Fixed a bug in ParseStreamLines
- * 2004/5/10 10:00 GMT+8 by Unruled Boy
- * 1.Well, fixed something but do not remember :(
- * 2004/5/8 17:00 GMT+8 by Unruled Boy
- * 1.Fixed a bug in parsing boundary
- * 2004/5/1 14:13 GMT+8 by Unruled Boy
- * 1.Adding three more constructors
- * 2.Adding descriptions to every public functions/property/void
- * 2004/4/29 19:05 GMT+8 by Unruled Boy
- * 1.Fixed the bug parsing headers/boundary
- * 2004/4/28 19:06 GMT+8 by Unruled Boy
- * 1.Adding DateTimeInfo property
- * 2.Maybe we correct the HTML content type bug
- * 2004/4/23 21:13 GMT+8 by Unruled Boy
- * 1.New Contructor
- * 2.Tidy up the codes to follow Hungarian Notation
- * 2004/3/29 10:38 GMT+8 by Unruled Boy
- * 1.removing bugs in decoding message
- * 2004/3/29 17:22 GMT+8 by Unruled Boy
- * 1.adding support for reply message using ms-tnef
- * 2.adding support for all custom headers
- * 3.rewriting the header parser(adding 3 ParseStreamLines)
- * 4.adding detail description for every function
- * 5.cleaning up the codes
- * 2004/3/30 09:15 GMT+8 by Unruled Boy
- * 1.Adding ImportanceType
- */
- using System;
- using System.IO;
- using System.Collections;
- using System.Text;
- using System.Text.RegularExpressions;
- namespace OpenPOP.MIMEParser
- {
- /// <summary>
- /// Message Parser.
- /// </summary>
- public class Message
- {
- #region Member Variables
- private ArrayList _attachments=new ArrayList();
- private string _rawHeader=null;
- private string _rawMessage=null;
- private string _rawMessageBody=null;
- private int _attachmentCount=0;
- private int _realAttachmentCount =0;
- private bool _hasRealAttachment = false;
- private string _replyTo=null;
- private string _replyToEmail=null;
- private string _from=null;
- private string _fromEmail=null;
- private string _date=null;
- private string _dateTimeInfo=null;
- private string _subject=null;
- private string[] _to=new string[0];
- private string[] _cc=new string[0];
- private string[] _bcc=new string[0];
- private ArrayList _keywords=new ArrayList();
- private string _contentType=null;
- private string _contentCharset=null;
- private string _reportType=null;
- private string _contentTransferEncoding=null;
- private bool _html=false;
- private long _contentLength=0;
- private string _contentEncoding=null;
- private string _returnPath=null;
- private string _mimeVersion=null;
- private string _received=null;
- private string _importance=null;
- private string _messageID=null;
- private string _attachmentboundry=null;
- private string _attachmentboundry2=null;
- private bool _hasAttachment=false;
- private string _dispositionNotificationTo=null;
- private ArrayList _messageBody=new ArrayList();
- private string _basePath=null;
- private bool _autoDecodeMSTNEF=false;
- private Hashtable _customHeaders=new Hashtable();
- #endregion
- #region Properties
- /// <summary>
- /// custom headers
- /// </summary>
- public Hashtable CustomHeaders
- {
- get{return _customHeaders;}
- set{_customHeaders=value;}
- }
- /// <summary>
- /// whether auto decoding MS-TNEF attachment files
- /// </summary>
- public bool AutoDecodeMSTNEF
- {
- get{return _autoDecodeMSTNEF;}
- set{_autoDecodeMSTNEF=value;}
- }
- /// <summary>
- /// path to extract MS-TNEF attachment files
- /// </summary>
- public string BasePath
- {
- get{return _basePath;}
- set
- {
- try
- {
- if(value.EndsWith("\"))
- _basePath=value;
- else
- _basePath=value+"\";
- }
- catch
- {
- }
- }
- }
- /// <summary>
- /// message keywords
- /// </summary>
- public ArrayList Keywords
- {
- get{return _keywords;}
- }
- /// <summary>
- /// disposition notification
- /// </summary>
- public string DispositionNotificationTo
- {
- get{return _dispositionNotificationTo;}
- }
- /// <summary>
- /// received server
- /// </summary>
- public string Received
- {
- get{return _received;}
- }
- /// <summary>
- /// importance level
- /// </summary>
- public string Importance
- {
- get{return _importance;}
- }
- /// <summary>
- /// importance level type
- /// </summary>
- public MessageImportanceType ImportanceType
- {
- get
- {
- switch(_importance.ToUpper())
- {
- case "5":
- case "HIGH":
- return MessageImportanceType.HIGH;
- case "3":
- case "NORMAL":
- return MessageImportanceType.NORMAL;
- case "1":
- case "LOW":
- return MessageImportanceType.LOW;
- default:
- return MessageImportanceType.NORMAL;
- }
- }
- }
- /// <summary>
- /// Content Charset
- /// </summary>
- public string ContentCharset
- {
- get{return _contentCharset;}
- }
- /// <summary>
- /// Content Transfer Encoding
- /// </summary>
- public string ContentTransferEncoding
- {
- get{return _contentTransferEncoding;}
- }
- /// <summary>
- /// Message Bodies
- /// </summary>
- public ArrayList MessageBody
- {
- get{return _messageBody;}
- }
- /// <summary>
- /// Attachment Boundry
- /// </summary>
- public string AttachmentBoundry
- {
- get{return _attachmentboundry;}
- }
- /// <summary>
- /// Alternate Attachment Boundry
- /// </summary>
- public string AttachmentBoundry2
- {
- get{return _attachmentboundry2;}
- }
- /// <summary>
- /// Attachment Count
- /// </summary>
- public int AttachmentCount
- {
- get{return _attachmentCount;}
- }
- public int RealAttachmentCount
- {
- get { return _realAttachmentCount; }
- }
- /// <summary>
- /// Attachments
- /// </summary>
- public ArrayList Attachments
- {
- get{return _attachments;}
- }
- /// <summary>
- /// CC
- /// </summary>
- public string[] CC
- {
- get{return _cc;}
- }
- /// <summary>
- /// BCC
- /// </summary>
- public string[] BCC
- {
- get{return _bcc;}
- }
- /// <summary>
- /// TO
- /// </summary>
- public string[] TO
- {
- get{return _to;}
- }
- /// <summary>
- /// Content Encoding
- /// </summary>
- public string ContentEncoding
- {
- get{return _contentEncoding;}
- }
- /// <summary>
- /// Content Length
- /// </summary>
- public long ContentLength
- {
- get{return _contentLength;}
- }
- /// <summary>
- /// Content Type
- /// </summary>
- public string ContentType
- {
- get{return _contentType;}
- }
- /// <summary>
- /// Report Type
- /// </summary>
- public string ReportType
- {
- get{return _reportType;}
- }
- /// <summary>
- /// HTML
- /// </summary>
- public bool HTML
- {
- get{return _html;}
- }
- /// <summary>
- /// Date
- /// </summary>
- public string Date
- {
- get{return _date;}
- }
- /// <summary>
- /// DateTime Info
- /// </summary>
- public string DateTimeInfo
- {
- get{return _dateTimeInfo;}
- }
- /// <summary>
- /// From name
- /// </summary>
- public string From
- {
- get{return _from;}
- }
- /// <summary>
- /// From Email
- /// </summary>
- public string FromEmail
- {
- get{return _fromEmail;}
- }
- /// <summary>
- /// Reply to name
- /// </summary>
- public string ReplyTo
- {
- get{return _replyTo;}
- }
- /// <summary>
- /// Reply to email
- /// </summary>
- public string ReplyToEmail
- {
- get{return _replyToEmail;}
- }
- /// <summary>
- /// whether has attachment
- /// </summary>
- public bool HasAttachment
- {
- get{return _hasAttachment;}
- }
- public bool HasRealAttachment
- {
- get { return _hasRealAttachment; }
- }
- /// <summary>
- /// raw message body
- /// </summary>
- public string RawMessageBody
- {
- get{return _rawMessageBody;}
- }
- /// <summary>
- /// Message ID
- /// </summary>
- public string MessageID
- {
- get{return _messageID;}
- }
- /// <summary>
- /// MIME version
- /// </summary>
- public string MimeVersion
- {
- get{return _mimeVersion;}
- }
- /// <summary>
- /// raw header
- /// </summary>
- public string RawHeader
- {
- get{return _rawHeader;}
- }
- /// <summary>
- /// raw message
- /// </summary>
- public string RawMessage
- {
- get{return _rawMessage;}
- }
- /// <summary>
- /// return path
- /// </summary>
- public string ReturnPath
- {
- get{return _returnPath;}
- }
- /// <summary>
- /// subject
- /// </summary>
- public string Subject
- {
- get{return _subject;}
- }
- #endregion
- /// <summary>
- /// release all objects
- /// </summary>
- ~Message()
- {
- _attachments.Clear();
- _attachments=null;
- _keywords.Clear();
- _keywords=null;
- _messageBody.Clear();
- _messageBody=null;
- _customHeaders.Clear();
- _customHeaders=null;
- }
- /// <summary>
- /// New Message
- /// </summary>
- /// <param name="blnFinish">reference for the finishing state</param>
- /// <param name="strBasePath">path to extract MS-TNEF attachment files</param>
- /// <param name="blnAutoDecodeMSTNEF">whether auto decoding MS-TNEF attachments</param>
- /// <param name="blnOnlyHeader">whether only decode the header without body</param>
- /// <param name="strEMLFile">file of email content to load from</param>
- public Message(ref bool blnFinish, string strBasePath, bool blnAutoDecodeMSTNEF, bool blnOnlyHeader, string strEMLFile)
- {
- string strMessage=null;
- if(Utility.ReadPlainTextFromFile(strEMLFile,ref strMessage))
- {
- NewMessage(ref blnFinish,strBasePath,blnAutoDecodeMSTNEF,strMessage,blnOnlyHeader);
- }
- else
- blnFinish=true;
- }
- /// <summary>
- /// New Message
- /// </summary>
- /// <param name="blnFinish">reference for the finishing state</param>
- /// <param name="strBasePath">path to extract MS-TNEF attachment files</param>
- /// <param name="blnAutoDecodeMSTNEF">whether auto decoding MS-TNEF attachments</param>
- /// <param name="strMessage">raw message content</param>
- /// <param name="blnOnlyHeader">whether only decode the header without body</param>
- public Message(ref bool blnFinish, string strBasePath, bool blnAutoDecodeMSTNEF, string strMessage, bool blnOnlyHeader)
- {
- NewMessage(ref blnFinish,strBasePath,blnAutoDecodeMSTNEF,strMessage,blnOnlyHeader);
- }
- /// <summary>
- /// New Message
- /// </summary>
- /// <param name="blnFinish">reference for the finishing state</param>
- /// <param name="strMessage">raw message content</param>
- /// <param name="blnOnlyHeader">whether only decode the header without body</param>
- public Message(ref bool blnFinish, string strMessage, bool blnOnlyHeader)
- {
- NewMessage(ref blnFinish,"",false,strMessage,blnOnlyHeader);
- }
- /// <summary>
- /// New Message
- /// </summary>
- /// <param name="blnFinish">reference for the finishing state</param>
- /// <param name="strMessage">raw message content</param>
- public Message(ref bool blnFinish, string strMessage)
- {
- NewMessage(ref blnFinish,"",false,strMessage,false);
- }
- /// <summary>
- /// get valid attachment
- /// </summary>
- /// <param name="intAttachmentNumber">attachment index in the attachments collection</param>
- /// <returns>attachment</returns>
- public Attachment GetAttachment(int intAttachmentNumber)
- {
- if(intAttachmentNumber<0 || intAttachmentNumber>_attachmentCount || intAttachmentNumber>_attachments.Count)
- {
- Utility.LogError("GetAttachment():attachment not exist");
- throw new ArgumentOutOfRangeException("intAttachmentNumber");
- }
- return (Attachment)_attachments[intAttachmentNumber];
- }
- /// <summary>
- /// New Message
- /// </summary>
- /// <param name="blnFinish">reference for the finishing state</param>
- /// <param name="strBasePath">path to extract MS-TNEF attachment files</param>
- /// <param name="blnAutoDecodeMSTNEF">whether auto decoding MS-TNEF attachments</param>
- /// <param name="strMessage">raw message content</param>
- /// <param name="blnOnlyHeader">whether only decode the header without body</param>
- /// <returns>construction result whether successfully new a message</returns>
- private bool NewMessage(ref bool blnFinish, string strBasePath, bool blnAutoDecodeMSTNEF, string strMessage, bool blnOnlyHeader)
- {
- StringReader srdReader=new StringReader(strMessage);
- StringBuilder sbdBuilder=new StringBuilder();
- _basePath=strBasePath;
- _autoDecodeMSTNEF=blnAutoDecodeMSTNEF;
- _rawMessage=strMessage;
- string strLine=srdReader.ReadLine();
- while(Utility.IsNotNullTextEx(strLine))
- {
- sbdBuilder.Append(strLine + "rn");
- ParseHeader(sbdBuilder,srdReader,ref strLine);
- if(Utility.IsOrNullTextEx(strLine))
- break;
- else
- strLine=srdReader.ReadLine();
- }
- _rawHeader=sbdBuilder.ToString();
- SetAttachmentBoundry2(_rawHeader);
- if(_contentLength==0)
- _contentLength=strMessage.Length;//_rawMessageBody.Length;
- if(blnOnlyHeader==false)
- {
- _rawMessageBody=srdReader.ReadToEnd().Trim();
- //the auto reply mail by outlook uses ms-tnef format
- if((_hasAttachment==true && _attachmentboundry!=null)||MIMETypes.IsMSTNEF(_contentType))
- {
- set_attachments();
- if (this.Attachments.Count>0)
- {
- Attachment at=this.GetAttachment(0);
- if(at!=null&&at.NotAttachment)
- this.GetMessageBody(at.DecodeAsText());
- else
- {}
- //in case body parts as text[0] html[1]
- if(this.Attachments.Count>1&&!this.IsReport())
- {
- at=this.GetAttachment(1);
- if(at!=null&&at.NotAttachment)
- this.GetMessageBody(at.DecodeAsText());
- else
- {}
- }
- }
- else
- {}
- }
- else
- {
- GetMessageBody(_rawMessageBody);
- }
- }
- blnFinish=true;
- return true;
- }
- /// <summary>
- /// parse message body
- /// </summary>
- /// <param name="strBuffer">raw message body</param>
- /// <returns>message body</returns>
- public string GetTextBody(string strBuffer)
- {
- if(strBuffer.EndsWith("rn."))
- return strBuffer.Substring(0,strBuffer.Length-"rn.".Length);
- else
- return strBuffer;
- }
- /// <summary>
- /// parse message body
- /// </summary>
- /// <param name="strBuffer">raw message body</param>
- public void GetMessageBody(string strBuffer)
- {
- int end, begin;
- string body;
- string encoding="";
- begin = end = 0;
- _messageBody.Clear();
- try
- {
- if(Utility.IsOrNullTextEx(strBuffer))
- return;
- else if(Utility.IsOrNullTextEx(_contentType) && _contentTransferEncoding==null)
- {
- _messageBody.Add(GetTextBody(strBuffer));
- }
- else if(_contentType!=null && _contentType.IndexOf("digest") >= 0)
- {
- // this is a digest method
- //ParseDigestMessage(strBuffer);
- _messageBody.Add(GetTextBody(strBuffer));
- }
- else if(_attachmentboundry2==null)
- {
- body=GetTextBody(strBuffer);
- if(Utility.IsQuotedPrintable(_contentTransferEncoding))
- {
- body=DecodeQP.ConvertHexContent(body);
- }
- else if(Utility.IsBase64(_contentTransferEncoding))
- {
- body=Utility.deCodeB64s(Utility.RemoveNonB64(body));
- }
- else if(Utility.IsNotNullText(_contentCharset))
- {
- body=Encoding.GetEncoding(_contentCharset).GetString(Encoding.Default.GetBytes(body));
- }
- _messageBody.Add(Utility.RemoveNonB64(body));
- }
- else
- {
- begin =0;
- while(begin!=-1)
- {
- // find "rnrn" denoting end of header
- begin = strBuffer.IndexOf("--" + _attachmentboundry2,begin);
- if(begin!=-1)
- {
- encoding=MIMETypes.GetContentTransferEncoding(strBuffer,begin);
- begin = strBuffer.IndexOf("rnrn",begin+1);//strBuffer.LastIndexOfAny(ALPHABET.ToCharArray());
- // find end of text
- end = strBuffer.IndexOf("--" + _attachmentboundry2,begin+1);
- if(begin!=-1)
- {
- if(end!=-1)
- {
- begin += 4;
- if(begin>=end)
- continue;
- else if (this._contentEncoding!=null && this._contentEncoding.IndexOf("8bit")!=-1)
- body=Utility.Change(strBuffer.Substring(begin, end - begin-2 ),_contentCharset);
- else
- body=strBuffer.Substring(begin, end - begin-2);
- }
- else
- {
- body=strBuffer.Substring(begin);
- }
- if(Utility.IsQuotedPrintable(encoding))
- {
- string ret=body;
- ret=DecodeQP.ConvertHexContent(ret);
- _messageBody.Add(ret);
- }
- else if(Utility.IsBase64(encoding))
- {
- string ret=Utility.RemoveNonB64(body);
- ret=Utility.deCodeB64s(ret);
- if(ret!="