diff --git a/AegisImplictMail/MimeAttachment.cs b/AegisImplictMail/MimeAttachment.cs
index 5473fc8..c55cf80 100644
--- a/AegisImplictMail/MimeAttachment.cs
+++ b/AegisImplictMail/MimeAttachment.cs
@@ -2,6 +2,7 @@
using System.IO;
using System.Net.Mail;
using System.Net.Mime;
+using System.Text;
namespace AegisImplicitMail
{
@@ -16,9 +17,10 @@ public class MimeAttachment : Attachment
internal static int AttachCount;
private AttachmentLocation _location;
///
- /// File to send.
+ /// Attachment is a File Stream
///
- public string FileName { get; set; }
+ public bool isFileStream { get; private set; } = false;
+
///
/// Content type of file (application/octet-stream for regular attachments).
///
@@ -48,74 +50,106 @@ public AttachmentLocation Location
}
}
+ public string GetEncodedAttachmentName()
+ {
+ Encoding displayNameEncoding = this.NameEncoding ?? Encoding.UTF8;
+ if (displayNameEncoding.Equals(Encoding.ASCII))
+ {
+ return this.ContentType.Name;
+ }
+ else
+ {
+ string encodingName = displayNameEncoding.BodyName.ToLower();
+ string encodedName = $"=?{encodingName}?B?{Convert.ToBase64String(displayNameEncoding.GetBytes(this.ContentType.Name))}?=";
+ return encodedName;
+ }
+ }
+
#endregion
#region Constructors
- ///
- /// Default constructor.
- ///
- // public SmtpAttachment():base(){}
///
- /// Constructor for passing all information at once.
+ /// Initializes a new instance of the AegisImplicitMail.MimeAttachment class with the specified
+ /// content string.
///
- /// File to send.
- /// Content type of file (application/octet-stream for regular attachments.)
- /// Where to put the attachment.
- public MimeAttachment(string fileName, ContentType contentType, AttachmentLocation location)
+ /// A System.String that contains a file path to use to create this attachment
+ /// Attached or Inline
+ public MimeAttachment(string fileName, AttachmentLocation location = AttachmentLocation.Attachmed)
: base(fileName)
{
- if (string.IsNullOrEmpty(fileName))
- {
- throw new ArgumentException(nameof(fileName));
- }
- FileName = fileName;
- ContentType = contentType;
Location = location;
}
+ ///
+ /// Initializes a new instance of the AegisImplicitMail.MimeAttachment class with the specified
+ /// content string and System.Net.Mime.ContentType.
+ ///
+ /// A System.String that contains a file path to use to create this attachment.
+ /// A System.Net.Mime.ContentType that describes the data in string.
+ /// Attached or Inline
+ public MimeAttachment(string fileName, ContentType contentType, AttachmentLocation location = AttachmentLocation.Attachmed)
+ : base(fileName, contentType)
+ {
+ Location = location;
+ }
///
- /// Shortcut constructor for passing regular style attachments.
+ /// Initializes a new instance of the AegisImplicitMail.MimeAttachment class with the specified
+ /// stream and name.
///
- /// File to send.
- public MimeAttachment(string filename)
- : this(filename, new ContentType(MediaTypeNames.Application.Octet), AttachmentLocation.Attachmed)
+ /// A readable System.IO.Stream that contains the content for this attachment.
+ ///
+ /// A System.String that contains the value for the System.Net.Mime.ContentType.Name
+ /// property of the System.Net.Mime.ContentType associated with this attachment.
+ /// To ensure compatibility with the most number of email providers, this value cannot be null.
+ ///
+ /// Attached or Inline
+ public MimeAttachment(Stream contentStream, string name, AttachmentLocation location = AttachmentLocation.Attachmed)
+ : base(contentStream, name)
{
+ isFileStream = true;
+ Location = location;
}
///
- /// Constructor for passing stream attachments.
+ /// Initializes a new instance of the AegisImplicitMail.MimeAttachment class with the specified
+ /// stream and content type.
///
- /// Stream to the attachment contents
- /// Name of the attachment as it will appear on the e-mail
- /// Where to put the attachment
- public MimeAttachment(Stream contentStream, string name, AttachmentLocation location = AttachmentLocation.Attachmed)
- :this(contentStream, name, new ContentType(MediaTypeNames.Application.Octet), location)
+ /// A readable System.IO.Stream that contains the content for this attachment.
+ /// A System.Net.Mime.ContentType that describes the data in stream.
+ /// Attached or Inline
+ public MimeAttachment(Stream contentStream, ContentType contentType, AttachmentLocation location = AttachmentLocation.Attachmed)
+ :base(contentStream, contentType)
{
+ isFileStream = true;
+ Location = location;
}
///
/// Constructor for passing stream attachments.
+ /// This constructor has no equivalent in System.Net.Mail.Attachment constructors.
+ /// Stays here for compatibility reasons.
///
/// Stream to the attachment contents
/// Name of the attachment as it will appear on the e-mail
/// Content type of the attachment
- /// Where to put the attachment
+ /// Attached or Inline
public MimeAttachment(Stream contentStream, string name, ContentType contentType, AttachmentLocation location = AttachmentLocation.Attachmed)
- : base(contentStream, name)
+ : this(contentStream, name)
{
+ isFileStream = true;
Location = location;
- ContentType = contentType;
+ ContentType.Name = name;
}
///
/// Show this attachment.
///
- /// The file name of the attachment.
+ /// The name of the attachment.
public override string ToString()
{
- return FileName;
+ return this.ContentType.Name;
}
}
diff --git a/AegisImplictMail/SmtpSocketClient.cs b/AegisImplictMail/SmtpSocketClient.cs
index 4c76a48..2d5d883 100644
--- a/AegisImplictMail/SmtpSocketClient.cs
+++ b/AegisImplictMail/SmtpSocketClient.cs
@@ -1092,38 +1092,19 @@ private void SendAttachments(StringBuilder buf, AttachmentLocation type)
continue;
}
- Stream stream;
- string fileName;
- if (string.IsNullOrEmpty(attachment.FileName))
- {
- stream = attachment.ContentStream;
- fileName = attachment.Name;
- }
- else
- {
- stream = new FileStream(attachment.FileName, FileMode.Open, FileAccess.Read, FileShare.Read);
- fileName = Path.GetFileName(attachment.FileName);
- }
-
- var cs = new CryptoStream(stream, new ToBase64Transform(), CryptoStreamMode.Read);
+ var cs = new CryptoStream(attachment.ContentStream, new ToBase64Transform(), CryptoStreamMode.Read);
_con.SendCommand(seperator);
- var escapedFileName = fileName.Replace(@"\", @"\\").Replace(@"""", @"\""");
buf.Append("Content-Type: ");
buf.Append(attachment.ContentType);
- buf.Append("; name=\"");
- buf.Append(escapedFileName);
- buf.Append("\"");
_con.SendCommand(buf.ToString());
_con.SendCommand("Content-Transfer-Encoding: base64");
buf.Length = 0;
- buf.Append("Content-Disposition: attachment; filename=\"");
- buf.Append(escapedFileName);
- buf.Append("\"");
+ buf.Append("Content-Disposition: attachment; filename=");
+ buf.Append(attachment.GetEncodedAttachmentName());
_con.SendCommand(buf.ToString());
buf.Length = 0;
buf.Append("Content-ID: ");
- var escapedContentId = "<" + (!string.IsNullOrEmpty(attachment.ContentId) ? attachment.ContentId : Path.GetFileNameWithoutExtension(fileName).Replace(" ", "-")) + ">";
- buf.Append(escapedContentId);
+ buf.Append(attachment.ContentId);
buf.Append("\r\n");
_con.SendCommand(buf.ToString());
buf.Length = 0;