private void ParseMessage( anmar.SharpMimeTools.SharpMimeMessage part, anmar.SharpMimeTools.MimeTopLevelMediaType types, bool html, SharpDecodeOptions options, System.String preferredtextsubtype, System.String path ) { if ( (types&part.Header.TopLevelMediaType)!=part.Header.TopLevelMediaType ) { #if LOG if ( log.IsDebugEnabled ) log.Debug (System.String.Concat("Mime-Type [", part.Header.TopLevelMediaType, "] is not an accepted Mime-Type. Skiping part.")); #endif return; } switch ( part.Header.TopLevelMediaType ) { case anmar.SharpMimeTools.MimeTopLevelMediaType.multipart: case anmar.SharpMimeTools.MimeTopLevelMediaType.message: // TODO: allow other subtypes of "message" // Only message/rfc822 allowed, other subtypes ignored if ( part.Header.TopLevelMediaType.Equals(anmar.SharpMimeTools.MimeTopLevelMediaType.message) && !part.Header.SubType.Equals("rfc822") ) break; if ( part.Header.SubType.Equals ("alternative") ) { if ( part.PartsCount>0 ) { anmar.SharpMimeTools.SharpMimeMessage altenative = null; // Get the first mime part of the alternatives that has a accepted Mime-Type for ( int i=part.PartsCount; i>0; i-- ) { anmar.SharpMimeTools.SharpMimeMessage item = part.GetPart(i-1); if ( (types&part.Header.TopLevelMediaType)!=part.Header.TopLevelMediaType || ( !html && item.Header.TopLevelMediaType.Equals(anmar.SharpMimeTools.MimeTopLevelMediaType.text) && item.Header.SubType.Equals("html") ) ) { #if LOG if ( log.IsDebugEnabled ) log.Debug (System.String.Concat("Mime-Type [", item.Header.TopLevelMediaType, "/", item.Header.SubType, "] is not an accepted Mime-Type. Skiping alternative part.")); #endif continue; } // First allowed one. if ( altenative==null ) { altenative=item; // We don't have to select body part based on subtype if not asked for, or not a text one // or it's already the preferred one if ( preferredtextsubtype==null || item.Header.TopLevelMediaType!=anmar.SharpMimeTools.MimeTopLevelMediaType.text || (preferredtextsubtype!=null && item.Header.SubType==preferredtextsubtype) ) { break; } // This one is preferred over the last part } else if ( preferredtextsubtype!=null && item.Header.TopLevelMediaType==anmar.SharpMimeTools.MimeTopLevelMediaType.text && item.Header.SubType==preferredtextsubtype ) { altenative=item; break; } } if ( altenative!=null ) { // If message body as html is allowed and part has a Content-ID field // add an anchor to mark this body part if ( html && part.Header.Contains("Content-ID") && (options&anmar.SharpMimeTools.SharpDecodeOptions.NamedAnchors)==anmar.SharpMimeTools.SharpDecodeOptions.NamedAnchors ) { // There is a previous text body, so enclose it in <pre> if ( !this._body_html && this._body.Length>0 ) { this._body = System.String.Concat ("<pre>", System.Web.HttpUtility.HtmlEncode(this._body), "</pre>"); this._body_html = true; } // Add the anchor this._body = System.String.Concat (this._body, "<a name=\"", anmar.SharpMimeTools.SharpMimeTools.Rfc2392Url(this.MessageID), "_", anmar.SharpMimeTools.SharpMimeTools.Rfc2392Url(part.Header.ContentID), "\"></a>"); } this.ParseMessage(altenative, types, html, options, preferredtextsubtype, path); } } // TODO: Take into account each subtype of "multipart" } else if ( part.PartsCount>0 ) { foreach ( anmar.SharpMimeTools.SharpMimeMessage item in part ) { this.ParseMessage(item, types, html, options, preferredtextsubtype, path); } } break; case anmar.SharpMimeTools.MimeTopLevelMediaType.text: if ( ( part.Disposition==null || !part.Disposition.Equals("attachment") ) && ( part.Header.SubType.Equals("plain") || part.Header.SubType.Equals("html") ) ) { bool body_was_html = this._body_html; // HTML content not allowed if ( part.Header.SubType.Equals("html") ) { if ( !html ) break; else this._body_html=true; } if ( html && part.Header.Contains("Content-ID") && (options&anmar.SharpMimeTools.SharpDecodeOptions.NamedAnchors)==anmar.SharpMimeTools.SharpDecodeOptions.NamedAnchors ) { this._body_html = true; } if ( this._body_html && !body_was_html && this._body.Length>0 ) { this._body = System.String.Concat ("<pre>", System.Web.HttpUtility.HtmlEncode(this._body), "</pre>"); } // If message body is html and this part has a Content-ID field // add an anchor to mark this body part if ( this._body_html && part.Header.Contains("Content-ID") && (options&anmar.SharpMimeTools.SharpDecodeOptions.NamedAnchors)==anmar.SharpMimeTools.SharpDecodeOptions.NamedAnchors ) { this._body = System.String.Concat (this._body, "<a name=\"", anmar.SharpMimeTools.SharpMimeTools.Rfc2392Url(this.MessageID), "_", anmar.SharpMimeTools.SharpMimeTools.Rfc2392Url(part.Header.ContentID), "\"></a>"); } if ( this._body_html && part.Header.SubType.Equals("plain") ) { this._body = System.String.Concat (this._body, "<pre>", System.Web.HttpUtility.HtmlEncode(part.BodyDecoded), "</pre>"); } else this._body = System.String.Concat (this._body, part.BodyDecoded); } else { if ( (types&anmar.SharpMimeTools.MimeTopLevelMediaType.application)!=anmar.SharpMimeTools.MimeTopLevelMediaType.application ) { #if LOG if ( log.IsDebugEnabled ) log.Debug (System.String.Concat("Mime-Type [", anmar.SharpMimeTools.MimeTopLevelMediaType.application, "] is not an accepted Mime-Type. Skiping part.")); #endif return; } goto case anmar.SharpMimeTools.MimeTopLevelMediaType.application; } break; case anmar.SharpMimeTools.MimeTopLevelMediaType.application: case anmar.SharpMimeTools.MimeTopLevelMediaType.audio: case anmar.SharpMimeTools.MimeTopLevelMediaType.image: case anmar.SharpMimeTools.MimeTopLevelMediaType.video: // Attachments not allowed. if ( (options&anmar.SharpMimeTools.SharpDecodeOptions.AllowAttachments)!=anmar.SharpMimeTools.SharpDecodeOptions.AllowAttachments ) break; anmar.SharpMimeTools.SharpAttachment attachment = null; // Save to a file if ( path!=null ) { System.IO.FileInfo file = part.DumpBody(path, true); if ( file!=null ) { attachment = new anmar.SharpMimeTools.SharpAttachment(file); attachment.Name = file.Name; attachment.Size = file.Length; } // Save to a stream } else { System.IO.MemoryStream stream = new System.IO.MemoryStream(); if ( part.DumpBody(stream) ) { attachment = new anmar.SharpMimeTools.SharpAttachment(stream); if ( part.Name!=null ) attachment.Name = part.Name; else attachment.Name = System.String.Concat("generated_", part.GetHashCode(), ".", part.Header.SubType); attachment.Size = stream.Length; } stream = null; } if ( attachment!=null && part.Header.SubType=="ms-tnef" && (options&anmar.SharpMimeTools.SharpDecodeOptions.DecodeTnef)==anmar.SharpMimeTools.SharpDecodeOptions.DecodeTnef ) { // Try getting attachments form a tnef stream #if LOG if ( log.IsDebugEnabled ) { log.Debug(System.String.Concat("Decoding ms-tnef stream.")); } #endif System.IO.Stream stream = attachment.Stream; if ( stream!=null && stream.CanSeek ) stream.Seek(0, System.IO.SeekOrigin.Begin); anmar.SharpMimeTools.SharpTnefMessage tnef = new anmar.SharpMimeTools.SharpTnefMessage(stream); if ( tnef.Parse(path) ) { if ( tnef.Attachments!=null ) { this._attachments.AddRange(tnef.Attachments); } attachment.Close(); // Delete the raw tnef file if ( attachment.SavedFile!=null ) { if ( stream!=null && stream.CanRead ) stream.Close(); attachment.SavedFile.Delete(); } attachment = null; tnef.Close(); #if LOG if ( log.IsDebugEnabled ) { log.Debug(System.String.Concat("ms-tnef stream decoded successfully. Found [", ((tnef.Attachments!=null)?tnef.Attachments.Count:0),"] attachments.")); } #endif } else { // The read-only stream is no longer needed and locks the file if ( attachment.SavedFile!=null && stream!=null && stream.CanRead ) stream.Close(); } stream = null; tnef = null; } if ( attachment!=null ) { if ( part.Disposition!=null && part.Disposition=="inline" ) { attachment.Inline = true; } attachment.MimeTopLevelMediaType = part.Header.TopLevelMediaType; attachment.MimeMediaSubType = part.Header.SubType; // Store attachment's CreationTime if ( part.Header.ContentDispositionParameters.ContainsKey("creation-date") ) attachment.CreationTime = anmar.SharpMimeTools.SharpMimeTools.parseDate ( part.Header.ContentDispositionParameters["creation-date"] ); // Store attachment's LastWriteTime if ( part.Header.ContentDispositionParameters.ContainsKey("modification-date") ) attachment.LastWriteTime = anmar.SharpMimeTools.SharpMimeTools.parseDate ( part.Header.ContentDispositionParameters["modification-date"] ); if ( part.Header.Contains("Content-ID") ) attachment.ContentID = part.Header.ContentID; this._attachments.Add(attachment); } break; default: break; } }
private void decodeMessage( anmar.SharpMimeTools.SharpMimeMessage mm, System.Web.UI.WebControls.PlaceHolder entity ) { System.String inline = System.String.Empty; switch ( mm.Header.TopLevelMediaType ) { case anmar.SharpMimeTools.MimeTopLevelMediaType.multipart: case anmar.SharpMimeTools.MimeTopLevelMediaType.message: // TODO: allow other subtypes of "message" // Only message/rfc822 allowed, other subtypes ignored if ( mm.Header.TopLevelMediaType.Equals(anmar.SharpMimeTools.MimeTopLevelMediaType.message) && !mm.Header.SubType.Equals("rfc822") ) break; if ( mm.Header.SubType.Equals ("alternative") ) { if ( mm.PartsCount>0 ) { this.decodeMessage ( mm.GetPart(mm.PartsCount-1), entity); } // TODO: Take into account each subtype of "multipart" } else if ( mm.PartsCount>0 ) { System.Web.UI.WebControls.PlaceHolder nestedentity = new System.Web.UI.WebControls.PlaceHolder (); System.Collections.IEnumerator enu = mm.GetEnumerator(); while ( enu.MoveNext() ) { this.decodeMessage ((anmar.SharpMimeTools.SharpMimeMessage) enu.Current, nestedentity); } entity.Controls.Add (nestedentity); } break; case anmar.SharpMimeTools.MimeTopLevelMediaType.text: if ( ( mm.Disposition==null || !mm.Disposition.Equals("attachment") ) && ( mm.Header.SubType.Equals("plain") || mm.Header.SubType.Equals("html") ) ) { System.Web.UI.WebControls.Label label = new System.Web.UI.WebControls.Label (); label.Text = mm.BodyDecoded; if ( mm.IsTextBrowserDisplay ) { label.Text = System.Web.HttpUtility.HtmlEncode (label.Text); label.Text = label.Text.Insert (0, "<pre id=\"message\">"); label.Text = label.Text.Insert (label.Text.Length, "</pre>"); } else { label.CssClass = "XPFormText"; if ( (int)Application["sharpwebmail/read/message/sanitizer_mode"]==1 ) { label.Text = anmar.SharpWebMail.BasicSanitizer.SanitizeHTML(label.Text, anmar.SharpWebMail.SanitizerMode.CommentBlocks|anmar.SharpWebMail.SanitizerMode.RemoveEvents); } } entity.Controls.Add (label); break; } else { goto case anmar.SharpMimeTools.MimeTopLevelMediaType.application; } case anmar.SharpMimeTools.MimeTopLevelMediaType.application: case anmar.SharpMimeTools.MimeTopLevelMediaType.audio: case anmar.SharpMimeTools.MimeTopLevelMediaType.image: case anmar.SharpMimeTools.MimeTopLevelMediaType.video: System.Web.UI.WebControls.HyperLink attachment = new System.Web.UI.WebControls.HyperLink (); System.Web.UI.WebControls.Image image = null; attachment.CssClass = "XPDownload"; if ( mm.Name!=null ) attachment.Text = System.String.Format ("{0} ({1} bytes)", System.IO.Path.GetFileName(mm.Name), mm.Size); if ( Session["sharpwebmail/read/message/temppath"]!=null ) { System.String path = Session["sharpwebmail/read/message/temppath"].ToString(); path = System.IO.Path.Combine (path, msgid); // Dump file contents System.IO.FileInfo file = mm.DumpBody ( path, true ); if ( file!=null && file.Exists ) { System.String urlstring = System.String.Format("download.aspx?msgid={0}&name={1}&i={2}", Server.UrlEncode(msgid), Server.UrlEncode(file.Name), inline); if ( mm.Disposition!=null && mm.Disposition.Equals("inline") ) { inline = "1"; if ( mm.Header.TopLevelMediaType.Equals(anmar.SharpMimeTools.MimeTopLevelMediaType.image) && ( mm.Header.SubType.Equals("gif") || mm.Header.SubType.Equals("jpg") || mm.Header.SubType.Equals("png")) ) { image = new System.Web.UI.WebControls.Image (); image.ImageUrl = urlstring; } } attachment.NavigateUrl = urlstring; attachment.Text = System.String.Format ("{0} ({1} bytes)", file.Name, file.Length); } } this.readMessageWindowAttachmentsHolder.Controls.Add (attachment); // Display inline image if ( image!=null ) { entity.Controls.Add (image); } break; default: break; } }