Exemple #1
0
        public void TestHeaders()
        {
            string custom1     = "customHeader";
            string custom2     = "X-customeHeader2";
            string headerValue = "custom value";

            MailHeader testHeader = new MailHeader(custom1, headerValue);

            msg.AddCustomHeader(testHeader);
            Assertion.Assert(msg.CustomHeaders.Contains(testHeader));

            msg.AddCustomHeader(custom2, headerValue);
//			Assertion.Assert(msg.CustomHeaders.Contains(testHeader));
        }
Exemple #2
0
        public void TestSend()
        {
            try
            {
                Console.WriteLine("\r\n ----- Smtp Test Below -----");

                msg.Subject = subject;
                msg.Body    = body;
                msg.AddImage(@"..\lib\test attachments\test.jpg", "testimage");
                msg.AddImage(@"..\lib\test attachments\test2.jpg", "testimage2");
                msg.HtmlBody = "<body><table><tr><td><b>Here is an embedded IMAGE:<img src=\"cid:testimage\"></td></tr>\r\n<tr><td>Here's another: <img src=\"cid:testimage2\"></td></tr></table></body>";


                msg.AddRecipient(ccAddress, AddressType.Cc);
                msg.AddRecipient(bccAddress, AddressType.Bcc);

                msg.AddAttachment(@"..\lib\test attachments\test.jpg");
                msg.AddAttachment(new Attachment(new FileStream(@"..\lib\test attachments\test.htm", FileMode.Open, FileAccess.Read), "test.htm"));

                msg.AddCustomHeader("X-FakeTestHeader", "Fake Value");
                msg.AddCustomHeader("X-AnotherFakeTestHeader", "Fake Value");
                msg.Notification = true;
                msg.Charset      = "ISO-8859-1";
                msg.Priority     = MailPriority.Low;


                smtp.Username = "******";
                smtp.Password = "******";


                for (int i = 0; i < 1; i++)
                {
                    smtp.SendMail(msg);
                }
            }
            catch (SmtpException se)
            {
                Assertion.Fail("TestSend() threw a SmtpException: " + se.Message);
            }
            catch (System.Exception e)
            {
                Assertion.Fail("TestSend() threw a System.Exception: " + e.Message + "; Target: " + e.TargetSite);
            }
        }
Exemple #3
0
        protected void Init()
        {
            sender        = "*****@*****.**";
            recipient     = "*****@*****.**";
            cc            = "*****@*****.**";
            senderName    = "FromName";
            recipientName = "ToName";
            ccName        = "ccName";
            subject       = "Mail Message Test\r\n";
            body          = "Hello from MailMessageTest";
            htmlBody      = "<HTML><HEAD></HEAD><BODY bgColor=\"#00ffff\"><b>Hello Jane. This is the body of the HTML mail message.</b></BODY></HTML>";
            charset       = "us-ascii";

            senderEmail    = new EmailAddress(sender, senderName);
            recipientEmail = new EmailAddress(recipient, recipientName);
            ccEmail        = new EmailAddress(cc, ccName);

            msg = new MailMessage(senderEmail, recipientEmail);
            msg.AddRecipient("*****@*****.**", AddressType.To);
            msg.AddRecipient("*****@*****.**", AddressType.To);
            msg.Subject  = subject;
            msg.Body     = body;
            msg.Charset  = charset;
            msg.Priority = MailPriority.High;

            msg.HtmlBody = htmlBody.ToString();
            msg.AddRecipient(ccEmail, AddressType.To);
            msg.AddRecipient(ccEmail, AddressType.Cc);
            msg.AddCustomHeader("X-Something", "Value");
            msg.AddCustomHeader("X-SomethingElse", "Value");
            msg.AddAttachment(@"..\lib\test attachments\test.jpg");
            msg.AddAttachment(@"..\lib\test attachments\test.htm");
            Attachment att = new Attachment(@"..\lib\test attachments\test.zip");

            msg.AddAttachment(att);


            msg.Notification = true;
        }
