コード例 #1
0
        /// <summary>
        ///    事务超时计算函数
        /// </summary>
        protected virtual void TimerElapsed()
        {
            if (_transactions.Count == 0)
            {
                return;
            }
            IList <TransactionIdentity> expireValues = new List <TransactionIdentity>();

            //check dead flag for transaction.
            foreach (KeyValuePair <TransactionIdentity, IMessageTransaction <TMessage> > pair in _transactions)
            {
                if (pair.Value.GetLease().IsDead)
                {
                    expireValues.Add(pair.Key);
                }
            }
            if (expireValues.Count == 0)
            {
                return;
            }
            //remove expired transactions.
            foreach (TransactionIdentity expireValue in expireValues)
            {
                IMessageTransaction <TMessage> transaction = GetRemove(expireValue);
                if (transaction != null)
                {
                    ((MessageTransaction <TMessage>)transaction).SetTimeout();
                    TransactionExpiredHandler(new LightSingleArgEventArgs <IMessageTransaction <TMessage> >(transaction));
                }
            }
        }
コード例 #2
0
        public override Task <SmtpResponse> SaveAsync(ISessionContext context, IMessageTransaction transaction, CancellationToken cancellationToken)
        {
            var textMessage = (ITextMessage)transaction.Message;

            var message = MimeKit.MimeMessage.Load(textMessage.Content);

            Console.WriteLine("New message from {0}: {1}", message.From, message.Subject);

            var email = new Email()
            {
                Body           = message.HtmlBody,
                Cc             = message.Cc.Cast <MailboxAddress>().Select(x => x.Address).ToList(),
                From           = message.From.ToString(),
                HadAttachments = message.Attachments.Any(),
                Subject        = message.Subject,
                To             = message.To.Cast <MailboxAddress>().Select(x => x.Address).ToList(),

                ReceivedAt = DateTimeOffset.UtcNow,
            };

            _messages.Add(email);

            TrimStorage();

            return(Task.FromResult(SmtpResponse.Ok));
        }
コード例 #3
0
        public override Task <SmtpResponse> SaveAsync(ISessionContext context, IMessageTransaction transaction, CancellationToken cancellationToken)
        {
            var id         = Guid.NewGuid().ToString("n");
            var receivedOn = DateTime.Now;

            var textMessage = (ITextMessage)transaction.Message;

            var message = MimeMessage.Load(textMessage.Content);

            var model = new MessageModel()
            {
                Id          = id,
                From        = GetFromAddress(message),
                To          = message.To.ToString(),
                Subject     = message.Subject,
                HtmlBody    = message.HtmlBody,
                TextBody    = message.TextBody,
                Attachments = GetAttachments(message),
                ReceivedOn  = receivedOn
            };

            MessageManager.AddMessage(model);

            return(Task.FromResult(SmtpResponse.Ok));
        }
コード例 #4
0
 /// <summary>
 /// Save the given message to the underlying storage system.
 /// </summary>
 /// <param name="context">The session context.</param>
 /// <param name="transaction">The SMTP message transaction to store.</param>
 /// <param name="cancellationToken">The cancellation token.</param>
 /// <returns>The response code to return that indicates the result of the message being saved.</returns>
 public override Task <SmtpResponse> SaveAsync(
     ISessionContext context,
     IMessageTransaction transaction,
     CancellationToken cancellationToken)
 {
     return(Task.FromResult(_delegate(context, transaction)));
 }
コード例 #5
0
        /// <inheritdoc />
        public override Task <SmtpResponse> SaveAsync(ISessionContext context, IMessageTransaction transaction, CancellationToken cancellationToken)
        {
            var textMessage = (ITextMessage)transaction.Message;

            var message = MimeMessage.Load(textMessage.Content);

            foreach (var sender in message.From)
            {
                foreach (var recipient in message.To)
                {
                    if (!(sender is MailboxAddress senderEmail) || !(recipient is MailboxAddress recipientEmail))
                    {
                        continue;
                    }

                    try
                    {
                        var acmeMessage = MimeKitConverter.ConvertToMessage(senderEmail, recipientEmail, message);
                        Log.Info($"INCOMING FROM {senderEmail.Address} TO {recipientEmail.Address} : {message.Subject}");

                        this.MessageReceived?.Invoke(this, acmeMessage);
                    }
                    catch (Exception e)
                    {
                        Log.Error(e);
                    }
                }
            }

            return(Task.FromResult(SmtpResponse.Ok));
        }
