/// <summary> /// Default Constructor /// </summary> public IMAPMessage() { _to = new List <IMAPMailAddress>(); _from = new List <IMAPMailAddress>(); _cc = new List <IMAPMailAddress>(); _bcc = new List <IMAPMailAddress>(); _textData = new IMAPMessageContent(); _htmlData = new IMAPMessageContent(); _bodyParts = new List <IMAPMessageContent>(); _received = String.Empty; _attachments = new List <IMAPFileAttachment>(); _embedded = new List <IMAPFileAttachment>(); _headerLoaded = false; _contentLoaded = false; _flags = new IMAPMessageFlags(); _properties = this.GetType().GetProperties(); }
/// <summary> /// Downloads the entire body of the message from the server. includes content and attachments. /// Structure is then parsed and the various data items are seperated and stored in the message object. /// </summary> /// <param name="msg"></param> public void ProcessBodyContent(IMAPMessage msg) { string cmd = "UID FETCH {0} BODY[]\r\n"; ArrayList result = new ArrayList(); Log(LogTypeEnum.INFO, String.Format("Downloading body of message {0} in folder {1}", msg.Uid, msg.Folder.FolderName)); // pausing the logger because otherwise we would be logging all of the binary data for attachments which slows // down the processing quite noticably. Can be unpaused for debugging purposes, but make sure to re-pause it. _logger.Paused = true; SendAndReceive(String.Format(cmd, msg.Uid), ref result); _logger.Paused = false; Log(LogTypeEnum.INFO, "Download complete"); bool withinSection = false; string boundary = ""; List<string> boundaryList = new List<string>(); boundaryList.Add(""); // first we need to extract the boundary string from the header // we use a collection because there might be other boundary demarcators in the content of the message and we // need to capture all of them if (msg.ContentType != null) { if (msg.ContentType.ToLower().Contains("boundary")) { boundaryList.Clear(); boundary = "--"; string t = msg.ContentType; int idx = t.ToLower().IndexOf("boundary"); int idx2 = t.IndexOf("=", idx); boundary += t.Substring(idx2 + 1).Replace("\"","").TrimStart(); int idx3 = boundary.IndexOf(";"); if (idx3 > -1) boundary = boundary.Substring(0, idx3); boundaryList.Add(boundary); if (boundary.Length > 10) boundary = boundary.Substring(0, 10); } } bool plainText = false; for (int i = 0; i < result.Count; i++) { string line = result[i].ToString(); //if (line.ToLower().Contains("content-type")) //{ // if (!line.ToLower().Contains("multipart")) // plainText = true; //} if (String.IsNullOrEmpty(msg.ContentType)) plainText = true; else if (msg.ContentType.ToLower().Contains("multipart")) plainText = false; else plainText = true; if (line.Contains("OK Success") || line.Contains("OK FETCH completed")) break; if (!ListContainsString(boundaryList, line) && !withinSection) continue; if (ListContainsString(boundaryList, line) && BoundaryAllDashes(boundaryList.ToArray()) ? true : !line.EndsWith("--")) withinSection = true; if (withinSection) { IMAPMessageContent content = new IMAPMessageContent(); // first we process the section header data, stopping when we hit an empty line if (!plainText) { while (!line.Equals(String.Empty)) { line = result[++i].ToString(); if (line.ToLower().Contains("boundary")) { string newBoundary = "--"; string t = line; int idx = t.ToLower().IndexOf("boundary"); int idx2 = t.IndexOf("=", idx); newBoundary += t.Substring(idx2 + 1).Replace("\"", ""); boundaryList.Add(newBoundary); } string[] headerField = GetNameValue(line); if (headerField.Length == 2) { PropertyInfo[] props = content.GetType().GetProperties(); foreach (PropertyInfo pinfo in props) { if (pinfo.Name.ToLower().Equals(headerField[0].ToLower())) { pinfo.SetValue(content, headerField[1].Trim(), null); break; } } } if (i + 2 < result.Count - 1) { if (result[i + 1].ToString().Equals("") && result[i + 2].ToString().Equals("")) break; } else { break; } } } else { content.ContentType = msg.ContentType; } bool isGarbageSection = content.ContentType != null ? content.ContentType.ToLower().Contains("multipart") : false; StringBuilder contentString = new StringBuilder(); bool hardEndOfMsg = false; // now we are in the section body. continue until we hit the next section while (true) { if (i + 1 > result.Count - 1) { hardEndOfMsg = true; break; } line = result[++i].ToString(); if (boundary.Equals("")) { if (line.StartsWith(")") || line.StartsWith(String.Format(" UID {0})",msg.Uid))) { // lets make sure this is the last ')' in the message, just to be safe int endOfMessage = 0; for (int k = result.Count - 1; k > 0; k--) { if (result[k].ToString().StartsWith(")") || result[k].ToString().StartsWith(String.Format(" UID {0})", msg.Uid))) { endOfMessage = k; break; } } if (i == endOfMessage) break; } } else if (ListContainsString(boundaryList, line)) { i--; break; } contentString.AppendLine(line); } if (!isGarbageSection && !hardEndOfMsg) { if (content.ContentTransferEncoding != null ? content.ContentTransferEncoding.ToLower().Equals("base64"): false) { content.BinaryData = Convert.FromBase64String(contentString.ToString()); if (content.ContentType.Contains("text/plain;") && content.ContentDisposition != "attachment;") { content.TextData = System.Text.Encoding.UTF8.GetString(content.BinaryData); } } else { content.TextData = contentString.ToString(); } msg._bodyParts.Add(content); Log(LogTypeEnum.INFO, String.Format("Added content section of type {0}", content.ContentType)); } withinSection = false; } } if (msg._bodyParts.Count == 0) { Log(LogTypeEnum.ERROR, "No body parts added for this message"); } else { foreach (IMAPMessageContent content in msg._bodyParts) { if (String.IsNullOrEmpty(content.ContentType)) Log(LogTypeEnum.ERROR, "No content type found for this part"); } } }
/// <summary> /// Default Constructor /// </summary> public IMAPMessage() { _to = new List<IMAPMailAddress>(); _from = new List<IMAPMailAddress>(); _cc = new List<IMAPMailAddress>(); _bcc = new List<IMAPMailAddress>(); _textData = new IMAPMessageContent(); _htmlData = new IMAPMessageContent(); _bodyParts = new List<IMAPMessageContent>(); _received = String.Empty; _attachments = new List<IMAPFileAttachment>(); _embedded = new List<IMAPFileAttachment>(); _headerLoaded = false; _contentLoaded = false; _flags = new IMAPMessageFlags(); _properties = this.GetType().GetProperties(); }