/// <summary> /// Constructor. /// </summary> /// <param name="stream"></param> public MimeMessage(Stream stream) { MimeParser mp = new MimeParser(stream); Parse(ref mp, null); CreateDefaultHeaders(); mp = null; }
/// <summary> /// Constructor /// </summary> /// <param name="mp">MimeParser</param> /// <param name="parentMultipartBody">Multipart Body of parent messages</param> protected MimeMessage(ref MimeParser mp, MimeMultipartBody parentMultipartBody) { if (parentMultipartBody != null) { parentMultipartBody.Add(this); } Parse(ref mp, parentMultipartBody); }
private void Parse(ref MimeParser mp, MimeMultipartBody parentMultipartBody) { try { string sLine = ""; byte [] buffer = null; bool isEOC = false; bool readBinaryBody = false; while(sLine != null) { //Check if the Binary encoding header is found if (_headers["content-transfer-encoding"] != null && MimeBodyPart.GetMimeEncoding(_headers["content-transfer-encoding"].Value) == MimeBodyPart.MimeEncoding.Binary && buffer == null) { readBinaryBody = true; } MimeParser.ChunkType chunkType = mp.ReadNextChunk(ref sLine, ref isEOC, ref readBinaryBody, ref buffer); switch(chunkType) { case MimeParser.ChunkType.VersionHeader: case MimeParser.ChunkType.Header: MimeHeader mh = new MimeHeader(sLine); InitializeMultipart(ref mp, mh); _headers.Add(mh); break; case MimeParser.ChunkType.Body: CreateBody(sLine, buffer); break; case MimeParser.ChunkType.StartBoundary: if (_body == null) CreateBody("", buffer); MimeMessage firstMessage = new MimeMessage(ref mp, (MimeMultipartBody)_body); break; case MimeParser.ChunkType.Boundary: MimeMessage nextMessage = new MimeMessage(ref mp, parentMultipartBody); return; case MimeParser.ChunkType.EndBoundary: return; case MimeParser.ChunkType.EOF: break; default: break; } } } catch(Exception err) { logger.Error(err); throw; } }
private void InitializeMultipart(ref MimeParser mp, MimeHeader mh) { //Check Content-Type if (mh.Name.ToLower().CompareTo("content-type") == 0 && mh.Value.StartsWith("multipart")) { _isMultiPart = true; mp.IsMultiPart = _isMultiPart; //Check boundary if (mh.Parameters["boundary"] != null) { _boundary = mh.Parameters["boundary"].Value; mp.Boundary = _boundary; } } }
/// <summary> /// Parsing mime from stream /// </summary> /// <param name="mp"></param> /// <param name="isChildMime"></param> private void Parse(ref MimeParser mp, bool isChildMime) { try { string sLine = ""; byte [] buffer = null; bool isEOC = false; bool readBinaryBody = false; //Read line by line //if line is null, end of file is detected. while(sLine != null) { if (isChildMime && _headers["content-type"] != null && _headers["content-type"].Value != "multipart/related") { readBinaryBody = true; } //Read next chunk //Usually the next line except for reading binary body. //Reading binary body will read until the boundary is found MimeParser.ChunkType chunkType = mp.ReadNextChunk(ref sLine, ref isEOC, ref readBinaryBody, ref buffer); //perform task based on the chunk type switch (chunkType) { case MimeParser.ChunkType.VersionHeader: case MimeParser.ChunkType.Header: MimeHeader mh = new MimeHeader(sLine); InitializeMultipart(ref mp, mh); _headers.Add(mh); break; case MimeParser.ChunkType.Body: CreateBody(sLine, buffer); //Check if the next line is the boundary of this child mime if (isChildMime && !_isMultiPart) return; break; case MimeParser.ChunkType.StartBoundary: case MimeParser.ChunkType.Boundary: Mime childMessage = new Mime(ref mp, true); _mimes.Add(childMessage); break; case MimeParser.ChunkType.EndBoundary: return; case MimeParser.ChunkType.EOF: break; default: break; } } } catch(Exception err) { logger.Error(err); throw; } }
/// <summary> /// Internal use to construct a child mime from mime parser /// </summary> /// <param name="mp"></param> /// <param name="isChildMime"></param> private Mime(ref MimeParser mp, bool isChildMime) { Parse(ref mp, isChildMime); //set filename if (_headers.Contains("Content-Disposition") && _headers["Content-Disposition"].Parameters.Contains("filename") && _fileName == null) { FileInfo fi = new FileInfo(_headers["Content-Disposition"].Parameters["filename"].Value); _fileName = fi.Name; } }
/// <summary> /// Internal use to construct mime from mime parser /// </summary> /// <param name="mp">MimeParser</param> private Mime(MimeParser mp) : this(ref mp, false) { CreateDefaultHeaders(); mp = null; }
public void ParseNestedMultiPartMime() { var stream = TestDataHelper.Instance.GetTestStream("mimeNestedMultipart.txt"); MimeParser mp = new MimeParser(stream); //Assuming Boundary is given. mp.IsMultiPart = true; mp.Boundary = "----_OAI_NextPart_2563710857820783"; string sLine = ""; bool isEOC = false; bool isEndOfChunk = true; int chunkCount = 0; while(sLine != null) { if (chunkCount == 5 && isEndOfChunk) { mp.Boundary = "----_OAI_NextPart_2563710857820783_FirstMessage"; } else if (chunkCount == 18 && isEndOfChunk) { mp.Boundary = "----_OAI_NextPart_2563710857820783_SecondMessage"; } MimeParser.ChunkType chunkType = mp.ReadNextChunk(ref sLine, ref isEOC); if (sLine != null) { if (isEndOfChunk) { chunkCount++; // System.Diagnostics.Trace.WriteLine("Chunk no:" + chunkCount.ToString() + ". Chunk type is " + chunkType.ToString() + ". The chunk string is"); } // System.Diagnostics.Trace.WriteLine(sLine); } isEndOfChunk = isEOC; } AssertionHelper.IsTrue("There are 30 chunks",chunkCount == 30); }