Пример #1
0
        internal static void HtmlAppendImages(string ssCharset, int linelength, bool use_multipart_related, StringBuilder sbMail, Encoding mailEncoding, string relatedBoundary, string alternateBoundary, string normBody, string images)
        {
            if (use_multipart_related)
            {
                sbMail.Append("Content-Type: multipart/related; boundary=\"" + relatedBoundary + "\"\r\n");
                sbMail.Append("\r\n");

                sbMail.Append("--" + relatedBoundary + "\r\n");
            }
            else
            {
                // #14440: Do nothing as starting boundary was already dumped above
            }
            sbMail.Append("Content-Type: multipart/alternative; boundary=\"" + alternateBoundary + "\"\r\n");
            sbMail.Append("\r\n");

            sbMail.Append("--" + alternateBoundary + "\r\n");
            sbMail.Append("Content-Type: text/plain; charset=\"" + ssCharset + "\"\r\n");
            sbMail.Append("Content-Transfer-Encoding: base64\r\n");
            sbMail.Append("\r\n");

            string plainText = EmailHelper.HtmlToText(normBody);

            sbMail.Append(EmailEncoding.GetBase64TextBlock(mailEncoding.GetBytes(plainText), linelength));

            sbMail.Append("--" + alternateBoundary + "\r\n");
            sbMail.Append("Content-Type: text/html; charset=\"" + ssCharset + "\"\r\n");
            sbMail.Append("Content-Transfer-Encoding: base64\r\n");
            sbMail.Append("\r\n");

            sbMail.Append(EmailEncoding.GetBase64TextBlock(mailEncoding.GetBytes(normBody), linelength));

            sbMail.Append("--" + alternateBoundary + "--\r\n");
            sbMail.Append(images);
            if (use_multipart_related)
            {
                sbMail.Append("--" + relatedBoundary + "--\r\n");
            }
            else
            {
                sbMail.Append("\r\n");
            }
        }
Пример #2
0
        // Left public because testing console needs this
        public static string ProcessEmailAddresses(Encoding encoding, string addresses)
        {
            StringBuilder new_addresses = new StringBuilder();

            string[] address_array = addresses.Split(',', ';');

            EncodeFlags flags = EncodeFlags.SingleLine | EncodeFlags.QuotedPrintable;

            foreach (string address_item in address_array)
            {
                string new_address_item = EmailHelper.TrimHeaderLine(EmailHelper.RemoveControlCodes(address_item));
                new_address_item = EmailFunctions.EncloseEmail(new_address_item);

                if (new_address_item.Length > 0)
                {
                    if (new_address_item.IndexOf("<") > 0)
                    {
                        string desc    = new_address_item.Substring(0, new_address_item.IndexOf("<") - 1);
                        string address = new_address_item.Substring(new_address_item.IndexOf("<") - 1, new_address_item.Length - new_address_item.IndexOf("<") + 1);
                        if (address != null)
                        {
                            address = EmailHelper.TrimHeaderLine(address);
                        }
                        if (EmailEncoding.NeedsEncoding(encoding, desc, flags))
                        {
                            new_addresses.Append(", " + EmailEncoding.EncodeString(encoding, desc, flags) + address);
                        }
                        else
                        {
                            new_addresses.Append(", " + new_address_item);
                        }
                    }
                    else
                    {
                        new_addresses.Append(", " + new_address_item);
                    }
                }
            }
            return(new_addresses.ToString().TrimStart(',').TrimStart());
        }
        public static string Compose(Encoding mailEncoding, string name, string email)
        {
            string qp_name = string.Empty;

            if (!name.IsEmpty())
            {
                if (NonQPNameRegex.Match(name).Value == name)
                {
                    if (!name.Contains(" "))
                    {
                        qp_name = name;
                    }
                    else
                    {
                        qp_name = "\"" + name + "\"";
                    }
                }
                else
                {
                    qp_name = "\"" + EmailEncoding.EncodeString(mailEncoding, name, EncodeFlags.SingleLine | EncodeFlags.QuotedPrintable) + "\"";
                }
            }

            email = email.Trim();

            if (!email.StartsWith("<") || !email.EndsWith(">"))
            {
                Match enclosedEmail = EnclosedEmailRegex.Match(email);
                if (enclosedEmail != Match.Empty)
                {
                    email = enclosedEmail.Value;
                }
                else
                {
                    email = "<" + email + ">";
                }
            }

            return((qp_name.IsEmpty() ? "" : (qp_name + " ")) + email);
        }
