给 OpenPOP.Net 加一个小功能,可用于收取邮件时监测数据流量!

/*
最近写了一个自动收邮件的机器人,原来一开始偷懒 "娶" 了 COM 组件 JMail:
《 封装 JMail 4.4 的 POP3 为 .Net 组件 (.dll 程序集),实现 "邮件(附件) 到达" 等 "事件"! 》
后来经人介绍认识了 OpenPOP.Net
我就 移情别恋 ,再后来我们就相爱了,再后来我就 修理她 :
加一个小功能( 红色字体代码部分 ),可用于 收取邮件时监测数据流量 !

老规矩: 我的代码随便 Copy & Paste 到任意一个 .cs 文件中 csc 即可测试! (结构不好,目的就是方便测试代码)

*/
//OpenPOP.Net
namespace OpenPOP.MIMEParser
{
using System;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections;
using System.Globalization;

///

1<summary>   
2/// Summary description for Attachment.   
3/// </summary>

public class Attachment : IComparable
{
#region Member Variables

private string _contentType = null;
private string _contentCharset = null;
private string _contentFormat = null;
private string _contentTransferEncoding = null;
private string _contentDescription = null;
private string _contentDisposition = null;
private string _contentFileName = "";
private string _defaultFileName = "body.htm";
private string _defaultFileName2 = "body*.htm";
private string _defaultReportFileName = "report.htm";
private string _defaultMIMEFileName = "body.eml";
private string _defaultMSTNEFFileName = "winmail.dat";
private string _contentID = null;
private long _contentLength = 0;
private string _rawAttachment = null;
private bool _inBytes = false;
private byte[] _rawBytes = null;

#endregion

#region Properties

///

1<summary>   
2/// raw attachment content bytes   
3/// </summary>

public byte[] RawBytes
{
get
{
return _rawBytes;
}
set
{
_rawBytes = value;
}
}

///

1<summary>   
2/// whether attachment is in bytes   
3/// </summary>

public bool InBytes
{
get
{
return _inBytes;
}
set
{
_inBytes = value;
}
}

///

1<summary>   
2/// Content length   
3/// </summary>

public long ContentLength
{
get
{
return _contentLength;
}
}

///

1<summary>   
2/// verify the attachment whether it is a real attachment or not   
3/// </summary>

///

1<remarks>this is so far not comprehensive and needs more work to finish</remarks>

public bool NotAttachment
{
get
{
/* if (_contentDisposition==null||_contentType==null)
return true;
else
return (_contentDisposition.IndexOf("attachment")==-1 && _contentType.IndexOf("text/plain")!=-1); /
/
if (_contentType==null)
return true;
else
return (_contentFileName!="");*/
if ((_contentType == null || _contentFileName == "") && _contentID == null) //&&_contentType.ToLower().IndexOf("text/")!=-1)
return true;
else
return false;

}
}

///

1<summary>   
2/// Content format   
3/// </summary>

public string ContentFormat
{
get
{
return _contentFormat;
}
}

///

1<summary>   
2/// Content charset   
3/// </summary>

public string ContentCharset
{
get
{
return _contentCharset;
}
}

///

1<summary>   
2/// default file name   
3/// </summary>

public string DefaultFileName
{
get
{
return _defaultFileName;
}
set
{
_defaultFileName = value;
}
}

///

1<summary>   
2/// default file name 2   
3/// </summary>

public string DefaultFileName2
{
get
{
return _defaultFileName2;
}
set
{
_defaultFileName2 = value;
}
}

///

1<summary>   
2/// default report file name   
3/// </summary>

public string DefaultReportFileName
{
get
{
return _defaultReportFileName;
}
set
{
_defaultReportFileName = value;
}
}

///

1<summary>   
2/// default MIME File Name   
3/// </summary>

public string DefaultMIMEFileName
{
get
{
return _defaultMIMEFileName;
}
set
{
_defaultMIMEFileName = value;
}
}

///

1<summary>   
2/// Content Type   
3/// </summary>

public string ContentType
{
get
{
return _contentType;
}
}

///

1<summary>   
2/// Content Transfer Encoding   
3/// </summary>

public string ContentTransferEncoding
{
get
{
return _contentTransferEncoding;
}
}

///

1<summary>   
2/// Content Description   
3/// </summary>

public string ContentDescription
{
get
{
return _contentDescription;
}
}

///

1<summary>   
2/// Content File Name   
3/// </summary>

public string ContentFileName
{
get
{
return _contentFileName;
}
set
{
_contentFileName = value;
}
}

///

1<summary>   
2/// Content Disposition   
3/// </summary>

public string ContentDisposition
{
get
{
return _contentDisposition;
}
}

///

1<summary>   
2/// Content ID   
3/// </summary>

public string ContentID
{
get
{
return _contentID;
}
}

///

1<summary>   
2/// Raw Attachment   
3/// </summary>

public string RawAttachment
{
get
{
return _rawAttachment;
}
}

///

1<summary>   
2/// decoded attachment in bytes   
3/// </summary>

public byte[] DecodedAttachment
{
get
{
return DecodedAsBytes();
}
}

#endregion

///

1<summary>   
2/// release all objects   
3/// </summary>

~Attachment()
{
_rawBytes = null;
_rawAttachment = null;
}

///

1<summary>   
2/// New Attachment   
3/// </summary>

///

1<param name="bytAttachment"/>

attachment bytes content
///

1<param name="lngFileLength"/>

file length
///

1<param name="strFileName"/>

file name
///

1<param name="strContentType"/>

content type
public Attachment(byte[] bytAttachment, long lngFileLength, string strFileName, string strContentType)
{
_inBytes = true;
_rawBytes = bytAttachment;
_contentLength = lngFileLength;
_contentFileName = strFileName;
_contentType = strContentType;
}

///

1<summary>   
2/// New Attachment   
3/// </summary>

///

1<param name="bytAttachment"/>

attachment bytes content
///

1<param name="strFileName"/>

file name
///

1<param name="strContentType"/>

content type
public Attachment(byte[] bytAttachment, string strFileName, string strContentType)
{
_inBytes = true;
_rawBytes = bytAttachment;
_contentLength = bytAttachment.Length;
_contentFileName = strFileName;
_contentType = strContentType;
}

///

1<summary>   
2/// New Attachment   
3/// </summary>

///

1<param name="strAttachment"/>

attachment content
///

1<param name="strContentType"/>

content type
///

1<param name="blnParseHeader"/>

whether only parse the header or not
public Attachment(string strAttachment, string strContentType, bool blnParseHeader)
{
if (!blnParseHeader)
{
_contentFileName = _defaultMSTNEFFileName;
_contentType = strContentType;
}
this.NewAttachment(strAttachment, blnParseHeader);
}

///

1<summary>   
2/// New Attachment   
3/// </summary>

///

1<param name="strAttachment"/>

attachment content
public Attachment(string strAttachment)
{
this.NewAttachment(strAttachment, true);
}

///

1<summary>   
2/// create attachment   
3/// </summary>

///

1<param name="strAttachment"/>

raw attachment text
///

1<param name="blnParseHeader"/>

parse header
private void NewAttachment(string strAttachment, bool blnParseHeader)
{
_inBytes = false;

if (strAttachment == null)
throw new ArgumentNullException("strAttachment");

StringReader srReader = new StringReader(strAttachment);

if (blnParseHeader)
{
string strLine = srReader.ReadLine();
while (Utility.IsNotNullTextEx(strLine))
{
ParseHeader(srReader, ref strLine);
if (Utility.IsOrNullTextEx(strLine))
break;
else
strLine = srReader.ReadLine();
}
}

this._rawAttachment = srReader.ReadToEnd();
_contentLength = this._rawAttachment.Length;
}

///

1<summary>   
2/// Parse header fields and set member variables   
3/// </summary>

///

1<param name="srReader"/>

string reader
///

1<param name="strLine"/>

header line
private void ParseHeader(StringReader srReader, ref string strLine)
{
string[] array = Utility.GetHeadersValue(strLine); //Regex.Split(strLine,":");
string[] values = Regex.Split(array[1], ";"); //array[1].Split(';');
string strRet = null;

switch (array[0].ToUpper())
{
case "CONTENT-TYPE":
if (values.Length > 0)
_contentType = values[0].Trim();
if (values.Length > 1)
{
_contentCharset = Utility.GetQuotedValue(values[1], "=", "charset");
}
if (values.Length > 2)
{
_contentFormat = Utility.GetQuotedValue(values[2], "=", "format");
}
_contentFileName = Utility.ParseFileName(strLine);
if (_contentFileName == "")
{
strRet = srReader.ReadLine();
if (strRet == "")
{
strLine = "";
break;
}
_contentFileName = Utility.ParseFileName(strLine);
if (_contentFileName == "")
ParseHeader(srReader, ref strRet);
}
break;
case "CONTENT-TRANSFER-ENCODING":
_contentTransferEncoding = Utility.SplitOnSemiColon(array[1])[0].Trim();
break;
case "CONTENT-DESCRIPTION":
_contentDescription = Utility.DecodeText(Utility.SplitOnSemiColon(array[1])[0].Trim());
break;
case "CONTENT-DISPOSITION":
if (values.Length > 0)
_contentDisposition = values[0].Trim();

///

   1<bug>reported by grandepuffo @ https://sourceforge.net/forum/message.php?msg_id=2589759   
   2//_contentFileName=values[1];   
   3if (values.Length &gt; 1)   
   4{   
   5_contentFileName = values[1];   
   6}   
   7else   
   8{   
   9_contentFileName = "";   
  10} 
  11
  12if (_contentFileName == "")   
  13_contentFileName = srReader.ReadLine(); 
  14
  15_contentFileName = _contentFileName.Replace("\t", "");   
  16_contentFileName = Utility.GetQuotedValue(_contentFileName, "=", "filename");   
  17_contentFileName = Utility.DecodeText(_contentFileName);   
  18break;   
  19case "CONTENT-ID":   
  20_contentID = Utility.SplitOnSemiColon(array[1])[0].Trim('&lt;').Trim('&gt;');   
  21break;   
  22}   
  23} 
  24
  25/// <summary>   
  26/// verify the encoding   
  27/// </summary>   
  28/// <param name="encoding"/>encoding to verify   
  29/// <returns>true if encoding</returns>   
  30private bool IsEncoding(string encoding)   
  31{   
  32return _contentTransferEncoding.ToLower().IndexOf(encoding.ToLower()) != -1;   
  33} 
  34
  35/// <summary>   
  36/// Decode the attachment to text   
  37/// </summary>   
  38/// <returns>Decoded attachment text</returns>   
  39public string DecodeAsText()   
  40{   
  41string decodedAttachment = null; 
  42
  43try   
  44{   
  45if (_contentType.ToLower() == "message/rfc822".ToLower())   
  46decodedAttachment = Utility.DecodeText(_rawAttachment);   
  47else if (_contentTransferEncoding != null)   
  48{   
  49decodedAttachment = _rawAttachment; 
  50
  51if (!IsEncoding("7bit"))   
  52{   
  53if (IsEncoding("8bit") &amp;&amp; _contentCharset != null &amp; _contentCharset != "")   
  54decodedAttachment = Utility.Change(decodedAttachment, _contentCharset); 
  55
  56if (Utility.IsQuotedPrintable(_contentTransferEncoding))   
  57decodedAttachment = DecodeQP.ConvertHexContent(decodedAttachment);   
  58else if (IsEncoding("8bit"))   
  59decodedAttachment = decodedAttachment;   
  60else   
  61decodedAttachment = Utility.deCodeB64s(Utility.RemoveNonB64(decodedAttachment));   
  62}   
  63}   
  64else if (_contentCharset != null)   
  65decodedAttachment = Utility.Change(_rawAttachment, _contentCharset); //Encoding.Default.GetString(Encoding.GetEncoding(_contentCharset).GetBytes(_rawAttachment));   
  66else   
  67decodedAttachment = _rawAttachment;   
  68}   
  69catch   
  70{   
  71decodedAttachment = _rawAttachment;   
  72}   
  73return decodedAttachment;   
  74} 
  75
  76/// <summary>   
  77/// decode attachment to be a message object   
  78/// </summary>   
  79/// <returns>message</returns>   
  80public Message DecodeAsMessage()   
  81{   
  82bool blnRet = false;   
  83return new Message(ref blnRet, "", false, _rawAttachment, false);   
  84} 
  85
  86/// <summary>   
  87/// Decode the attachment to bytes   
  88/// </summary>   
  89/// <returns>Decoded attachment bytes</returns>   
  90public byte[] DecodedAsBytes()   
  91{   
  92if (_rawAttachment == null)   
  93return null;   
  94if (_contentFileName != "")   
  95{   
  96byte[] decodedBytes = null; 
  97
  98if (_contentType != null &amp;&amp; _contentType.ToLower() == "message/rfc822".ToLower())   
  99decodedBytes = Encoding.Default.GetBytes(Utility.DecodeText(_rawAttachment));   
 100else if (_contentTransferEncoding != null)   
 101{   
 102string bytContent = _rawAttachment; 
 103
 104if (!IsEncoding("7bit"))   
 105{   
 106if (IsEncoding("8bit") &amp;&amp; _contentCharset != null &amp; _contentCharset != "")   
 107bytContent = Utility.Change(bytContent, _contentCharset); 
 108
 109if (Utility.IsQuotedPrintable(_contentTransferEncoding))   
 110decodedBytes = Encoding.Default.GetBytes(DecodeQP.ConvertHexContent(bytContent));   
 111else if (IsEncoding("8bit"))   
 112decodedBytes = Encoding.Default.GetBytes(bytContent);   
 113else   
 114decodedBytes = Convert.FromBase64String(Utility.RemoveNonB64(bytContent));   
 115}   
 116else   
 117decodedBytes = Encoding.Default.GetBytes(bytContent);   
 118}   
 119else if (_contentCharset != null)   
 120decodedBytes = Encoding.Default.GetBytes(Utility.Change(_rawAttachment, _contentCharset)); //Encoding.Default.GetString(Encoding.GetEncoding(_contentCharset).GetBytes(_rawAttachment));   
 121else   
 122decodedBytes = Encoding.Default.GetBytes(_rawAttachment); 
 123
 124return decodedBytes;   
 125}   
 126else   
 127{   
 128return null;   
 129}   
 130} 
 131
 132public int CompareTo(object attachment)   
 133{   
 134return (this.RawAttachment.CompareTo(((Attachment) (attachment)).RawAttachment));   
 135}   
 136} 
 137
 138public enum MessageImportanceType   
 139{   
 140HIGH = 5,   
 141NORMAL = 3,   
 142LOW = 1   
 143} 
 144
 145/// <summary>   
 146/// Decoding Quoted-Printable text   
 147///   
 148/// </summary>   
 149public class DecodeQP   
 150{   
 151public DecodeQP()   
 152{   
 153} 
 154
 155/// <summary>   
 156/// Decoding Quoted-Printable string   
 157/// </summary>   
 158/// <param name="Hexstring"/>Quoted-Printable encoded string   
 159/// <param name="encode"/>encoding method   
 160/// <returns>decoded string</returns>   
 161public static string ConvertHexToString(string Hexstring, string Encoding)   
 162{   
 163try   
 164{   
 165return ConvertHexToString(Hexstring, System.Text.Encoding.GetEncoding(Encoding));   
 166}   
 167catch   
 168{   
 169return ConvertHexContent(Hexstring);   
 170}   
 171} 
 172
 173/// <summary>   
 174/// Decoding Quoted-Printable string   
 175/// </summary>   
 176/// <param name="Hexstring"/>Quoted-Printable encoded string   
 177/// <param name="encode"/>encoding method   
 178/// <returns>decoded string</returns>   
 179public static string ConvertHexToString(string Hexstring, Encoding encode)   
 180{   
 181try   
 182{   
 183if (Hexstring == null || Hexstring.Equals("")) return ""; 
 184
 185if (Hexstring.StartsWith("=")) Hexstring = Hexstring.Substring(1); 
 186
 187string[] aHex = Hexstring.Split(new char[1] {'='});   
 188byte[] abyte = new Byte[aHex.Length]; 
 189
 190for (int i = 0; i &lt; abyte.Length; i++)   
 191{   
 192// Console.WriteLine(aHex[i]);   
 193abyte[i] = (byte) int.Parse(aHex[i], NumberStyles.HexNumber);   
 194}   
 195return encode.GetString(abyte);   
 196}   
 197catch   
 198{   
 199return Hexstring;   
 200}   
 201} 
 202
 203/// <summary>   
 204/// Decoding Quoted-Printable string at a position   
 205/// </summary>   
 206/// <param name="Hexstring"/>Quoted-Printable encoded string   
 207/// <param name="encode"/>encoding method, "Default" is suggested   
 208/// <param name="nStart"/>position to start, normally 0   
 209/// <returns>decoded string</returns>   
 210public static string ConvertHexContent(string Hexstring, Encoding encode, long nStart)   
 211{   
 212if (nStart &gt;= Hexstring.Length) return Hexstring; 
 213
 214//to hold string to be decoded   
 215StringBuilder sbHex = new StringBuilder();   
 216sbHex.Append("");   
 217//to hold decoded string   
 218StringBuilder sbEncoded = new StringBuilder();   
 219sbEncoded.Append("");   
 220//wether we reach Quoted-Printable string   
 221bool isBegin = false;   
 222string temp;   
 223int i = (int) nStart; 
 224
 225while (i &lt; Hexstring.Length)   
 226{   
 227//init next loop   
 228sbHex.Remove(0, sbHex.Length);   
 229isBegin = false;   
 230int count = 0; 
 231
 232while (i &lt; Hexstring.Length)   
 233{   
 234temp = Hexstring.Substring(i, 1); //before reaching Quoted-Printable string, one char at a time   
 235if (temp.StartsWith("="))   
 236{   
 237temp = Hexstring.Substring(i, 3); //get 3 chars   
 238if (temp.EndsWith("\r\n")) //return char   
 239{   
 240if (isBegin &amp;&amp; (count%2 == 0))   
 241break;   
 242// sbEncoded.Append("");   
 243i = i + 3;   
 244}   
 245else if (!temp.EndsWith("3D"))   
 246{   
 247sbHex.Append(temp);   
 248isBegin = true; //we reach Quoted-Printable string, put it into buffer   
 249i = i + 3;   
 250count++;   
 251}   
 252else //if it ends with 3D, it is "="   
 253{   
 254if (isBegin &amp;&amp; (count%2 == 0)) //wait until even items to handle all character sets   
 255break; 
 256
 257sbEncoded.Append("=");   
 258i = i + 3;   
 259} 
 260
 261}   
 262else   
 263{   
 264if (isBegin) //we have got the how Quoted-Printable string, break it   
 265break;   
 266sbEncoded.Append(temp); //not Quoted-Printable string, put it into buffer   
 267i++;   
 268} 
 269
 270}   
 271//decode Quoted-Printable string   
 272sbEncoded.Append(ConvertHexToString(sbHex.ToString(), encode));   
 273} 
 274
 275return sbEncoded.ToString();   
 276} 
 277
 278  
 279/// <summary>   
 280/// Decoding Quoted-Printable string using default encoding and begin at 0   
 281/// </summary>   
 282/// <param name="Hexstring"/>Quoted-Printable encoded string   
 283/// <returns>decoded string</returns>   
 284public static string ConvertHexContent(string Hexstring)   
 285{   
 286if (Hexstring == null || Hexstring.Equals("")) return Hexstring; 
 287
 288return ConvertHexContent(Hexstring, Encoding.Default, 0); 
 289
 290}   
 291} 
 292
 293/// <summary>   
 294/// Message Parser.   
 295/// </summary>   
 296public class Message   
 297{   
 298#region Member Variables 
 299
 300private ArrayList _attachments = new ArrayList();   
 301private string _rawHeader = null;   
 302private string _rawMessage = null;   
 303private string _rawMessageBody = null;   
 304private int _attachmentCount = 0;   
 305private string _replyTo = null;   
 306private string _replyToEmail = null;   
 307private string _from = null;   
 308private string _fromEmail = null;   
 309private string _date = null;   
 310private string _dateTimeInfo = null;   
 311private string _subject = null;   
 312private string[] _to = new string[0];   
 313private string[] _cc = new string[0];   
 314private string[] _bcc = new string[0];   
 315private ArrayList _keywords = new ArrayList();   
 316private string _contentType = null;   
 317private string _contentCharset = null;   
 318private string _reportType = null;   
 319private string _contentTransferEncoding = null;   
 320private bool _html = false;   
 321private long _contentLength = 0;   
 322private string _contentEncoding = null;   
 323private string _returnPath = null;   
 324private string _mimeVersion = null;   
 325private string _received = null;   
 326private string _importance = null;   
 327private string _messageID = null;   
 328private string _attachmentboundry = null;   
 329private string _attachmentboundry2 = null;   
 330private bool _hasAttachment = false;   
 331private string _dispositionNotificationTo = null;   
 332private ArrayList _messageBody = new ArrayList();   
 333private string _basePath = null;   
 334private bool _autoDecodeMSTNEF = false;   
 335private Hashtable _customHeaders = new Hashtable(); 
 336
 337#endregion 
 338
 339#region Properties 
 340
 341/// <summary>   
 342/// custom headers   
 343/// </summary>   
 344public Hashtable CustomHeaders   
 345{   
 346get   
 347{   
 348return _customHeaders;   
 349}   
 350set   
 351{   
 352_customHeaders = value;   
 353}   
 354} 
 355
 356/// <summary>   
 357/// whether auto decoding MS-TNEF attachment files   
 358/// </summary>   
 359public bool AutoDecodeMSTNEF   
 360{   
 361get   
 362{   
 363return _autoDecodeMSTNEF;   
 364}   
 365set   
 366{   
 367_autoDecodeMSTNEF = value;   
 368}   
 369} 
 370
 371/// <summary>   
 372/// path to extract MS-TNEF attachment files   
 373/// </summary>   
 374public string BasePath   
 375{   
 376get   
 377{   
 378return _basePath;   
 379}   
 380set   
 381{   
 382try   
 383{   
 384if (value.EndsWith("\\\"))   
 385_basePath = value;   
 386else   
 387_basePath = value + "\\\";   
 388}   
 389catch   
 390{   
 391}   
 392}   
 393} 
 394
 395/// <summary>   
 396/// message keywords   
 397/// </summary>   
 398public ArrayList Keywords   
 399{   
 400get   
 401{   
 402return _keywords;   
 403}   
 404} 
 405
 406/// <summary>   
 407/// disposition notification   
 408/// </summary>   
 409public string DispositionNotificationTo   
 410{   
 411get   
 412{   
 413return _dispositionNotificationTo;   
 414}   
 415} 
 416
 417/// <summary>   
 418/// received server   
 419/// </summary>   
 420public string Received   
 421{   
 422get   
 423{   
 424return _received;   
 425}   
 426} 
 427
 428/// <summary>   
 429/// importance level   
 430/// </summary>   
 431public string Importance   
 432{   
 433get   
 434{   
 435return _importance;   
 436}   
 437} 
 438
 439/// <summary>   
 440/// importance level type   
 441/// </summary>   
 442public MessageImportanceType ImportanceType   
 443{   
 444get   
 445{   
 446switch (_importance.ToUpper())   
 447{   
 448case "5":   
 449case "HIGH":   
 450return MessageImportanceType.HIGH;   
 451case "3":   
 452case "NORMAL":   
 453return MessageImportanceType.NORMAL;   
 454case "1":   
 455case "LOW":   
 456return MessageImportanceType.LOW;   
 457default:   
 458return MessageImportanceType.NORMAL;   
 459}   
 460}   
 461} 
 462
 463/// <summary>   
 464/// Content Charset   
 465/// </summary>   
 466public string ContentCharset   
 467{   
 468get   
 469{   
 470return _contentCharset;   
 471}   
 472} 
 473
 474/// <summary>   
 475/// Content Transfer Encoding   
 476/// </summary>   
 477public string ContentTransferEncoding   
 478{   
 479get   
 480{   
 481return _contentTransferEncoding;   
 482}   
 483} 
 484
 485/// <summary>   
 486/// Message Bodies   
 487/// </summary>   
 488public ArrayList MessageBody   
 489{   
 490get   
 491{   
 492return _messageBody;   
 493}   
 494} 
 495
 496/// <summary>   
 497/// Attachment Boundry   
 498/// </summary>   
 499public string AttachmentBoundry   
 500{   
 501get   
 502{   
 503return _attachmentboundry;   
 504}   
 505} 
 506
 507/// <summary>   
 508/// Alternate Attachment Boundry   
 509/// </summary>   
 510public string AttachmentBoundry2   
 511{   
 512get   
 513{   
 514return _attachmentboundry2;   
 515}   
 516} 
 517
 518/// <summary>   
 519/// Attachment Count   
 520/// </summary>   
 521public int AttachmentCount   
 522{   
 523get   
 524{   
 525return _attachmentCount;   
 526}   
 527} 
 528
 529/// <summary>   
 530/// Attachments   
 531/// </summary>   
 532public ArrayList Attachments   
 533{   
 534get   
 535{   
 536return _attachments;   
 537}   
 538} 
 539
 540/// <summary>   
 541/// CC   
 542/// </summary>   
 543public string[] CC   
 544{   
 545get   
 546{   
 547return _cc;   
 548}   
 549} 
 550
 551/// <summary>   
 552/// BCC   
 553/// </summary>   
 554public string[] BCC   
 555{   
 556get   
 557{   
 558return _bcc;   
 559}   
 560} 
 561
 562/// <summary>   
 563/// TO   
 564/// </summary>   
 565public string[] TO   
 566{   
 567get   
 568{   
 569return _to;   
 570}   
 571} 
 572
 573/// <summary>   
 574/// Content Encoding   
 575/// </summary>   
 576public string ContentEncoding   
 577{   
 578get   
 579{   
 580return _contentEncoding;   
 581}   
 582} 
 583
 584/// <summary>   
 585/// Content Length   
 586/// </summary>   
 587public long ContentLength   
 588{   
 589get   
 590{   
 591return _contentLength;   
 592}   
 593} 
 594
 595/// <summary>   
 596/// Content Type   
 597/// </summary>   
 598public string ContentType   
 599{   
 600get   
 601{   
 602return _contentType;   
 603}   
 604} 
 605
 606/// <summary>   
 607/// Report Type   
 608/// </summary>   
 609public string ReportType   
 610{   
 611get   
 612{   
 613return _reportType;   
 614}   
 615} 
 616
 617/// <summary>   
 618/// HTML   
 619/// </summary>   
 620public bool HTML   
 621{   
 622get   
 623{   
 624return _html;   
 625}   
 626} 
 627
 628/// <summary>   
 629/// Date   
 630/// </summary>   
 631public string Date   
 632{   
 633get   
 634{   
 635return _date;   
 636}   
 637} 
 638
 639/// <summary>   
 640/// DateTime Info   
 641/// </summary>   
 642public string DateTimeInfo   
 643{   
 644get   
 645{   
 646return _dateTimeInfo;   
 647}   
 648} 
 649
 650/// <summary>   
 651/// From name   
 652/// </summary>   
 653public string From   
 654{   
 655get   
 656{   
 657return _from;   
 658}   
 659} 
 660
 661/// <summary>   
 662/// From Email   
 663/// </summary>   
 664public string FromEmail   
 665{   
 666get   
 667{   
 668return _fromEmail;   
 669}   
 670} 
 671
 672/// <summary>   
 673/// Reply to name   
 674/// </summary>   
 675public string ReplyTo   
 676{   
 677get   
 678{   
 679return _replyTo;   
 680}   
 681} 
 682
 683/// <summary>   
 684/// Reply to email   
 685/// </summary>   
 686public string ReplyToEmail   
 687{   
 688get   
 689{   
 690return _replyToEmail;   
 691}   
 692} 
 693
 694/// <summary>   
 695/// whether has attachment   
 696/// </summary>   
 697public bool HasAttachment   
 698{   
 699get   
 700{   
 701return _hasAttachment;   
 702}   
 703} 
 704
 705/// <summary>   
 706/// raw message body   
 707/// </summary>   
 708public string RawMessageBody   
 709{   
 710get   
 711{   
 712return _rawMessageBody;   
 713}   
 714} 
 715
 716/// <summary>   
 717/// Message ID   
 718/// </summary>   
 719public string MessageID   
 720{   
 721get   
 722{   
 723return _messageID;   
 724}   
 725} 
 726
 727/// <summary>   
 728/// MIME version   
 729/// </summary>   
 730public string MimeVersion   
 731{   
 732get   
 733{   
 734return _mimeVersion;   
 735}   
 736} 
 737
 738/// <summary>   
 739/// raw header   
 740/// </summary>   
 741public string RawHeader   
 742{   
 743get   
 744{   
 745return _rawHeader;   
 746}   
 747} 
 748
 749/// <summary>   
 750/// raw message   
 751/// </summary>   
 752public string RawMessage   
 753{   
 754get   
 755{   
 756return _rawMessage;   
 757}   
 758} 
 759
 760/// <summary>   
 761/// return path   
 762/// </summary>   
 763public string ReturnPath   
 764{   
 765get   
 766{   
 767return _returnPath;   
 768}   
 769} 
 770
 771/// <summary>   
 772/// subject   
 773/// </summary>   
 774public string Subject   
 775{   
 776get   
 777{   
 778return _subject;   
 779}   
 780} 
 781
 782#endregion 
 783
 784/// <summary>   
 785/// release all objects   
 786/// </summary>   
 787~Message()   
 788{   
 789_attachments.Clear();   
 790_attachments = null;   
 791_keywords.Clear();   
 792_keywords = null;   
 793_messageBody.Clear();   
 794_messageBody = null;   
 795_customHeaders.Clear();   
 796_customHeaders = null;   
 797} 
 798
 799/// <summary>   
 800/// New Message   
 801/// </summary>   
 802/// <param name="blnFinish"/>reference for the finishing state   
 803/// <param name="strBasePath"/>path to extract MS-TNEF attachment files   
 804/// <param name="blnAutoDecodeMSTNEF"/>whether auto decoding MS-TNEF attachments   
 805/// <param name="blnOnlyHeader"/>whether only decode the header without body   
 806/// <param name="strEMLFile"/>file of email content to load from   
 807public Message(ref bool blnFinish, string strBasePath, bool blnAutoDecodeMSTNEF, bool blnOnlyHeader, string strEMLFile)   
 808{   
 809string strMessage = null;   
 810if (Utility.ReadPlainTextFromFile(strEMLFile, ref strMessage))   
 811{   
 812NewMessage(ref blnFinish, strBasePath, blnAutoDecodeMSTNEF, strMessage, blnOnlyHeader);   
 813}   
 814else   
 815blnFinish = true;   
 816} 
 817
 818/// <summary>   
 819/// New Message   
 820/// </summary>   
 821/// <param name="blnFinish"/>reference for the finishing state   
 822/// <param name="strBasePath"/>path to extract MS-TNEF attachment files   
 823/// <param name="blnAutoDecodeMSTNEF"/>whether auto decoding MS-TNEF attachments   
 824/// <param name="strMessage"/>raw message content   
 825/// <param name="blnOnlyHeader"/>whether only decode the header without body   
 826public Message(ref bool blnFinish, string strBasePath, bool blnAutoDecodeMSTNEF, string strMessage, bool blnOnlyHeader)   
 827{   
 828NewMessage(ref blnFinish, strBasePath, blnAutoDecodeMSTNEF, strMessage, blnOnlyHeader);   
 829} 
 830
 831/// <summary>   
 832/// New Message   
 833/// </summary>   
 834/// <param name="blnFinish"/>reference for the finishing state   
 835/// <param name="strMessage"/>raw message content   
 836/// <param name="blnOnlyHeader"/>whether only decode the header without body   
 837public Message(ref bool blnFinish, string strMessage, bool blnOnlyHeader)   
 838{   
 839NewMessage(ref blnFinish, "", false, strMessage, blnOnlyHeader);   
 840} 
 841
 842/// <summary>   
 843/// New Message   
 844/// </summary>   
 845/// <param name="blnFinish"/>reference for the finishing state   
 846/// <param name="strMessage"/>raw message content   
 847public Message(ref bool blnFinish, string strMessage)   
 848{   
 849NewMessage(ref blnFinish, "", false, strMessage, false);   
 850} 
 851
 852/// <summary>   
 853/// get valid attachment   
 854/// </summary>   
 855/// <param name="intAttachmentNumber"/>attachment index in the attachments collection   
 856/// <returns>attachment</returns>   
 857public Attachment GetAttachment(int intAttachmentNumber)   
 858{   
 859if (intAttachmentNumber &lt; 0 || intAttachmentNumber &gt; _attachmentCount || intAttachmentNumber &gt; _attachments.Count)   
 860{   
 861Utility.LogError("GetAttachment():attachment not exist");   
 862throw new ArgumentOutOfRangeException("intAttachmentNumber");   
 863}   
 864return (Attachment) _attachments[intAttachmentNumber];   
 865} 
 866
 867/// <summary>   
 868/// New Message   
 869/// </summary>   
 870/// <param name="blnFinish"/>reference for the finishing state   
 871/// <param name="strBasePath"/>path to extract MS-TNEF attachment files   
 872/// <param name="blnAutoDecodeMSTNEF"/>whether auto decoding MS-TNEF attachments   
 873/// <param name="strMessage"/>raw message content   
 874/// <param name="blnOnlyHeader"/>whether only decode the header without body   
 875/// <returns>construction result whether successfully new a message</returns>   
 876private bool NewMessage(ref bool blnFinish, string strBasePath, bool blnAutoDecodeMSTNEF, string strMessage, bool blnOnlyHeader)   
 877{   
 878StringReader srdReader = new StringReader(strMessage);   
 879StringBuilder sbdBuilder = new StringBuilder();   
 880_basePath = strBasePath;   
 881_autoDecodeMSTNEF = blnAutoDecodeMSTNEF; 
 882
 883_rawMessage = strMessage; 
 884
 885string strLine = srdReader.ReadLine();   
 886while (Utility.IsNotNullTextEx(strLine))   
 887{   
 888sbdBuilder.Append(strLine + "\r\n");   
 889ParseHeader(sbdBuilder, srdReader, ref strLine);   
 890if (Utility.IsOrNullTextEx(strLine))   
 891break;   
 892else   
 893strLine = srdReader.ReadLine();   
 894} 
 895
 896_rawHeader = sbdBuilder.ToString(); 
 897
 898SetAttachmentBoundry2(_rawHeader); 
 899
 900if (_contentLength == 0)   
 901_contentLength = strMessage.Length; //_rawMessageBody.Length; 
 902
 903if (blnOnlyHeader == false)   
 904{   
 905_rawMessageBody = srdReader.ReadToEnd().Trim(); 
 906
 907//the auto reply mail by outlook uses ms-tnef format   
 908if ((_hasAttachment == true &amp;&amp; _attachmentboundry != null) || MIMETypes.IsMSTNEF(_contentType))   
 909{   
 910set_attachments(); 
 911
 912if (this.Attachments.Count &gt; 0)   
 913{   
 914Attachment at = this.GetAttachment(0);   
 915if (at != null &amp;&amp; at.NotAttachment)   
 916this.GetMessageBody(at.DecodeAsText());   
 917else   
 918{   
 919}   
 920//in case body parts as text[0] html[1]   
 921if (this.Attachments.Count &gt; 1 &amp;&amp; !this.IsReport())   
 922{   
 923at = this.GetAttachment(1);   
 924if (at != null &amp;&amp; at.NotAttachment)   
 925this.GetMessageBody(at.DecodeAsText());   
 926else   
 927{   
 928}   
 929}   
 930}   
 931else   
 932{   
 933}   
 934}   
 935else   
 936{   
 937GetMessageBody(_rawMessageBody);   
 938}   
 939} 
 940
 941blnFinish = true;   
 942return true;   
 943} 
 944
 945/// <summary>   
 946/// parse message body   
 947/// </summary>   
 948/// <param name="strBuffer"/>raw message body   
 949/// <returns>message body</returns>   
 950public string GetTextBody(string strBuffer)   
 951{   
 952if (strBuffer.EndsWith("\r\n."))   
 953return strBuffer.Substring(0, strBuffer.Length - "\r\n.".Length);   
 954else   
 955return strBuffer;   
 956} 
 957
 958/// <summary>   
 959/// parse message body   
 960/// </summary>   
 961/// <param name="strBuffer"/>raw message body   
 962public void GetMessageBody(string strBuffer)   
 963{   
 964int end, begin;   
 965string body;   
 966string encoding = ""; 
 967
 968begin = end = 0;   
 969_messageBody.Clear(); 
 970
 971try   
 972{   
 973if (Utility.IsOrNullTextEx(strBuffer))   
 974return;   
 975else if (Utility.IsOrNullTextEx(_contentType) &amp;&amp; _contentTransferEncoding == null)   
 976{   
 977_messageBody.Add(GetTextBody(strBuffer));   
 978}   
 979else if (_contentType != null &amp;&amp; _contentType.IndexOf("digest") &gt;= 0)   
 980{   
 981// this is a digest method   
 982//ParseDigestMessage(strBuffer);   
 983_messageBody.Add(GetTextBody(strBuffer));   
 984}   
 985else if (_attachmentboundry2 == null)   
 986{   
 987body = GetTextBody(strBuffer); 
 988
 989if (Utility.IsQuotedPrintable(_contentTransferEncoding))   
 990{   
 991body = DecodeQP.ConvertHexContent(body);   
 992}   
 993else if (Utility.IsBase64(_contentTransferEncoding))   
 994{   
 995body = Utility.deCodeB64s(Utility.RemoveNonB64(body));   
 996}   
 997else if (Utility.IsNotNullText(_contentCharset))   
 998{   
 999body = Encoding.GetEncoding(_contentCharset).GetString(Encoding.Default.GetBytes(body));   
1000}   
1001_messageBody.Add(Utility.RemoveNonB64(body));   
1002}   
1003else   
1004{   
1005begin = 0; 
1006
1007while (begin != -1)   
1008{   
1009// find "\r\n\r\n" denoting end of header   
1010begin = strBuffer.IndexOf("--" + _attachmentboundry2, begin);   
1011if (begin != -1)   
1012{   
1013encoding = MIMETypes.GetContentTransferEncoding(strBuffer, begin); 
1014
1015begin = strBuffer.IndexOf("\r\n\r\n", begin + 1); //strBuffer.LastIndexOfAny(ALPHABET.ToCharArray()); 
1016
1017// find end of text   
1018end = strBuffer.IndexOf("--" + _attachmentboundry2, begin + 1); 
1019
1020if (begin != -1)   
1021{   
1022if (end != -1)   
1023{   
1024begin += 4;   
1025if (begin &gt;= end)   
1026continue;   
1027else if (this._contentEncoding != null &amp;&amp; this._contentEncoding.IndexOf("8bit") != -1)   
1028body = Utility.Change(strBuffer.Substring(begin, end - begin - 2), _contentCharset);   
1029else   
1030body = strBuffer.Substring(begin, end - begin - 2);   
1031}   
1032else   
1033{   
1034body = strBuffer.Substring(begin);   
1035} 
1036
1037if (Utility.IsQuotedPrintable(encoding))   
1038{   
1039string ret = body;   
1040ret = DecodeQP.ConvertHexContent(ret);   
1041_messageBody.Add(ret);   
1042}   
1043else if (Utility.IsBase64(encoding))   
1044{   
1045string ret = Utility.RemoveNonB64(body);   
1046ret = Utility.deCodeB64s(ret);   
1047if (ret != "\0")   
1048_messageBody.Add(ret);   
1049else   
1050_messageBody.Add(body);   
1051}   
1052else   
1053_messageBody.Add(body); 
1054
1055if (end == -1) break;   
1056}   
1057else   
1058{   
1059break;   
1060}   
1061}   
1062else   
1063{   
1064if (_messageBody.Count == 0)   
1065{   
1066_messageBody.Add(strBuffer);   
1067}   
1068break;   
1069}   
1070}   
1071}   
1072}   
1073catch (Exception e)   
1074{   
1075Utility.LogError("GetMessageBody():" + e.Message);   
1076_messageBody.Add(Utility.deCodeB64s(strBuffer));   
1077} 
1078
1079if (_messageBody.Count &gt; 1)   
1080_html = true;   
1081} 
1082
1083/// <summary>   
1084/// verify if the message is a report   
1085/// </summary>   
1086/// <returns>if it is a report message, return true, else, false</returns>   
1087public bool IsReport()   
1088{   
1089if (Utility.IsNotNullText(_contentType))   
1090return (_contentType.ToLower().IndexOf("report".ToLower()) != -1);   
1091else   
1092return false;   
1093} 
1094
1095/// <summary>   
1096/// verify if the attachment is MIME Email file   
1097/// </summary>   
1098/// <param name="attItem"/>attachment   
1099/// <returns>if MIME Email file, return true, else, false</returns>   
1100public bool IsMIMEMailFile(Attachment attItem)   
1101{   
1102try   
1103{   
1104return (attItem.ContentFileName.ToLower().EndsWith(".eml".ToLower()) || attItem.ContentType.ToLower() == "message/rfc822".ToLower());   
1105}   
1106catch (Exception e)   
1107{   
1108Utility.LogError("IsMIMEMailFile():" + e.Message);   
1109return false;   
1110}   
1111} 
1112
1113/// <summary>   
1114/// translate pictures url within the body   
1115/// </summary>   
1116/// <param name="strBody"/>message body   
1117/// <param name="hsbFiles"/>pictures collection   
1118/// <returns>translated message body</returns>   
1119public string TranslateHTMLPictureFiles(string strBody, Hashtable hsbFiles)   
1120{   
1121try   
1122{   
1123for (int i = 0; i &lt; this.AttachmentCount; i++)   
1124{   
1125Attachment att = this.GetAttachment(i);   
1126if (Utility.IsPictureFile(att.ContentFileName) == true)   
1127{   
1128if (Utility.IsNotNullText(att.ContentID))   
1129//support for embedded pictures   
1130strBody = strBody.Replace("cid:" + att.ContentID, hsbFiles[att.ContentFileName].ToString()); 
1131
1132strBody = strBody.Replace(att.ContentFileName, hsbFiles[att.ContentFileName].ToString());   
1133}   
1134}   
1135}   
1136catch (Exception e)   
1137{   
1138Utility.LogError("TranslateHTMLPictureFiles():" + e.Message);   
1139}   
1140return strBody;   
1141} 
1142
1143/// <summary>   
1144&amp;nb</summary></bug>
Published At
Categories with Web编程
Tagged with
comments powered by Disqus