コード例 #6
0
        public override async Task <SmtpResponse> SaveAsync(ISessionContext context, IMessageTransaction transaction, CancellationToken cancellationToken)
        {
            try
            {
                var textMessage = (ITextMessage)transaction.Message;
                var message     = MimeMessage.Load(textMessage.Content);
                var entity      = message.ToReceivedMail();
                var mailGuid    = entity.Headers.ContainsKey(MailGuidHeader)
                    ? entity.Headers[MailGuidHeader]
                    : Guid.NewGuid().ToString();
                foreach (var mimeEntity in message.Attachments)
                {
                    /* TODO store attachements as tmp files and load them to minio */
                }


                _backgroundJobClient.Enqueue <RedisMinioStoreJob>(rmsj => rmsj.StoreMail(transaction.To.Select(im => im.AsAddress()).ToList(), mailGuid, entity));
                return(SmtpResponse.Ok);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                return(SmtpResponse.MailboxUnavailable);
            }
        }
コード例 #7
0
ファイル: MailServer.cs プロジェクト: abdullah-19/com-crawler
            public override Task <SmtpResponse> SaveAsync(ISessionContext context, IMessageTransaction transaction, CancellationToken cancellationToken)
            {
                var textMessage = (ITextMessage)transaction.Message;

                var message = MimeKit.MimeMessage.Load(textMessage.Content);

                Log.Logs.Instance.Push($"[Mail Server] Mail received. from='{message.From}', to='{message.To}', title='{message.Subject}'");

                var mailbox_path = Path.Combine(AppProvider.ApplicationPath, "mailbox");

                if (!Directory.Exists(mailbox_path))
                {
                    Directory.CreateDirectory(mailbox_path);
                }

                var save_path = Path.Combine(mailbox_path, $"{DateTime.Now.Ticks}-{(message.Subject + Crypto.Random.RandomString(15)).GetHashMD5()}.mime");

                File.WriteAllText(save_path, message.ToString());

                DataBase.Add(new MailColumnModel
                {
                    Title    = message.Subject,
                    DateTime = message.Date.UtcDateTime.Ticks.ToString(),
                    From     = message.From.ToString(),
                    To       = message.To.ToString(),
                    FileName = save_path,
                });

                return(Task.FromResult(SmtpResponse.Ok));
            }
コード例 #8
0
        public async Task <SmtpResponse> SaveAsync(ISessionContext context, IMessageTransaction transaction, CancellationToken stoppingToken)
        {
            try
            {
                _logger.LogInformation($"Using stack {_stack.Name}.");

                MimeMessage message;
                using (var stream = ((ITextMessage)transaction.Message).Content)
                {
                    message = MimeMessage.Load(stream);
                }

                AddBccEmails(message, transaction);

                // ReSharper disable once LoopCanBeConvertedToQuery
                foreach (var middleware in _stack.Middlewares)
                {
                    message = await middleware.RunAsync(message, context, transaction, stoppingToken).ConfigureAwait(false);
                }
            }
            catch (Exception exception)
            {
                _logger.Log(LogLevel.Error, "Email middleware routing failed");
                return(new SmtpResponse(SmtpReplyCode.TransactionFailed, exception.Message));
            }

            return(SmtpResponse.Ok);
        }
コード例 #9
0
ファイル: Program.cs プロジェクト: kbilsted/SmtpServerDemo
        public override Task <SmtpResponse> SaveAsync(ISessionContext context, IMessageTransaction transaction, CancellationToken cancellationToken)
        {
            var         textMessage = (ITextMessage)transaction.Message;
            MimeMessage message     = MimeKit.MimeMessage.Load(textMessage.Content);

            _buffer.Add(message);
            return(Task.FromResult(SmtpResponse.Ok));
        }
