/// <summary> /// Decodes the attachment data from a mime encoded type. /// </summary> /// <param name="writeAttachmentToFile">Write the attachment indicator.</param> private void DecodeData(bool writeAttachmentToFile) { // If the data is an attachemnt. if (_contentDisposition != null) { // If the attachment is encoded as BASE-64 // then decode the data from base 64. if ((_contentDisposition.Equals("attachment;")) && (_contentTransferEncoding.ToUpper().Equals("BASE64"))) { // Convert the attachment data to a byte array // from the base 64 encoding. Assign the decoded // data to the byte array of the raw file. _binaryData = Convert.FromBase64String(_data.Replace("\n", "")); _file = _binaryData; _decoded = true; // If write the attachment set then // directly write the attachment // to the specified file. if (writeAttachmentToFile) { EmailMessageParse.WriteAttachment(_binaryData, _connection.AttachmentDirectory, _filename); } } // If the attachment is encoded as QUOTED-PRINTABLE // then decode the data from quoted printable. else if ((_contentDisposition.Equals("attachment;")) && (_contentTransferEncoding.ToUpper().Equals("QUOTED-PRINTABLE"))) { // Convert the attachment data to a byte array // from the quoted printable encoding. Assign the decoded // data to the byte array of the raw file. string output = EmailMessageParse.FromQuotedPrintable(_data); _file = Encoding.ASCII.GetBytes(output); _decoded = true; // If write the attachment set then // directly write the attachment // to the specified file. if (writeAttachmentToFile) { EmailMessageParse.WriteQuotedPrintable(output, _connection.AttachmentDirectory, _filename); } } // If the attachment has been encoded with // some other transfer encoding then assign // the raw encoded data. else if (_contentDisposition.Equals("attachment;")) { _file = Encoding.ASCII.GetBytes(_data); _decoded = false; } } }
/// <summary> /// Write the attachment to the file path. /// </summary> /// <param name="directoryPath">The directory path to write the file.</param> /// <param name="fileName">The name of the file to write.</param> /// <returns>True if the attachment was written else false.</returns> public bool WriteAttachment(string directoryPath, string fileName) { try { // Write the current attachment // to the specified file. EmailMessageParse.WriteAttachment(_file, directoryPath, fileName); return(true); } catch (Exception ex) { throw new Exception(ex.Message); } }
/// <summary> /// Message body and attachment constructor. /// </summary> /// <param name="lines">The array of lines in the message.</param> /// <param name="startOfBody">The start of the body data.</param> /// <param name="multipartBoundary">The multipary boundary.</param> /// <param name="mainContentType">The main content type.</param> /// <param name="writeAttachmentToFile">Write to file.</param> /// <param name="connection">The connection object.</param> public MessageBody(string[] lines, long startOfBody, string multipartBoundary, string mainContentType, bool writeAttachmentToFile, Pop3ConnectionAdapter connection) { // Get the number of message lines. long stopOfBody = lines.Length; // If the multipart boudary is null then // only a body part exists. if (multipartBoundary == null) { // Create a new string builder. StringBuilder sbText = new StringBuilder(); // For each line in the message // append the body lines. for (long i = startOfBody; i < stopOfBody; i++) { sbText.Append(lines[i].Replace("\n", "").Replace("\r", "")); } // Add a new body to the component // list store. _component.Add(new MessageAttachment(mainContentType, sbText.ToString(), writeAttachmentToFile, connection)); } // Multipart boundary exists then a body and attachment // exists in the message. else { // Get the multipart boundary // string in the message. string boundary = multipartBoundary; // Set as first component or body // of the message to get. bool firstComponent = true; // Loop through whole of email message // get the bodt all attachments. for (long i = startOfBody; i < stopOfBody;) { bool boundaryFound = true; string contentType = null; string name = null; string filename = null; string contentTransferEncoding = null; string contentDescription = null; string contentDisposition = null; string data = null; // If the first component is to be added // this is the body of a multipart message. if (firstComponent) { boundaryFound = false; firstComponent = false; // For all the lines in the message. while (i < stopOfBody) { // Get the current line in the message. string line = lines[i].Replace("\n", "").Replace("\r", ""); // If the end of the body boundary // has been found then exit the loop // all body data has been found. if (EmailMessageParse.GetContentMappingHeaderType(line, boundary) == Nequeo.Net.Mail.MesssageContentMappingType.MultipartBoundaryFound) { boundaryFound = true; ++i; break; } else { ++i; } } } // Check to see whether multipart boundary // was not found. This will indicate that // the message data is corrupt. if (!boundaryFound) { throw new Exception("Missing multipart boundary: " + boundary); } // Initalise the end of header indicator. bool endOfHeader = false; // Read all header information. // For all other lines in the // messsage. while ((i < stopOfBody)) { // Get the current line in the message. string line = lines[i].Replace("\n", "").Replace("\r", ""); // Get the current content mapping type. Nequeo.Net.Mail.MesssageContentMappingType lineType = EmailMessageParse.GetContentMappingHeaderType(line, boundary); // Get the mapping type. switch (lineType) { case Nequeo.Net.Mail.MesssageContentMappingType.ContentType: // Mapping type is content type header. // Get the content type data. contentType = EmailMessageParse.ContentType(line); break; case Nequeo.Net.Mail.MesssageContentMappingType.ContentTransferEncoding: // Mapping type is content transfer encoding header. // Get the content transfer encoding data. contentTransferEncoding = EmailMessageParse.ContentTransferEncoding(line); break; case Nequeo.Net.Mail.MesssageContentMappingType.ContentDisposition: // Mapping type is content disposition header. // Get the content disposition data. contentDisposition = EmailMessageParse.ContentDisposition(line); break; case Nequeo.Net.Mail.MesssageContentMappingType.ContentDescription: // Mapping type is content description header. // Get the content description data. contentDescription = EmailMessageParse.ContentDescription(line); break; case Nequeo.Net.Mail.MesssageContentMappingType.EndOfHeader: // End of header has been found. endOfHeader = true; break; } // Increment to the next line after // find the content mapping type in // the prevoius line. ++i; // If end of header found then search // for the next component starting point // search for the next attachment. break // out of the loop and end the process. if (endOfHeader) { break; } else { // Read all header information. // For all other lines in the // messsage. while (i < stopOfBody) { // If more lines to read for this line. if (line.Substring(line.Length - 1, 1).Equals(";")) { // Get the current line in the message. string nextLine = lines[i].Replace("\r", "").Replace("\n", ""); // Get the current attachment header type. // interate through each attachment data. switch (EmailMessageParse.GetAttachmenHeaderType(nextLine)) { case Nequeo.Net.Mail.MesssageAttachmentType.Name: // Attachment name header type. // Get the attachment name in the message. name = EmailMessageParse.Name(nextLine); break; case Nequeo.Net.Mail.MesssageAttachmentType.Filename: // Attachment file nale header type. // Get the attachment file name in the message. filename = EmailMessageParse.Filename(nextLine); break; case Nequeo.Net.Mail.MesssageAttachmentType.EndOfHeader: // End of header has been found. endOfHeader = true; break; } // If the end of the attachment // data has not been found if (!endOfHeader) { // Assign the current line to // the next line line = nextLine; ++i; } else { // End the loop. break; } } else { // End the loop. break; } } } } // Boundary found to false. boundaryFound = false; // Create a new string builder. StringBuilder sbText = new StringBuilder(); // Initailise the emial composed indicator. bool emailComposed = false; // For each remaining line in // the message store the body // and the attachment. while (i < stopOfBody) { // Get the current line in the message. string line = lines[i].Replace("\n", ""); // If the end of the body boundary // has been found then exit the loop // all component data has been found. if (EmailMessageParse.GetContentMappingHeaderType(line, boundary) == Nequeo.Net.Mail.MesssageContentMappingType.MultipartBoundaryFound) { boundaryFound = true; ++i; break; } // If the component is done then // the email is composed, this // component has been completed // composed. else if (EmailMessageParse.GetContentMappingHeaderType(line, boundary) == Nequeo.Net.Mail.MesssageContentMappingType.ComponentDone) { emailComposed = true; break; } // Add the current line of component // data to the string builder. // Move to the next line in the message. sbText.Append(lines[i]); ++i; } // If data has been built // then this is the component data // that is body or attachment data. if (sbText.Length > 0) { data = sbText.ToString(); } // Add a new message body or attachment to the // component list store. _component.Add(new MessageAttachment(contentType, name, filename, contentTransferEncoding, contentDescription, contentDisposition, data, writeAttachmentToFile, connection)); // If all multiparts have been // composed then exit break // out of the loop. if (emailComposed) { break; } } } }
/// <summary> /// Parse each header type for each line in the email message. /// </summary> /// <param name="lines">The array of lines in the email message.</param> /// <returns>The start of the message body.</returns> private long ParseHeader(string[] lines) { // Get the total number of lines // and set the body start count to // zero. int numberOfLines = lines.Length; long bodyStart = 0; // For each line in the email message // parse all headers required. for (int i = 0; i < numberOfLines; i++) { // Get the current email line. string currentLine = lines[i].Replace("\n", ""); // Get the current line header type. Nequeo.Net.Mail.MesssageHeaderType lineType = GetHeaderType(currentLine); // Get each haeder type. switch (lineType) { case Nequeo.Net.Mail.MesssageHeaderType.From: // From email message. _from = EmailMessageParse.From(currentLine); break; case Nequeo.Net.Mail.MesssageHeaderType.Subject: // Subject of the message. _subject = EmailMessageParse.Subject(currentLine); break; case Nequeo.Net.Mail.MesssageHeaderType.To: // To email message. _to = EmailMessageParse.To(currentLine); break; case Nequeo.Net.Mail.MesssageHeaderType.ReplyTo: // Reply to email message. _replyTo = EmailMessageParse.ReplyTo(currentLine); break; case Nequeo.Net.Mail.MesssageHeaderType.Date: // Date received message. _date = EmailMessageParse.Date(currentLine); break; case Nequeo.Net.Mail.MesssageHeaderType.Organization: // The orginization that sent the message. _organization = EmailMessageParse.Organization(currentLine); break; case Nequeo.Net.Mail.MesssageHeaderType.ReturnPath: // The email address return path. _returnPath = EmailMessageParse.ReturnPath(currentLine); break; case Nequeo.Net.Mail.MesssageHeaderType.Received: // The computers that sent and recevied the message. _received += EmailMessageParse.Received(currentLine); break; case Nequeo.Net.Mail.MesssageHeaderType.Cc: // The carbon copy email address. _cc = EmailMessageParse.Cc(currentLine); break; case Nequeo.Net.Mail.MesssageHeaderType.Bcc: // The blind carbon copy email address. _bcc = EmailMessageParse.Bcc(currentLine); break; case Nequeo.Net.Mail.MesssageHeaderType.Priority: // The email message priority. _priority = EmailMessageParse.Priority(currentLine); break; case Nequeo.Net.Mail.MesssageHeaderType.Importance: // The importance of the message. _importance = EmailMessageParse.Importance(currentLine); break; case Nequeo.Net.Mail.MesssageHeaderType.ContentType: // The content type of the message // that has been specified (text, html etc..). _contentType = EmailMessageParse.ContentType(currentLine); // Is multi part, that is are // attachments included. _isMultipart = EmailMessageParse.IsMultipart(_contentType); // If multipart. if (_isMultipart) { // Boundary has been found // for the attachments. if (_contentType.Substring(_contentType.Length - 1, 1).Equals(";")) { // Increament the line index by one // move to the next line. ++i; // Get the boundary data from the message. _multipartBoundary = EmailMessageParse.MultipartBoundary(lines[i].Replace("\n", "")); } else { // Boundary definition is on same // line as Content-Type. _multipartBoundary = EmailMessageParse.MultipartBoundary(_contentType); } } break; case Nequeo.Net.Mail.MesssageHeaderType.EndOfHeader: // The end of all message headers has been // found so the next data is the body of the // message increment the body start index. bodyStart = i + 1; break; } // If the body index is greater than // zero then end of headers has been // for and the body of the message // has started, break out of the loop. if (bodyStart > 0) { break; } } // Return the start of the body. return(bodyStart); }