Пример #4
0
        public static void AddPart(HeaderFlags flags, string ssContentType, string ssContentID, string ssBoundary, string ssFilename, string ssLocation, byte[] ssContent, string ssContentTransferEncod, out string ssoPart)
        {
            System.Text.StringBuilder ssPart = new System.Text.StringBuilder();
            // Define the line size

            int linelength = EmailEncoding.MaxLineLength;

            // Add starting boundary
            ssPart.Append("--" + ssBoundary + "\r\n");

            if ((flags & HeaderFlags.ContentType) == HeaderFlags.ContentType)
            {
                // Add the attachment Content type and encoding
                ssPart.Append("Content-Type: " + (ssContentType.IsEmpty() ? "application/octet-stream" : ssContentType) + "");

                // If a filename was given add description and disposition
                if (ssFilename != "")
                {
                    ssPart.Append("; name=\"" + ssFilename + "\"\r\n");
                    if ((flags & HeaderFlags.ContentDescription) == HeaderFlags.ContentDescription)
                    {
                        ssPart.Append("Content-Description: " + ssFilename + "\r\n");
                    }
                    if ((flags & HeaderFlags.ContentDisposition) == HeaderFlags.ContentDisposition)
                    {
                        ssPart.Append("Content-Disposition: attachment; filename=\"" + ssFilename + "\"\r\n");
                    }
                    else if ((flags & HeaderFlags.ContentDispositionInline) == HeaderFlags.ContentDispositionInline)
                    {
                        ssPart.Append("Content-Disposition: inline; filename=\"" + ssFilename + "\"\r\n");
                    }
                }
                else
                {
                    ssPart.Append("; charset=\"iso-8859-1\"\r\n");
                    ssPart.Append("Content-Disposition: inline\r\n");
                }
            }

            if ((flags & HeaderFlags.ContentID) == HeaderFlags.ContentID)
            {
                if (ssContentID != "")
                {
                    ssPart.Append("Content-ID: <" + ssContentID + ">\r\n");
                }
            }

            ssContentTransferEncod = ssContentTransferEncod.ToLower();
            ssPart.Append("Content-Transfer-Encoding: " + ssContentTransferEncod + "\r\n");

            // If a location was given add it to the attachment header
            if ((flags & HeaderFlags.Location) == HeaderFlags.Location)
            {
                if (ssLocation != "")
                {
                    ssPart.Append("Content-Location: " + ssLocation + "\r\n");
                }
            }

            switch (ssContentTransferEncod)
            {
            case "base64":
                // Encode the binary part to base64 and add it to the attachment
                int    base64Length;
                string base64 = EmailEncoding.GetBase64TextBlock(ssContent, linelength, out base64Length);
                ssPart.Append("Content-Length: " + base64Length + "\r\n");
                ssPart.Append("\r\n");
                ssPart.Append(base64);
                break;

            case "binary":
                ssPart.Append("Content-Length: " + ssContent.Length + "\r\n");
                ssPart.Append("\r\n");
                foreach (byte bte in ssContent)
                {
                    ssPart.Append(Convert.ToChar(bte));
                }
                ssPart.Append("\r\n");
                break;

            default:
                if ((ssContentTransferEncod == null) || (ssContentTransferEncod == ""))
                {
                    throw new InvalidOperationException("Empty Content Transfer Encoding not supported");
                }
                throw new InvalidOperationException("Content Transfer Encoding " + ssContentTransferEncod + " not supported");
            }

            ssoPart = ssPart.ToString();
        }