コード例 #10
0
        public MockMessage(IMessageTransaction transaction, ReadOnlySequence <byte> buffer)
        {
            Transaction = transaction;

            using var stream = new MemoryStream(buffer.ToArray());

            MimeMessage = MimeMessage.Load(stream);
        }
コード例 #11
0
 public MessageTransactionDecorator(
     IMessageTransaction source,
     IOutboundTransport outbound,
     InboundTransportOptions options)
 {
     this.source = source;
     this.outbound = outbound;
     this.options = options;
 }
コード例 #12
0
        public override Task <SmtpResponse> SaveAsync(ISessionContext context, IMessageTransaction transaction, CancellationToken cancellationToken)
        {
            var textMessage = (ITextMessage)transaction.Message;
            var message     = MimeMessage.Load(textMessage.Content);

            Messages.Add(message);
            _semaphore.Release();
            return(Task.FromResult(SmtpResponse.Ok));
        }
コード例 #13
0
        public override async Task <SmtpResponse> SaveAsync(ISessionContext context, IMessageTransaction transaction,
                                                            CancellationToken cancellationToken)
        {
            var statusUser = Config.GetSection("StatusUser").Value;
            var alarmUser  = Config.GetSection("AlarmUser").Value;

            var textMessage = (ITextMessage)transaction.Message;

            var message = MimeMessage.Load(textMessage.Content);

            var user = transaction.To.First().User;

            //
            // Send SMS in alert event only
            //
            if (user.Equals(alarmUser, StringComparison.InvariantCultureIgnoreCase))
            {
                Logger.LogInformation("Received alarm event");

                var apiKey = Guid.Parse(Config.GetSection("ApiKey").Value);

                var from = Config.GetSection("From").Value;

                var recipients = Config.GetSection("Recipients").GetChildren().Select(e => e.Value).ToList();

                Logger.LogInformation(
                    $"Will send alarm SMS to the following recipients: {string.Join(", ", recipients)}");

                var client = new TextClient(apiKey);

                var result = await client
                             .SendMessageAsync(message.TextBody, from, recipients, transaction.From.User, cancellationToken)
                             .ConfigureAwait(false);

                if (result.statusCode == TextClientStatusCode.Ok)
                {
                    Logger.LogInformation($"Successfully sent the following message to recipients: {message.TextBody}");

                    return(await Task.FromResult(SmtpResponse.Ok));
                }

                Logger.LogError($"Message delivery failed: {result.statusMessage} ({result.statusCode})");

                return(await Task.FromResult(SmtpResponse.TransactionFailed));
            }

            if (user.Equals(statusUser, StringComparison.InvariantCultureIgnoreCase))
            {
                Logger.LogInformation($"Received status change: {message.TextBody}");
            }
            else
            {
                Logger.LogWarning($"Unknown message received (maybe a test?): {message.TextBody}");
            }

            return(await Task.FromResult(SmtpResponse.Ok));
        }
コード例 #14
0
 public MessageTransactionDecorator(
     IMessageTransaction source,
     IOutboundTransport outbound,
     InboundTransportOptions options)
 {
     this.source   = source;
     this.outbound = outbound;
     this.options  = options;
 }
コード例 #15
0
            public override Task <SmtpResponse> SaveAsync(ISessionContext context, IMessageTransaction transaction, CancellationToken cancellationToken)
            {
                var textMessage = ( ITextMessage )transaction.Message;
                var message     = MimeKit.MimeMessage.Load(textMessage.Content);

                actualEmails.Push(message.HtmlBody);

                return(Task.FromResult(SmtpResponse.Ok));
            }
コード例 #16
0
 private static string GetReceivedBody(IMessageTransaction receivedMessage)
 {
     if (receivedMessage.Message is ITextMessage textMessage)
     {
         var streamReader = new StreamReader(textMessage.Content);
         return(streamReader.ReadToEnd());
     }
     throw new NotSupportedException("only ITextMessage supported");
 }
