Exemple #1
0
        private MessageEntitySummary HandleMimeEntity(MimeEntity entity)
        {
            int index = 0;

            return(MimeEntityVisitor.VisitWithResults <MessageEntitySummary>(entity, (e, p) =>
            {
                string fileName = PunyCodeReplacer.DecodePunycode(!string.IsNullOrEmpty(e.ContentDisposition?.FileName)
            ? e.ContentDisposition?.FileName
            : e.ContentType?.Name);

                MessageEntitySummary result = new MessageEntitySummary()
                {
                    MessageId = Id,
                    Id = index.ToString(),
                    ContentId = e.ContentId,
                    Name = (fileName ?? e.ContentId ?? index.ToString()) + " - " + e.ContentType.MimeType,
                    Headers = e.Headers.Select(h => new Header {
                        Name = h.Field, Value = PunyCodeReplacer.DecodePunycode(h.Value)
                    }).ToList(),
                    ChildParts = new List <MessageEntitySummary>(),
                    Attachments = new List <AttachmentSummary>(),
                    Warnings = new List <MessageWarning>(),
                    Size = e.ToString().Length,
                    IsAttachment = (e.ContentDisposition?.Disposition != "inline" && !string.IsNullOrEmpty(fileName)) || e.ContentDisposition?.Disposition == "attachment",
                    MimeEntity = e
                };

                if (p != null)
                {
                    p.ChildParts.Add(result);

                    if (result.IsAttachment)
                    {
                        if (e.ContentDisposition?.Disposition != "attachment")
                        {
                            result.Warnings.Add(new MessageWarning {
                                Details = $"Attachment '{fileName}' should have \"Content-Disposition: attachment\" header."
                            });
                        }

                        if (string.IsNullOrEmpty(fileName))
                        {
                            result.Warnings.Add(new MessageWarning {
                                Details = $"Attachment with content ID '{e.ContentId}' should have filename specified in either 'Content-Type' or 'Content-Disposition' header."
                            });
                        }

                        p.Attachments.Add(new AttachmentSummary()
                        {
                            Id = result.Id,
                            ContentId = result.ContentId,
                            FileName = fileName,
                            Url = $"api/messages/{Id}/part/{result.Id}/content"
                        });
                    }
                }

                index++;
                return result;
            }));
        }
Exemple #2
0
        public async Task <DbModel.Message> ConvertAsync(Stream messageData, string envelopeFrom, string envelopeTo)
        {
            string subject        = "";
            string mimeParseError = null;

            byte[] data = new byte[messageData.Length];
            await messageData.ReadAsync(data, 0, data.Length);


            bool foundHeaders   = false;
            bool foundSeparator = false;

            using (StreamReader dataReader = new StreamReader(new MemoryStream(data)))
            {
                while (!dataReader.EndOfStream)
                {
                    if (dataReader.ReadLine().Length != 0)
                    {
                        foundHeaders = true;
                    }
                    else
                    {
                        foundSeparator = true;
                        break;
                    }
                }
            }

            if (!foundHeaders || !foundSeparator)
            {
                mimeParseError = "Malformed MIME message. No headers found";
            }
            else
            {
                messageData.Seek(0, SeekOrigin.Begin);
                try
                {
                    CancellationTokenSource cts = new CancellationTokenSource();
                    cts.CancelAfter(TimeSpan.FromSeconds(10));
                    MimeMessage mime = await MimeMessage.LoadAsync(messageData, true, cts.Token).ConfigureAwait(false);

                    subject = mime.Subject;
                }
                catch (OperationCanceledException e)
                {
                    mimeParseError = e.Message;
                }
                catch (FormatException e)
                {
                    mimeParseError = e.Message;
                }
            }


            DbModel.Message message = new DbModel.Message()
            {
                Id = Guid.NewGuid(),

                From            = PunyCodeReplacer.DecodePunycode(envelopeFrom),
                To              = PunyCodeReplacer.DecodePunycode(envelopeTo),
                ReceivedDate    = DateTime.Now,
                Subject         = PunyCodeReplacer.DecodePunycode(subject),
                Data            = data,
                MimeParseError  = mimeParseError,
                AttachmentCount = 0
            };

            var parts = new ApiModel.Message(message).Parts;

            foreach (var part in parts)
            {
                message.AttachmentCount += CountAttachments(part);
            }


            return(message);
        }
Exemple #3
0
        public Message(DbModel.Message dbMessage)
        {
            Data         = dbMessage.Data;
            Id           = dbMessage.Id;
            From         = dbMessage.From;
            To           = dbMessage.To;
            Cc           = "";
            Bcc          = "";
            ReceivedDate = dbMessage.ReceivedDate;
            Subject      = dbMessage.Subject;

            Parts      = new List <ApiModel.MessageEntitySummary>();
            RelayError = dbMessage.RelayError;

            if (dbMessage.MimeParseError != null)
            {
                MimeParseError = dbMessage.MimeParseError;
                Headers        = new List <Header>();
                Parts          = new List <MessageEntitySummary>();
            }
            else
            {
                using (MemoryStream stream = new MemoryStream(dbMessage.Data))
                {
                    MimeMessage = MimeMessage.Load(stream);

                    if (MimeMessage.From != null)
                    {
                        From = MimeMessage.From.ToString();
                    }

                    List <string> recipients = new List <string>(dbMessage.To.Split(",")
                                                                 .Select(r => r.Trim())
                                                                 .Where(r => !string.IsNullOrEmpty(r)));

                    if (MimeMessage.To != null)
                    {
                        To = string.Join(", ", MimeMessage.To.Select(t => PunyCodeReplacer.DecodePunycode(t.ToString())));

                        foreach (MailboxAddress to in MimeMessage.To.Where(t => t is MailboxAddress))
                        {
                            recipients.Remove(PunyCodeReplacer.DecodePunycode(to.Address));
                        }
                    }

                    if (MimeMessage.Cc != null)
                    {
                        Cc = string.Join(", ", MimeMessage.Cc.Select(t => PunyCodeReplacer.DecodePunycode(t.ToString())));

                        foreach (MailboxAddress cc in MimeMessage.Cc.Where(t => t is MailboxAddress))
                        {
                            recipients.Remove(PunyCodeReplacer.DecodePunycode(cc.Address));
                        }
                    }

                    Bcc = string.Join(", ", recipients);

                    Headers = MimeMessage.Headers.Select(h => new Header {
                        Name = h.Field, Value = PunyCodeReplacer.DecodePunycode(h.Value)
                    }).ToList();
                    Parts.Add(HandleMimeEntity(MimeMessage.Body));
                }
            }
        }