コード例 #1
0
        /// <summary>
        ///     Sends an array of email messages using a session state object.
        ///     Credentials, Enable SSL and Client Hostname are NOT taken from the state object but
        ///     rather from the properties of this class.
        /// </summary>
        /// <param name="sessionStates">The session states.</param>
        /// <param name="sessionId">The session identifier.</param>
        /// <param name="ct">The cancellation token.</param>
        /// <returns>
        ///     A task that represents the asynchronous of send email operation.
        /// </returns>
        /// <exception cref="ArgumentNullException">sessionStates.</exception>
        /// <exception cref="SecurityException">Could not upgrade the channel to SSL.</exception>
        /// <exception cref="SmtpException">Defines an SMTP Exceptions class.</exception>
        public async Task SendMailAsync(IEnumerable <SmtpSessionState> sessionStates, string sessionId = null, CancellationToken ct = default)
        {
            if (sessionStates == null)
            {
                throw new ArgumentNullException(nameof(sessionStates));
            }

            using (var tcpClient = new TcpClient())
            {
                await tcpClient.ConnectAsync(Host, Port);

                using (var connection = new Connection(tcpClient, Encoding.UTF8, "\r\n", true, 1000))
                {
                    var sender = new SmtpSender(sessionId);

                    try
                    {
                        // Read the greeting message
                        sender.ReplyText = await connection.ReadLineAsync(ct);

                        // EHLO 1
                        sender.RequestText = $"{SmtpCommandNames.EHLO} {ClientHostname}";

                        await connection.WriteLineAsync(sender.RequestText, ct);

                        do
                        {
                            sender.ReplyText = await connection.ReadLineAsync(ct);
                        } while (!sender.IsReplyOk);

                        sender.ValidateReply();

                        // STARTTLS
                        if (EnableSsl)
                        {
                            sender.RequestText = $"{SmtpCommandNames.STARTTLS}";

                            await connection.WriteLineAsync(sender.RequestText, ct);

                            sender.ReplyText = await connection.ReadLineAsync(ct);

                            sender.ValidateReply();

                            if (await connection.UpgradeToSecureAsClientAsync() == false)
                            {
                                throw new SecurityException("Could not upgrade the channel to SSL.");
                            }
                        }

                        {
                            // EHLO 2
                            sender.RequestText = $"{SmtpCommandNames.EHLO} {ClientHostname}";

                            await connection.WriteLineAsync(sender.RequestText, ct);

                            do
                            {
                                sender.ReplyText = await connection.ReadLineAsync(ct);
                            } while (!sender.IsReplyOk);

                            sender.ValidateReply();
                        }

                        // AUTH
                        if (Credentials != null)
                        {
                            var auth = new ConnectionAuth(connection, sender, Credentials);
                            await auth.AuthenticateAsync(ct);
                        }

                        foreach (var sessionState in sessionStates)
                        {
                            {
                                // MAIL FROM
                                sender.RequestText = $"{SmtpCommandNames.MAIL} FROM:<{sessionState.SenderAddress}>";

                                await connection.WriteLineAsync(sender.RequestText, ct);

                                sender.ReplyText = await connection.ReadLineAsync(ct);

                                sender.ValidateReply();
                            }

                            // RCPT TO
                            foreach (var recipient in sessionState.Recipients)
                            {
                                sender.RequestText = $"{SmtpCommandNames.RCPT} TO:<{recipient}>";

                                await connection.WriteLineAsync(sender.RequestText, ct);

                                sender.ReplyText = await connection.ReadLineAsync(ct);

                                sender.ValidateReply();
                            }

                            {
                                // DATA
                                sender.RequestText = $"{SmtpCommandNames.DATA}";

                                await connection.WriteLineAsync(sender.RequestText, ct);

                                sender.ReplyText = await connection.ReadLineAsync(ct);

                                sender.ValidateReply();
                            }

                            {
                                // CONTENT
                                var dataTerminator = sessionState.DataBuffer.Skip(sessionState.DataBuffer.Count - 5).ToArray().ToText();

                                sender.RequestText = $"Buffer ({sessionState.DataBuffer.Count} bytes)";

                                await connection.WriteDataAsync(sessionState.DataBuffer.ToArray(), true, ct);

                                if (dataTerminator.EndsWith(SmtpDefinitions.SmtpDataCommandTerminator) == false)
                                {
                                    await connection.WriteTextAsync(SmtpDefinitions.SmtpDataCommandTerminator, ct);
                                }

                                sender.ReplyText = await connection.ReadLineAsync(ct);

                                sender.ValidateReply();
                            }
                        }

                        {
                            // QUIT
                            sender.RequestText = $"{SmtpCommandNames.QUIT}";

                            await connection.WriteLineAsync(sender.RequestText, ct);

                            sender.ReplyText = await connection.ReadLineAsync(ct);

                            sender.ValidateReply();
                        }
                    }
                    catch (Exception ex)
                    {
                        var errorMessage = $"Could not send email. {ex.Message}\r\n    Last Request: {sender.RequestText}\r\n    Last Reply: {sender.ReplyText}";
                        errorMessage.Error(typeof(SmtpClient).FullName, sessionId);

                        throw new SmtpException(errorMessage);
                    }
                }
            }
        }