コード例 #17
0
        public override async Task <SmtpResponse> SaveAsync(ISessionContext context, IMessageTransaction transaction, CancellationToken cancellationToken)
        {
            var textMessage = (ITextMessage)transaction.Message;
            var message     = MimeKit.MimeMessage.Load(textMessage.Content);

            queueService.Push(QueuedEmailMessage.FromMimeMessage(message));

            return(SmtpResponse.Ok);
        }
コード例 #18
0
        /// <summary>
        ///     激活一个事务,并尝试处理该事务的响应消息流程
        /// </summary>
        /// <param name="identity">事务唯一标示</param>
        /// <param name="response">响应消息</param>
        public void Active(TransactionIdentity identity, TMessage response)
        {
            IMessageTransaction <TMessage> transaction = GetRemove(identity);

            if (transaction == null)
            {
                return;
            }
            transaction.SetResponse(response);
        }
コード例 #19
0
        /// <summary>
        ///     为一个管理中的事务进行续约操作
        /// </summary>
        /// <param name="key">事务唯一键值</param>
        /// <param name="timeSpan">续约时间</param>
        /// <returns>
        ///     返回续约后的时间
        ///     <para>* 如果返回值 = MIN(DateTime), 则表示续约失败</para>
        /// </returns>
        public virtual DateTime Renew(TransactionIdentity key, TimeSpan timeSpan)
        {
            IMessageTransaction <TMessage> transaction = GetTransaction(key);

            if (transaction == null)
            {
                return(DateTime.MinValue);
            }
            return(transaction.GetLease().Renew(timeSpan));
        }
コード例 #20
0
        /// <summary>
        /// Save the given message to the underlying storage system.
        /// </summary>
        /// <param name="context">The session context.</param>
        /// <param name="transaction">The SMTP message transaction to store.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>A unique identifier that represents this message in the underlying message store.</returns>
        public override Task <SmtpResponse> SaveAsync(ISessionContext context, IMessageTransaction transaction, CancellationToken cancellationToken)
        {
            var textMessage = (ITextMessage)transaction.Message;

            using (var reader = new StreamReader(textMessage.Content, Encoding.UTF8))
            {
                Console.WriteLine("Hello Data" + reader.ReadToEnd());
            }

            return(Task.FromResult(SmtpResponse.Ok));
        }
コード例 #21
0
        public override async Task <SmtpResponse> SaveAsync(ISessionContext context, IMessageTransaction transaction, CancellationToken cancellationToken)
        {
            var message = MimeMessage.Load(((ITextMessage)transaction.Message).Content);

            await _bot.SendTextMessageAsync(
                chatId : _chatId,
                text : $"{message.Subject}\nFrom: {message.From}\nTo: {message.To}\n{message.TextBody}",
                cancellationToken : cancellationToken);

            return(SmtpResponse.Ok);
        }
コード例 #22
0
        public override Task <SmtpResponse> SaveAsync(ISessionContext context, IMessageTransaction transaction, ReadOnlySequence <byte> buffer, CancellationToken cancellationToken)
        {
            var scope = (IServiceScope)context.Properties[SmtpServerConstants.Scope];

            var logger = scope.ServiceProvider.GetRequiredService <ILogger <MailDamMessageStore> >();

            Guid sessionId = (Guid)context.Properties[SmtpServerConstants.SessionId];
            var  mailboxId = (Guid)context.Properties[SmtpServerConstants.Mailbox];

            var mailId = Guid.NewGuid();

            var mailboxRepository = scope.ServiceProvider.GetService <IMailboxRepository>();

            var mailbox = mailboxRepository.Get(mailboxId, false);

            var mailRepository = scope.ServiceProvider.GetService <IMailRepository>();

            using var messageStream = new MemoryStream();

            var position = buffer.GetPosition(0);

            while (buffer.TryGet(ref position, out var memory))
            {
                messageStream.Write(memory.Span);
            }

            messageStream.Position = 0;

            var message = MimeKit.MimeMessage.LoadAsync(messageStream, cancellationToken).Result;

            bool result = true;

            if (mailbox.ImapEnabled && message != null)
            {
                try
                {
                    Imap.SendMessageToImap(mailbox, message);

                    logger.LogInformation($"Storing mail {mailId} in session {sessionId} for mailbox {mailbox.MailboxId} in imap");
                }
                catch (Exception e)
                {
                    logger.LogError(e, $"Storing of mail failed with in session {sessionId} for mailbox {mailbox.MailboxId} in imap because: {e.Message}");
                    result = false;
                }
            }

            if (!mailbox.Passthrough && message != null)
            {
                result = result && SaveMessage(logger, mailRepository, messageStream, mailId, message, mailboxId, sessionId);
            }

            return(result ? Task.FromResult(SmtpResponse.Ok) : Task.FromResult(SmtpResponse.TransactionFailed));
        }