Пример #5
0
        /// <summary>
        /// Initializes the production of an email message, creating its headers and main body. Note that this
        /// action does not immediately send the message, as you may want to add futher parts (attachments) to
        /// it (using <see cref="AddPart" />). To finalize message and send it you should then call RichMailSend
        /// </summary>
        /// <remarks>
        /// Older emails clients (such as some versions of Lotus and Outlook 2000) do not correctly support the MIME encoding used to send HTML emails. To enable HTML emails to be delivered correctly to these clients you can add &quot;lotus/compatible&quot; (without the quotes) to the ContentType. This will change how the whole email is created and allows those clients to shows the message properly at the expense of more recent email clients (such as Yahoo! Mail) that will not display the message correctly.
        /// </remarks>
        /// <param name="processAddresses">Pre-process the email addresses?</param>
        /// <param name="ssFrom">Email address of the sender</param>
        /// <param name="ssTo">Email addresses to send the email to (comma separated)</param>
        /// <param name="headers">Email header information</param>
        /// <param name="ssCc">Email addresses to carbon-copy the email to (comma separated)</param>
        /// <param name="ssBcc">Email addresses to blind carbon-copy the email to (comma separated)</param>
        /// <param name="ssContentType">MIME type of the message.</param>
        /// <param name="ssCharset">Character used in the message text</param>
        /// <param name="ssSubject">Subject of the message</param>
        /// <param name="ssBody">Text content of the message</param>
        /// <param name="ssBodyIsHtml">TRUE if content of the message is HTML rather than plain text</param>
        /// <param name="ssUrl">Base URL to use in case the Body is HTML. This allows any relative paths that may exist in the Body to be expanded to full blown URL's</param>
        /// <param name="ssIncludeImages">If TRUE, any images referenced via an URL in the Body are attached to the message</param>
        /// <param name="ssInReplyTo">Alternate reply-to email address</param>
        /// <param name="userAgent">User agent to use to request the email messages.</param>
        /// <param name="realHostname">The hostname to use when building links in the email body.</param>
        /// <param name="zoneAddress">Deploymentzoneadress of the running espace</param>
        /// <param name="ssBoundary">System marker that should be passed in to any further parts that are added to this message (see <see cref="AddPart" />).</param>
        /// <param name="ssMail">The full message text produced by the call</param>
        /// <param name="emailId">The created email id.</param>
        public static void CreateEmail(bool processAddresses, string ssFrom, string ssTo, List <String> headers, string ssCc, string ssBcc, string ssContentType, string ssCharset, string ssSubject, string ssBody, bool ssBodyIsHtml, string ssUrl, bool ssIncludeImages, string ssInReplyTo, string userAgent, string realHostname, string zoneAddress, out string ssBoundary, out string ssMail, out string emailId)
        {
            bool prepareMimeEncoding = true;
            //string base64 = null;
            bool use_multipart_related = true;

            ssBoundary = "";
            System.Text.StringBuilder sbMail = new System.Text.StringBuilder();

            if (realHostname == null)
            {
                throw new InvalidOperationException("The 'Default DNS Name' must be set in Service Center's Environment Configuration to send emails.");
            }

            // Cleanup the content type
            ssContentType = EmailHelper.TrimHeaderLine(ssContentType);

            // This is a hack to support Outlook 2000 and other clients
            // that do not support multipart/related.
            int tpos = ssContentType.ToUpper().IndexOf("LOTUS/COMPATIBLE");

            if (tpos >= 0)
            {
                ssContentType         = ssContentType.Remove(tpos, 16);
                use_multipart_related = false;
            }

            // If no Content Type defined, set it to "multipart/mixed"
            if (ssContentType == "")
            {
                ssContentType = "multipart/mixed";
            }

            if (!ssContentType.ToLower().StartsWith("multipart"))
            {
                // If it's not a multipart message then don't encase in MIME containers
                prepareMimeEncoding = false;
            }

            if (ssBodyIsHtml)
            {
                prepareMimeEncoding = true;
            }

            // If no Content Type defined, set it to "multipart/mixed"
            if (ssCharset == "")
            {
                ssCharset = "iso-8859-1";
            }
            else
            {
                ssCharset = EmailHelper.TrimHeaderLine(ssCharset);
            }

            // Get a correct encoder
            System.Text.Encoding mailEncoding = System.Text.Encoding.GetEncoding(ssCharset);

            if (prepareMimeEncoding)
            {
                // Get a random boundary
                ssBoundary = EmailHelper.CreateRandomBoundary();
            }
            else
            {
                ssBoundary = "";
            }

            // Add date to email header
            sbMail.Append("Date: ");
            sbMail.Append(EmailHelper.GetEmailDate(System.DateTime.Now));
            sbMail.Append("\r\n");

            if (processAddresses)
            {
                ssFrom = EmailHelper.ProcessEmailAddresses(mailEncoding, ssFrom);
            }

            emailId = System.Guid.NewGuid().ToString().Replace("-", "") + "@" + RuntimePlatformSettings.EMail.ServerHost.GetValue();
            // Add the EmailID
            sbMail.Append("Message-ID: <" + emailId + ">\r\n");


            // Add from to email header
            sbMail.Append("From: ");
            sbMail.Append(ssFrom);
            sbMail.Append("\r\n");

            if (processAddresses)
            {
                // If any of the email addresses in the To field are in the format
                // "description <email address>", then encode with iso-8859-1 the description.
                ssTo = EmailHelper.ProcessEmailAddresses(mailEncoding, ssTo);
            }

            // Add to to email header
            sbMail.Append("To: ");
            sbMail.Append(ssTo);
            sbMail.Append("\r\n");

            // Add headers

            if (headers != null)
            {
                foreach (String header in headers)
                {
                    sbMail.Append(header);
                    sbMail.Append("\r\n");
                }
            }

            // If cc not empty, add it to email header
            if (ssCc != "")
            {
                if (processAddresses)
                {
                    // If any of the email addresses in the Cc field are in the format
                    // "description <email address>", then encode with iso-8859-1 the description.
                    ssCc = EmailHelper.ProcessEmailAddresses(mailEncoding, ssCc);
                }

                // Add it to the email header
                sbMail.Append("Cc: ");
                sbMail.Append(ssCc);
                sbMail.Append("\r\n");
            }

            ssInReplyTo = EmailHelper.TrimHeaderLine(ssInReplyTo);

            // Add In-Reply-To to email header
            if (ssInReplyTo != "")
            {
                sbMail.Append("In-Reply-To:");
                sbMail.Append(ssInReplyTo);
                sbMail.Append("\r\n");
            }

            ssSubject = EmailHelper.TrimHeaderLine(ssSubject);

            EncodeFlags headerEncodeFlags = EncodeFlags.SingleLine | EncodeFlags.QuotedPrintable;

            // Encode the subject
            if (EmailEncoding.NeedsEncoding(mailEncoding, ssSubject, headerEncodeFlags))
            {
                ssSubject = EmailEncoding.EncodeString(mailEncoding, ssSubject, headerEncodeFlags);
            }

            // Add subject to email header
            sbMail.Append("Subject: ");
            sbMail.Append(ssSubject);
            sbMail.Append("\r\n");

            // Add content type to email header
            if (prepareMimeEncoding)
            {
                sbMail.Append("MIME-Version: 1.0\r\n");
            }
            if (prepareMimeEncoding)
            {
                sbMail.Append("Content-Type: " + ssContentType + "; boundary=\"" + ssBoundary + "\"\r\n");
            }
            else
            {
                sbMail.Append("Content-Type: " + ssContentType + "; charset=\"" + ssCharset + "\"\r\n");
                sbMail.Append("Content-Transfer-Encoding: base64\r\n");
            }

            //sbMail += "Content-Transfer-Encoding: base64\r\n";
            if (prepareMimeEncoding)
            {
                sbMail.Append("\r\n");

                // For older clients to display something
                sbMail.Append("This is a multi-part message in MIME format.\r\n");

                // Dump the starting boundary
                sbMail.Append("--" + ssBoundary + "\r\n");
            }

            // Add body header to email
            //System.Text.Encoding bodyEncoding = System.Text.Encoding.GetEncoding(ssCharset);
            if (ssBodyIsHtml)
            {
                // Outlook 2000 is too old by now and treats emails using MULTIPART/RELATED as
                // MULTIPART/MIXED (which is standards compliant).
                // Thus if a tree like the following is used it will show an empty email
                // with two attachments. The first attachment is an email and a second one is the attachment file.
                //   Begin Message
                //     Begin Mixed Content
                //       Begin Related Contnt
                //         Begin Alternative Content
                //           Plain text message
                //           HTML Message message
                //         End Alternative Content
                //         Image
                //       End Related Content
                //       Attachment
                //     End Mixed Content
                //   End Message
                //
                // To avoid this we now have a flag that disables the use of MULTIPART/RELATED
                // and uses a tree like this :
                //   Begin Message
                //     Begin Mixed Content
                //       Begin Alternative Content
                //         Plain text message
                //         HTML Message message
                //       End Alternative Content
                //       Image
                //       Attachment
                //     End Mixed Content
                //   End Message

                string relatedBoundary = null;
                if (use_multipart_related)
                {
                    relatedBoundary = EmailHelper.CreateRandomBoundary();
                }

                string           alternateBoundary = EmailHelper.CreateRandomBoundary();
                string           normBody;
                Hashtable        uri2cidMap;
                StringCollection uris;

                // remove meta content type
                normBody = ScriptableEmailFunctions.GetRegex("<meta +http-equiv='?\"?content-type[^>]+>", RegexOptions.IgnoreCase).Replace(ssBody, "");

                // Place stylesheet inline
                var match = ScriptableEmailFunctions.GetRegex("<link [^>]*href=\"([^\"]+\\.css)(\\?[0-9_]+)?\"[^>]*>", RegexOptions.IgnoreCase).Match(normBody);
                if (match.Success)
                {
                    string css;
                    Uri    absUri = null;
                    try {
                        absUri = new Uri(new Uri(ssUrl), match.Groups[1].Value);
                    } catch { }
                    if (absUri != null)
                    {
                        string cssEncoding;
                        EmailHelper.HttpGet(absUri.AbsoluteUri, MailUA, null, out css, out cssEncoding);
                        css      = EmailHelper.NormalizeCSS(css);
                        normBody = normBody.Substring(0, match.Index) + "<style>" + css + "</style>" + normBody.Substring(match.Index + match.Length, normBody.Length - match.Index - match.Length);
                    }
                }

                string returnBody;
                EmailHelper.HtmlProcessPaths(normBody, ssUrl, ssIncludeImages, use_multipart_related, out returnBody, out uris, out uri2cidMap);
                normBody = returnBody;

                // Replace localhost with the real name for any unescaped link that occurred (normal destinations are already ok)
                if (realHostname != null)   //just for sanity check
                {
                    normBody = ReplaceLinksWithEnvAddress(realHostname, zoneAddress, normBody);
                }

                string images = EmailHelper.HtmlFetchImages(ssIncludeImages, ssBoundary, use_multipart_related, relatedBoundary, uri2cidMap, userAgent);
                EmailHelper.HtmlAppendImages(ssCharset, EmailEncoding.MaxEncodedLength, use_multipart_related, sbMail, mailEncoding, relatedBoundary, alternateBoundary, normBody, images);
            }
            else if (ssBody != "")
            {
                if (prepareMimeEncoding)
                {
                    sbMail.Append("Content-Type: text/plain; charset=\"" + ssCharset + "\"\r\n");
                    sbMail.Append("Content-Transfer-Encoding: base64\r\n");
                }
                sbMail.Append("\r\n");

                // Encode body and add it to the email
                sbMail.Append(EmailEncoding.GetBase64TextBlock(mailEncoding.GetBytes(ssBody), EmailEncoding.MaxEncodedLength));
            }
            else
            {
                sbMail.Append("\r\n");
            }

            ssMail = sbMail.ToString();
        } // CreateEmail