コード例 #2
0
        /// <summary>
        /// Sends an array of email messages using a session state object.
        /// Credentials, Enable SSL and Client Hostname are NOT taken from the state object but
        /// rather from the properties of this class.
        /// </summary>
        /// <param name="sessionStates">The session states.</param>
        /// <param name="sessionId">The session identifier.</param>
        /// <param name="callback">The callback.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>
        /// A task that represents the asynchronous of send email operation.
        /// </returns>
        /// <exception cref="ArgumentNullException">sessionStates.</exception>
        /// <exception cref="SecurityException">Could not upgrade the channel to SSL.</exception>
        /// <exception cref="SmtpException">Defines an SMTP Exceptions class.</exception>
        public async Task SendMailAsync(
            IEnumerable <SmtpSessionState> sessionStates,
            string?sessionId = null,
            RemoteCertificateValidationCallback?callback = null,
            CancellationToken cancellationToken          = default)
        {
            if (sessionStates == null)
            {
                throw new ArgumentNullException(nameof(sessionStates));
            }

            using var tcpClient = new TcpClient();
            await tcpClient.ConnectAsync(Host, Port, cancellationToken).ConfigureAwait(false);

            using var connection = new Connection(tcpClient, Encoding.UTF8, "\r\n", true, 1000);
            var sender = new SmtpSender(sessionId);

            try
            {
                // Read the greeting message
                sender.ReplyText = await connection.ReadLineAsync(cancellationToken).ConfigureAwait(false);

                // EHLO 1
                await SendEhlo(sender, connection, cancellationToken).ConfigureAwait(false);

                // STARTTLS
                if (EnableSsl)
                {
                    sender.RequestText = $"{SmtpCommandNames.STARTTLS}";

                    await connection.WriteLineAsync(sender.RequestText, cancellationToken).ConfigureAwait(false);

                    sender.ReplyText = await connection.ReadLineAsync(cancellationToken).ConfigureAwait(false);

                    sender.ValidateReply();

                    if (await connection.UpgradeToSecureAsClientAsync(callback: callback).ConfigureAwait(false) == false)
                    {
                        throw new SecurityException("Could not upgrade the channel to SSL.");
                    }
                }

                // EHLO 2
                await SendEhlo(sender, connection, cancellationToken).ConfigureAwait(false);

                // AUTH
                if (Credentials != null)
                {
                    var auth = new ConnectionAuth(connection, sender, Credentials);
                    await auth.AuthenticateAsync(cancellationToken).ConfigureAwait(false);
                }

                foreach (var sessionState in sessionStates)
                {
                    {
                        // MAIL FROM
                        sender.RequestText = $"{SmtpCommandNames.MAIL} FROM:<{sessionState.SenderAddress}>";

                        await connection.WriteLineAsync(sender.RequestText, cancellationToken).ConfigureAwait(false);

                        sender.ReplyText = await connection.ReadLineAsync(cancellationToken).ConfigureAwait(false);

                        sender.ValidateReply();
                    }

                    // RCPT TO
                    foreach (var recipient in sessionState.Recipients)
                    {
                        sender.RequestText = $"{SmtpCommandNames.RCPT} TO:<{recipient}>";

                        await connection.WriteLineAsync(sender.RequestText, cancellationToken).ConfigureAwait(false);

                        sender.ReplyText = await connection.ReadLineAsync(cancellationToken).ConfigureAwait(false);

                        sender.ValidateReply();
                    }

                    {
                        // DATA
                        sender.RequestText = $"{SmtpCommandNames.DATA}";

                        await connection.WriteLineAsync(sender.RequestText, cancellationToken).ConfigureAwait(false);

                        sender.ReplyText = await connection.ReadLineAsync(cancellationToken).ConfigureAwait(false);

                        sender.ValidateReply();
                    }

                    {
                        // CONTENT
                        var dataTerminator = sessionState.DataBuffer
                                             .Skip(sessionState.DataBuffer.Count - 5)
                                             .ToText();

                        sender.RequestText = $"Buffer ({sessionState.DataBuffer.Count} bytes)";

                        await connection.WriteDataAsync(sessionState.DataBuffer.ToArray(), true, cancellationToken).ConfigureAwait(false);

                        if (!dataTerminator.EndsWith(SmtpDefinitions.SmtpDataCommandTerminator, StringComparison.OrdinalIgnoreCase))
                        {
                            await connection.WriteTextAsync(SmtpDefinitions.SmtpDataCommandTerminator, cancellationToken).ConfigureAwait(false);
                        }

                        sender.ReplyText = await connection.ReadLineAsync(cancellationToken).ConfigureAwait(false);

                        sender.ValidateReply();
                    }
                }

                {
                    // QUIT
                    sender.RequestText = $"{SmtpCommandNames.QUIT}";

                    await connection.WriteLineAsync(sender.RequestText, cancellationToken).ConfigureAwait(false);

                    sender.ReplyText = await connection.ReadLineAsync(cancellationToken).ConfigureAwait(false);

                    sender.ValidateReply();
                }
            }
            catch (Exception ex)
            {
                throw new SmtpException($"Could not send email - Session ID {sessionId}. {ex.Message}\r\n    Last Request: {sender.RequestText}\r\n    Last Reply: {sender.ReplyText}");
            }
        }