コード例 #23
0
        /// <summary>
        /// Return the MIME content of the text message.
        /// </summary>
        /// <param name="messageTransaction">The message transaction to return the message text body from.</param>
        /// <returns>The MIME content of the text message.</returns>
        public static string Mime(this IMessageTransaction messageTransaction)
        {
            if (messageTransaction == null)
            {
                throw new ArgumentNullException(nameof(messageTransaction));
            }

            var textMessage = (ITextMessage)messageTransaction.Message;

            return(textMessage.Mime());
        }
コード例 #24
0
        public override async Task <SmtpResponse> SaveAsync(
            ISessionContext context,
            IMessageTransaction transaction,
            ReadOnlySequence <byte> buffer,
            CancellationToken cancellationToken)
        {
            await this._receivedDataHandler.HandleReceivedAsync(
                buffer.ToArray(),
                transaction.To.Select(s => s.AsAddress()).ToArray());

            return(SmtpResponse.Ok);
        }
コード例 #25
0
        public override async Task <SmtpResponse> SaveAsync(ISessionContext context, IMessageTransaction transaction, ReadOnlySequence <byte> buffer, CancellationToken cancellationToken)
        {
            var stream  = new MemoryStream(buffer.ToArray(), writable: false);
            var message = await MimeMessage.LoadAsync(stream, cancellationToken);

            await _bot.SendTextMessageAsync(
                chatId : _chatId,
                text : $"{message.Subject}\nFrom: {message.From}\nTo: {message.To}\n{message.TextBody}",
                cancellationToken : cancellationToken);

            return(SmtpResponse.Ok);
        }
コード例 #26
0
        /// <summary>
        /// Returns the subject from the message.
        /// </summary>
        /// <param name="messageTransaction">The message transaction to return the message subject from.</param>
        /// <returns>The message subject from the message transaction.</returns>
        public static string Subject(this IMessageTransaction messageTransaction)
        {
            if (messageTransaction == null)
            {
                throw new ArgumentNullException(nameof(messageTransaction));
            }

            var textMessage = (ITextMessage)messageTransaction.Message;

            textMessage.Content.Position = 0;

            return(MimeKit.MimeMessage.Load(textMessage.Content).Subject);
        }
コード例 #27
0
        public override async Task <SmtpResponse> SaveAsync(
            ISessionContext context,
            IMessageTransaction transaction,
            CancellationToken cancellationToken)
        {
            var textMessage = (ITextMessage)transaction.Message;

            this._receivedDataHandler.HandleReceived(
                await ToArrayAsync(textMessage.Content),
                transaction.To.Select(s => s.AsAddress()).ToArray());

            return(SmtpResponse.Ok);
        }
コード例 #28
0
        SaveAsync(ISessionContext context,
                  IMessageTransaction transaction,
                  CancellationToken cancellationToken)
        {
            ITextMessage textMessage = (ITextMessage)transaction.Message;

            using (var reader = new StreamReader(textMessage.Content, Encoding.UTF8))
            {
                Message.Invoke(reader.ReadToEnd());
            }

            return(Task.FromResult(SmtpResponse.Ok));
        }