Пример #6
0
        public static int CreateEmail(string bodyUrl, string emailSubject, string emailBody,
                                      string from, string to, string cc, string bcc,
                                      int activityId, int tenantId, int eSpaceId, string emailDefSSKey, bool storeContent,
                                      List <String> headers, List <EmailAttachment> attachments, string realHostname, string zoneAddress)
        {
            NormalizeFields(ref from, ref to, ref cc, ref bcc);

            string subject = emailSubject;
            string charset = "UTF-8";

            Regex titleRe    = ScriptableEmailFunctions.GetRegex("<title>([^<]*)</title>", RegexOptions.IgnoreCase);
            Match titleMatch = titleRe.Match(emailBody);

            if (titleMatch.Success)
            {
                subject = HttpUtility.HtmlDecode(titleMatch.Groups[1].Value.Trim());
            }

            emailBody = CleanEmailBody(emailBody);

            // #122347 TODO: process obtained emailBody to separate attachments from body

            string emailBoundary;
            string pathUrl = bodyUrl.Substring(0, bodyUrl.LastIndexOf('/') + 1);
            string messageId;
            string content;

            CreateEmail(false, // the email addresses need to be correctly formated already (using the provided functions), processing them would re-encode them
                               //multipart/related
                        from, to, headers, cc, bcc, "", charset, subject, emailBody, true, pathUrl, true, "", MailUA, realHostname,
                        zoneAddress, out emailBoundary, out content, out messageId);

            StringBuilder emailContent = new StringBuilder();

            emailContent.Append(content);

            if (attachments != null)
            {
                foreach (EmailAttachment att in attachments)
                {
                    string newPart;
                    string encodedFilename = att.FileName;
                    if (EmailEncoding.NeedsEncoding(Encoding.UTF8, att.FileName, EncodeFlags.QuotedPrintable))
                    {
                        encodedFilename = EmailEncoding.EncodeString(Encoding.UTF8, att.FileName, EncodeFlags.QuotedPrintable);
                    }
                    AddPart(HeaderFlags.ContentType | HeaderFlags.ContentDisposition, att.MimeType, null, emailBoundary, encodedFilename, null, att.FileContent, "base64", out newPart);
                    emailContent.Append(newPart);
                }
            }

            // Close email
            emailContent.Append("--" + emailBoundary + "--\r\n");
            emailContent.Append("\r\n");

            string       finalContent = emailContent.ToString();
            int          contentLen   = finalContent.Length;
            UTF8Encoding encoder      = new UTF8Encoding();

            byte[] byteContent = encoder.GetBytes(finalContent);

            using (Transaction trans = DatabaseAccess.ForRuntimeDatabase.GetRequestTransaction()) {
                return(DBRuntimePlatform.Instance.SaveEmail(trans,
                                                            EmailHelper.GetCleanEmailAddress(from),
                                                            EmailHelper.GetCleanEmailAddresses(to),
                                                            EmailHelper.GetCleanEmailAddresses(cc),
                                                            EmailHelper.GetCleanEmailAddresses(bcc),
                                                            subject, byteContent, contentLen, activityId, tenantId, eSpaceId, emailDefSSKey, storeContent, messageId,
                                                            AppInfo.GetAppInfo().Properties.EnableEmails,
                                                            AppInfo.GetAppInfo().Properties.TestEmails));
            }
        }