Exemple #4
0
        public void MailTest()
        {
            using (SmtpClient smtpClient = new SmtpClient("smtp.163.com"))
            {
                smtpClient.Connected              += (x, y) => _logger.Debug("mail", "Connected:{0}", y);
                smtpClient.Authenticated          += (x, y) => _logger.Debug("mail", "Authenticated:{0}", y);
                smtpClient.StartedMessageTransfer += (x, y) => _logger.Debug("mail", "StartedMessageTransfer:{0}", y);
                smtpClient.EndedMessageTransfer   += (x, y) => _logger.Debug("mail", "EndedMessageTransfer:{0}", y);
                smtpClient.Disconnected           += (x, y) => _logger.Debug("mail", "Disconnected:{0}", y);

                smtpClient.Connect();

                smtpClient.UserName = "******";
                smtpClient.Password = "******";

                smtpClient.Authenticate("*****@*****.**", "*****@*****.**");

                MailAddress from = new MailAddress("Lsong", "*****@*****.**");
                MailAddress to   = new MailAddress("*****@*****.**");
                MailAddress cc   = new MailAddress("Test<*****@*****.**>");

                MailMessage mailMessage = new MailMessage(from, to);
                mailMessage.AddRecipient(cc, AddressType.Cc);
                mailMessage.AddRecipient("*****@*****.**", AddressType.Bcc);

                mailMessage.Charset      = "UTF-8";
                mailMessage.Priority     = MailPriority.High;
                mailMessage.Notification = true;

                mailMessage.AddCustomHeader("X-CustomHeader", "Value");
                mailMessage.AddCustomHeader("X-CompanyName", "Value");

                //string testCid = mailMessage.AddImage("C:\\test.bmp");

                //mailMessage.AddAttachment("C:\\test.zip");

                mailMessage.Subject  = "This's a test Mail.";
                mailMessage.Body     = "hello everybody .";
                mailMessage.HtmlBody =
                    string.Format("<html><body>hello everybody .<br /><img src='cid:{0}' /></body></html>", "");

                smtpClient.SendMail(mailMessage);
            }

            using (PopClient popClient = new PopClient("pop.163.com"))
            {
                popClient.UserName = "";
                popClient.Password = "";
                popClient.Connect("pop.163.com", 110, false);
                popClient.Authenticate("*****@*****.**", "*****@*****.**");

                int messageCount = popClient.GetMessageCount();
                for (int i = messageCount; i > 1; i--)
                {
                    //try
                    //{
                    MessageHeader      messageHeader = popClient.GetMessageHeaders(i);
                    MailAddress        sender        = messageHeader.Sender;
                    MailAddress        from          = messageHeader.From;
                    List <MailAddress> to            = messageHeader.To;
                    string             subject       = messageHeader.Subject;

                    _logger.Debug("mail", subject);
                    if (sender != null)
                    {
                        _logger.Info("mail", "Sender:{0}", sender);
                    }
                    if (from != null)
                    {
                        _logger.Info("mail", "From:{0}", from);
                    }
                    if (to != null)
                    {
                        foreach (MailAddress mailAddress in to)
                        {
                            _logger.Info("mail", "TO:{0}", mailAddress);
                        }
                    }
                    Message     message  = popClient.GetMessage(i);
                    MessagePart textBody = message.FindFirstPlainTextVersion();
                    MessagePart htmlBody = message.FindFirstHtmlVersion();


                    if (textBody != null)
                    {
                        string text = textBody.GetBodyAsText();
                        System.Console.WriteLine(text);
                    }
                    else if (htmlBody != null)
                    {
                        string html = htmlBody.GetBodyAsText();
                        System.Console.WriteLine(html);
                    }
                    System.Console.ReadKey();
                    //}
                    //catch (Exception exception)
                    //{
                    //    _logger.Error("mail", exception);
                    //}
                }
            }
        }
        private void DumpMapiProperties(IMessage inMsg, MailMessage outMsg)
        {
            String header, body;
            //Get the original transport headers, and parse them out
            String xportHdrs = MapiUtils.GetStringProperty(inMsg, Tags.PR_TRANSPORT_MESSAGE_HEADERS);
            if (xportHdrs == null) {
                return;
            }

            //Each header line consists of the header, whitespace, colon, whitespace, value
            Regex hdrLineRex = new Regex(@"
            (?# Match single- and multi-line SMTP headers )
            (?<header>        (?# The header element... )
              [a-z0-9\-]+     (?# consists of letters, numbers, or hyphens.)
            )                 (?# the header is followed by...)
            \s*:\s*           (?# ...optional whitespace, a colon, additional optional whitespace...)
            (?<value>         (?# ...and the value of the header, which is ...)
              .*?             (?# ...any character, possibly spanning multiple lines...)
            )
            (?=\r\n\S|\n\S|\z)(?# ...delimited by the start of another line w/ non-whitespace, or the end of the string)
            ",
                RegexOptions.IgnoreCase | //Obviously, case-insensitive
                RegexOptions.Multiline | //Need to match potentially multi-line SMTP headers
                RegexOptions.Singleline | //and . matches newlines as well
                RegexOptions.IgnorePatternWhitespace //Ignore the pattern whitespace included for readability
                );

            foreach (Match match in hdrLineRex.Matches(xportHdrs)) {
                if (match.Success) {
                    header = match.Groups["header"].Value;
                    body = match.Groups["value"].Value;

                    //If this header isn't one of the built-in ones that will be generated automatically
                    //by OpenSmtp.net
                    if (header.ToLower() != "to" &&
                        header.ToLower() != "from" &&
                        header.ToLower() != "reply-to" &&
                        header.ToLower() != "date" &&
                        header.ToLower() != "subject" &&
                        header.ToLower() != "cc" &&
                        header.ToLower() != "bcc" &&
                        header.ToLower() != "mime-version" &&
                        header.ToLower() != "content-type" &&
                        header.ToLower() != "content-transfer-encoding") {
                        //OpenSmtp isn't smart enough to recognize multi-line header values, and wants to
                        //quoted-printable them because of the CR/LF control chars.  So, straighten multi-line values out
                        body = Regex.Replace(body, @"\r\n\s+|\n\s+", " ");
                        outMsg.AddCustomHeader(header, body);
                    }
                }
            }

            //Now dump all of the MAPI properties as X- headers just in case they're needed
            Tags[] propIds;
            inMsg.GetPropList(0, out propIds);
            foreach (Tags propId in propIds) {
                //Skip properties that are too big or redundant
                if (propId == Tags.ptagBody ||
                    propId == Tags.ptagBodyHtml ||
                    propId == Tags.ptagHtml ||
                    propId == Tags.PR_BODY ||
                    propId == Tags.PR_BODY_HTML ||
                    propId == Tags.PR_RTF_COMPRESSED ||
                    propId == Tags.PR_TRANSPORT_MESSAGE_HEADERS) {
                    continue;
                }
                header = String.Format("X-{0}", propId);

                try {
                    Value val = MapiUtils.GetProperty(inMsg, propId);

                    if (val is MapiBinary) {
                        //Binary values aren't good for much
                        continue;
                    }

                    if (val == null) {
                        body = "<null>";
                    } else {
                        body = val.ToString();
                        //Cannot have line breaks in SMTP headers, so if there are any, escape them
                        body = body.Replace("\n", @"\n");
                        body = body.Replace("\r", @"\r");
                        body = body.Replace("\t", @"\t");
                    }

                    outMsg.AddCustomHeader(header, body);
                } catch (MapiException e) {
                    outMsg.AddCustomHeader("X-Exception", String.Format("Error getting property: {0}", e.Message));
                }
            }
        }
        public void AddMessage(IMessage msg)
        {
            //Check the msg class.  If this is a non-delivery report, I don't know how to handle that
            String msgClass = MapiUtils.GetStringProperty(msg, Tags.PR_MESSAGE_CLASS);
            if (msgClass == "REPORT.IPM.Note.NDR") {
                return;
            }

            //A maildir is a folder full of files named thusly:
            // [timestamp].[uniqueid].[hostname]
            //
            // timestamp is simply the total seconds of the message time stamp
            // uniqueid is some system-generated ID that is unique within the namespace
            // of the hostname and timestamp.
            // hostname is the name of the host delivering the mail.
            //
            // since we're bulk-loading messages and can assume no other source is
            // submitting them, cop out on the uniqueid and just use a randomly-seeded, increasing counter
            //
            // In addition, for msgs in 'cur' (which all of these are), the file name can be followed by the following:
            // (source: http://cr.yp.to/proto/maildir.html)

            //When you move a file from new to cur, you have to change its name from uniq to uniq:info. Make sure to preserve the uniq string, so that separate messages can't bump into each other.
            //
            //info is morally equivalent to the Status field used by mbox readers. It'd be useful to have MUAs agree on the meaning of info, so I'm keeping a list of info semantics. Here it is.
            //
            //info starting with "1,": Experimental semantics.
            //
            //info starting with "2,": Each character after the comma is an independent flag.
            //
            //    * Flag "P" (passed): the user has resent/forwarded/bounced this message to someone else.
            //    * Flag "R" (replied): the user has replied to this message.
            //    * Flag "S" (seen): the user has viewed this message, though perhaps he didn't read all the way through it.
            //    * Flag "T" (trashed): the user has moved this message to the trash; the trash will be emptied by a later user action.
            //    * Flag "D" (draft): the user considers this message a draft; toggled at user discretion.
            //    * Flag "F" (flagged): user-defined flag; toggled at user discretion.
            //
            //New flags may be defined later. Flags must be stored in ASCII order: e.g., "2,FRS".
            //
            // From empirical study of Courier-IMAP Maildirs, there's also a 'S=whatever' before the flags.  So:
            // whatever:2,S=12345,RS.
            //
            // Apparently this makes it faster for Courier to get messages sizes for quota enforcement purposes.  However
            //tbird at least don't seem to know what to do w/ this, so I won't include size info.
            //
            //The contents of each file are in standard RFC 2822 format.

            //TODO: Use PR_MSG_STATUS for R, D, T, F
            DateTime recvTime = MapiUtils.GetSysTimeProperty(msg, Tags.ptagMsgDeliveryTime);
            int size = MapiUtils.GetLongProperty(msg, Tags.PR_MESSAGE_SIZE);
            int flags = MapiUtils.GetLongProperty(msg, Tags.PR_MESSAGE_FLAGS);
            bool read = ((flags & (int)MAPI33.WellKnownValues.PR_MESSAGE_FLAGS.Read) != 0);
            bool draft = ((flags & (int)MAPI33.WellKnownValues.PR_MESSAGE_FLAGS.Unsent) != 0);

            //Update the unique id
            _lastUniqueId += 1 + new Random().Next(100);

            String name = recvTime.Ticks.ToString();
            name += ".";
            name += _lastUniqueId.ToString();
            name += ".";
            name += System.Net.Dns.GetHostName();
            //LAME: Colons in filenames aren't supported coz the path canonicalizer is too lazy to know the difference
            //between an alt data stream and just a plain colon.  Bogus.
            name += ";2,";
            //name += "S=" + size.ToString() + ","; tbird doesn't know what to do w/ this
            if (read) {
                name += "S";
            }
            if (draft) {
                name += "D";
            }

            //Create a message object
            MailMessage outMsg = new MailMessage();
            outMsg.Date = recvTime;

            //Depending upon the message class, use different logic to populate the message
            if (msgClass == "IPM.Note") {
                ProcessMailMessage(msg, outMsg);
            } else if (msgClass == "IPM.Contact") {
                ProcessContact(msg, outMsg);
                return; //TODO: don't skip
            } else if (msgClass == "IPM.Calendar") {
                ProcessAppointment(msg, outMsg);
                return; //TODO: don't skip
            } else if (msgClass == "IPM.Task") {
                ProcessTask(msg, outMsg);
                return; //TODO: don't skip
            } else if (msgClass == "IPM.StickyNote") {
                ProcessNote(msg, outMsg);
                return; //TODO: don't skip
            } else {
                ProcessUnknownMsgClass(msg, outMsg);
                return; //TODO: don't skip
            }

            outMsg.AddCustomHeader("X-ConvertedFromMapi",
                String.Format("Adam Nelson's Mapi to Maildir Converter.  {0}", DateTime.Now.ToString()));

            //Create the file in a temp location
            String tmpMsgFileName = System.IO.Path.Combine(System.IO.Path.GetTempPath(), System.IO.Path.GetTempFileName());
            outMsg.Save(tmpMsgFileName);

            //Read the msg from the temp file, and write it to the destination file,
            //replacing the Windows line endings (CR LF) with UNIX (LF)
            String msgFileName = System.IO.Path.Combine(_curPath, name);

            const String LF = "\xa";
            using (StreamReader sr = new StreamReader(tmpMsgFileName)) {
                using (StreamWriter sw = new StreamWriter(msgFileName)) {
                    String line = null;
                    while ( (line = sr.ReadLine()) != null) {
                        sw.Write(line);
                        sw.Write(LF);
                    }
                }
            }

            File.Delete(tmpMsgFileName);

            //if there was a non-bogus receive time, set the date/time stamp
            //on the file to that time.
            if (recvTime != DateTime.MinValue) {
                //Set the date/time on the file to be the receive time
                //There seems to be an undocumented bug in the behavior of File.Set*Time.
                //Specifically, if it is used to set a time on a date with a different GMT
                //offset than the current date (eg, set the file to '3/1/04 12:00PM' (which is during
                //standard time in the Eastern time zone, and thus GMT-5) on '7/1/04' (which is
                //during daylight savings time in the Eastern time zone, and thus GMT-4), then
                //the resulting value displayed by Windows Explorer is one hour ahead.  To continue
                //the example above, explorer would display the time for the file as
                //'1:00 PM' instead of '12:00 PM'.  It's as though the timezone translation
                //is being performed when it should not.
                //
                //There is newsgroup chatter suggesting this has been seen before, but not confirmed
                //by MS.  The Get*Time methods must reverse whatever transformation is applied
                //by the Set*Time methods, as they return the same time passed in.
                //
                //At any rate, the workaround is to apply a compensating reverse adjustment
                //That is, subtract from recvTime the difference in GMT offset on recvTime's date,
                //and on the current date

                //For EST, this will be -300 minutes (-5 hours)
                //For EDT, -240 minutes (-4 hours)
                double thenGmtOffset = (recvTime - recvTime.ToUniversalTime()).TotalMinutes;
                double nowGmtOffset = (DateTime.Now - DateTime.Now.ToUniversalTime()).TotalMinutes;

                //To continue the example above, this will be an offset of -60 minutes
                double compensatingOffset = thenGmtOffset - nowGmtOffset;

                //Can't possibly be 24 hours or more.
                System.Diagnostics.Debug.Assert(compensatingOffset < 24*60);

                DateTime fsTime = recvTime.AddMinutes(compensatingOffset);

                File.SetCreationTime(msgFileName, fsTime);
                File.SetLastWriteTime(msgFileName, fsTime);
            }
        }