コード例 #29
0
        /*
         * BCC recipients are not part of the MIME message so they are not added to
         * the MimeMessage. See: https://github.com/cosullivan/SmtpServer/issues/35
         * To solve this problem, we add all transaction emails that are not part of
         * the MIME message to the BCC.
         */
        private void AddBccEmails(MimeMessage message, IMessageTransaction transaction)
        {
            var messageEmails = FlattenInternetAddresses(message.To.Union(message.Cc))
                                .Select(ma => ma.Address.ToLower());

            var transactionEmails = transaction.To
                                    .Select(m => m.AsAddress().ToLower())
                                    .Distinct();

            var bccMailboxAddresses = transactionEmails.Except(messageEmails)
                                      .Select(s => new MailboxAddress(s));

            message.Bcc.AddRange(bccMailboxAddresses);
        }
コード例 #30
0
        public override async Task <SmtpResponse> SaveAsync(ISessionContext context, IMessageTransaction transaction, ReadOnlySequence <byte> buffer, CancellationToken cancellationToken)
        {
            logger.LogInformation("Mail.Receive :: begin");

            try
            {
                using var scope        = serviceScopeFactory.CreateScope();
                await using var stream = new MemoryStream();

                var position = buffer.GetPosition(0);
                while (buffer.TryGet(ref position, out var memory))
                {
                    await stream.WriteAsync(memory, cancellationToken);
                }

                stream.Position = 0;
                var message = await MimeMessage.LoadAsync(stream, cancellationToken);

                logger.LogInformation($"Mail.Receive :: subject:{message.Subject}, sender:{message.From}");

                bool saved = false;
                if (message.Subject.Equals("motion", StringComparison.OrdinalIgnoreCase))
                {
                    string sourceId = message.From.FirstOrDefault().ToString();
                    sourceId = sourceId.Substring(0, sourceId.IndexOf("@"));

                    var device = jsonDatabaseService.Cameras.FirstOrDefault(c => c.SourceID == sourceId);
                    if (device != null)
                    {
                        await scope.ServiceProvider.GetService <ITriggerService>().FireTriggersFromDevice(device, DeviceEvent.Motion);
                        await SaveToEml(scope, message.MessageId, stream.ToArray(), device.Source.ToString(), device.SourceID);

                        saved = true;
                    }
                }

                if (!saved)
                {
                    await SaveToEml(scope, message.MessageId, stream.ToArray(), "raw", "unknown");
                }
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "Mail.Receive :: unknown error");
            }

            logger.LogInformation("Mail.Receive :: done");
            return(SmtpResponse.Ok);
        }
コード例 #31
0
        /// <summary>
        /// Returns the text message body.
        /// </summary>
        /// <param name="messageTransaction">The message transaction to return the message text body from.</param>
        /// <param name="charset">The character set to use.</param>
        /// <returns>The message text body from the message transaction.</returns>
        public static string Text(this IMessageTransaction messageTransaction, string charset = "utf-8")
        {
            if (messageTransaction == null)
            {
                throw new ArgumentNullException(nameof(messageTransaction));
            }

            var textMessage = (ITextMessage)messageTransaction.Message;

            textMessage.Content.Position = 0;

            var message = MimeKit.MimeMessage.Load(textMessage.Content);

            return(((TextPart)message.Body).GetText(charset).TrimEnd('\n', '\r'));
        }
コード例 #32
0
ファイル: MessageWorker.cs プロジェクト: jamesholcomb/NDomain
        private async Task ProcessTransaction(IMessageTransaction transaction)
        {
            Func<Task> completion;

            try
            {
                using (new DomainTransactionScope(transaction.Message.Id, transaction.RetryCount))
                {
                    // process message within a logical transaction that can be used for processing idempotency
                    await this.messageDispatcher.ProcessMessage(transaction.Message);
                }

                completion = () => transaction.Commit();
            }
            catch (Exception ex)
            {
                this.logger.Error(ex,
                                     "Failed to process message {0} with id {1}",
                                     transaction.Message.Name,
                                     transaction.Message.Id);

                completion = () => transaction.Fail();
            }

            // try to complete the transaction, regardless of failures
            try
            {
                await completion();
            }
            catch (Exception ex)
            {
                this.logger.Error(ex,
                                     "Failed to complete message {0} with id {1}",
                                     transaction.Message.Name,
                                     transaction.Message.Id);
            }
        }