//
#if SECURITY_DEP
+
+#if MONOTOUCH || MONODROID
+using System.Security.Cryptography.X509Certificates;
+#else
extern alias PrebuiltSystem;
+using X509CertificateCollection = PrebuiltSystem::System.Security.Cryptography.X509Certificates.X509CertificateCollection;
+using System.Security.Cryptography.X509Certificates;
+#endif
+
#endif
using System;
using System.Net;
using System.Net.Mime;
using System.Net.Sockets;
-using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading;
using System.Reflection;
using System.Configuration;
using System.Net.Security;
using System.Security.Authentication;
-
-#if SECURITY_DEP
-using X509CertificateCollection = PrebuiltSystem::System.Security.Cryptography.X509Certificates.X509CertificateCollection;
-#endif
+using System.Threading.Tasks;
namespace System.Net.Mail {
public class SmtpClient
-#if NET_4_0
: IDisposable
-#endif
{
#region Fields
if (cfg != null) {
this.host = cfg.Network.Host;
this.port = cfg.Network.Port;
-#if NET_4_0
this.enableSsl = cfg.Network.EnableSsl;
-#endif
TargetName = cfg.Network.TargetName;
if (this.TargetName == null)
TargetName = "SMTPSVC/" + (host != null ? host : "");
if (port != 0)
this.port = port;
+ else if (this.port == 0)
+ this.port = 25;
}
#endregion // Constructors
}
#endif
-#if NET_4_0
public
-#endif
string TargetName { get; set; }
public ICredentialsByHost Credentials {
#endregion // Events
#region Methods
-#if NET_4_0
public void Dispose ()
{
Dispose (true);
{
// TODO: We should close all the connections and abort any async operations here
}
-#endif
private void CheckState ()
{
if (messageInProcess != null)
MailAddress from = message.From;
if (from == null)
from = defaultFrom;
-
- SendHeader (HeaderName.Date, DateTime.Now.ToString ("ddd, dd MMM yyyy HH':'mm':'ss zzz", DateTimeFormatInfo.InvariantInfo));
+
+ string dt = DateTime.Now.ToString("ddd, dd MMM yyyy HH':'mm':'ss zzz", DateTimeFormatInfo.InvariantInfo);
+ // remove ':' from time zone offset (e.g. from "+01:00")
+ dt = dt.Remove(dt.Length - 3, 1);
+ SendHeader(HeaderName.Date, dt);
+
SendHeader (HeaderName.From, EncodeAddress(from));
SendHeader (HeaderName.To, EncodeAddresses(message.To));
if (message.CC.Count > 0)
sfre.Add (new SmtpFailedRecipientException (status.StatusCode, message.Bcc [i].Address));
}
-#if TARGET_JVM // List<T>.ToArray () is not supported
- if (sfre.Count > 0) {
- SmtpFailedRecipientException[] xs = new SmtpFailedRecipientException[sfre.Count];
- sfre.CopyTo (xs);
- throw new SmtpFailedRecipientsException ("failed recipients", xs);
- }
-#else
if (sfre.Count >0)
throw new SmtpFailedRecipientsException ("failed recipients", sfre.ToArray ());
-#endif
// DATA
status = SendCommand ("DATA");
if (message.ReplyToList.Count > 0)
SendHeader ("Reply-To", EncodeAddresses (message.ReplyToList));
-#if NET_4_0
foreach (string s in message.Headers.AllKeys)
SendHeader (s, ContentType.EncodeSubjectRFC2047 (message.Headers [s], message.HeadersEncoding));
-#else
- foreach (string s in message.Headers.AllKeys)
- SendHeader (s, message.Headers [s]);
-#endif
AddPriorityHeader (message);
Send (new MailMessage (from, to, subject, body));
}
+ public Task SendMailAsync (MailMessage message)
+ {
+ var tcs = new TaskCompletionSource<object> ();
+ SendCompletedEventHandler handler = null;
+ handler = (s, e) => SendMailAsyncCompletedHandler (tcs, e, handler, this);
+ SendCompleted += handler;
+ SendAsync (message, tcs);
+ return tcs.Task;
+ }
+
+ public Task SendMailAsync (string from, string recipients, string subject, string body)
+ {
+ return SendMailAsync (new MailMessage (from, recipients, subject, body));
+ }
+
+ static void SendMailAsyncCompletedHandler (TaskCompletionSource<object> source, AsyncCompletedEventArgs e, SendCompletedEventHandler handler, SmtpClient client)
+ {
+ if ((object) handler != e.UserState)
+ return;
+
+ client.SendCompleted -= handler;
+
+ if (e.Error != null) {
+ source.SetException (e.Error);
+ return;
+ }
+
+ if (e.Cancelled) {
+ source.SetCanceled ();
+ return;
+ }
+
+ source.SetResult (null);
+ }
+
private void SendDot()
{
writer.Write(".\r\n");
CheckCancellation ();
if (escapeDots) {
- int i;
- for (i = 0; i < line.Length; i++) {
- if (line[i] != '.')
- break;
- }
- if (i > 0 && i == line.Length) {
- line += ".";
+ if (line.Length > 0 && line[0] == '.') {
+ line = "." + line;
}
}
writer.Write (line);
case TransferEncoding.Base64:
byte [] content = new byte [av.ContentStream.Length];
av.ContentStream.Read (content, 0, content.Length);
-#if TARGET_JVM
- SendData (Convert.ToBase64String (content));
-#else
SendData (Convert.ToBase64String (content, Base64FormattingOptions.InsertLineBreaks));
-#endif
break;
case TransferEncoding.QuotedPrintable:
byte [] bytes = new byte [av.ContentStream.Length];
case TransferEncoding.Base64:
byte [] content = new byte [lr.ContentStream.Length];
lr.ContentStream.Read (content, 0, content.Length);
-#if TARGET_JVM
- SendData (Convert.ToBase64String (content));
-#else
SendData (Convert.ToBase64String (content, Base64FormattingOptions.InsertLineBreaks));
-#endif
break;
case TransferEncoding.QuotedPrintable:
byte [] bytes = new byte [lr.ContentStream.Length];
att.ContentStream.Read (content, 0, content.Length);
switch (att.TransferEncoding) {
case TransferEncoding.Base64:
-#if TARGET_JVM
- SendData (Convert.ToBase64String (content));
-#else
SendData (Convert.ToBase64String (content, Base64FormattingOptions.InsertLineBreaks));
-#endif
break;
case TransferEncoding.QuotedPrintable:
SendData (ToQuotedPrintable (content));
throw new SmtpException (SmtpStatusCode.GeneralFailure, "Server does not support secure connections.");
}
-#if TARGET_JVM
- ((NetworkStream) stream).ChangeToSSLSocket ();
-#elif SECURITY_DEP
+#if SECURITY_DEP
SslStream sslStream = new SslStream (stream, false, callback, null);
CheckCancellation ();
sslStream.AuthenticateAsClient (Host, this.ClientCertificates, SslProtocols.Default, false);