Exemplo n.º 1
0
 /// <summary>
 /// Visit the children of a <see cref="MailKit.BodyPartMultipart"/>.
 /// </summary>
 /// <remarks>
 /// Visits the children of a <see cref="MailKit.BodyPartMultipart"/>.
 /// </remarks>
 /// <param name="multipart">The multipart.</param>
 protected virtual void VisitChildren(BodyPartMultipart multipart)
 {
     for (int i = 0; i < multipart.BodyParts.Count; i++)
     {
         multipart.BodyParts[i].Accept(this);
     }
 }
Exemplo n.º 2
0
        async void RenderMultipartRelated(IMailFolder folder, UniqueId uid, BodyPartMultipart bodyPart)
        {
            // download the entire multipart/related for simplicity since we'll probably end up needing all of the image attachments anyway...
            var related = await folder.GetBodyPartAsync(uid, bodyPart) as MultipartRelated;

            RenderMultipartRelated(related);
        }
        public void TestMultipartWithNoChildren()
        {
            var original = new BodyPartMultipart {
                ContentType = new ContentType("multipart", "mixed")
                {
                    Boundary = "----=_NextPart_000_001"
                }
            };

            original.BodyParts.Add(new BodyPartMultipart {
                ContentType = new ContentType("multipart", "alternative")
                {
                    Boundary = "----=_AlternativePart_001_001"
                }
            });

            var serialized = original.ToString();

            Assert.IsTrue(BodyPart.TryParse(serialized, out var body), "Failed to parse.");
            Assert.IsInstanceOf <BodyPartMultipart> (body, "Body types did not match.");

            var multipart = (BodyPartMultipart)body;

            Assert.IsTrue(multipart.ContentType.IsMimeType("multipart", "mixed"), "Content-Type did not match.");
            Assert.AreEqual(original.ContentType.Boundary, multipart.ContentType.Boundary, "boundary param did not match");
            Assert.AreEqual(1, multipart.BodyParts.Count, "BodyParts count does not match.");
            Assert.IsInstanceOf <BodyPartMultipart> (multipart.BodyParts[0], "The type of the first child does not match.");

            var alternative = (BodyPartMultipart)multipart.BodyParts[0];

            Assert.IsTrue(alternative.ContentType.IsMimeType("multipart", "alternative"), "Inner Content-Type did not match.");
            Assert.AreEqual(original.BodyParts[0].ContentType.Boundary, alternative.ContentType.Boundary, "Inner boundary param did not match");
            Assert.AreEqual(0, alternative.BodyParts.Count, "Inner BodyParts count does not match.");
        }
Exemplo n.º 4
0
        static BodyPartMultipart CreateMultipart(string type, string subtype, string partSpecifier, params BodyPart[] bodyParts)
        {
            var multipart = new BodyPartMultipart {
                ContentType = CreateContentType(type, subtype, partSpecifier)
            };

            foreach (var bodyPart in bodyParts)
            {
                multipart.BodyParts.Add(bodyPart);
            }
            return(multipart);
        }
Exemplo n.º 5
0
        public void fill(BodyPartMultipart part)
        {
            attachmentList.AddRange(
                part
                .BodyParts
                .OfType <BodyPartBasic>()
                );

            foreach (var mp in part.BodyParts.Where(p => p is BodyPartMultipart))
            {
                fill((BodyPartMultipart)mp);
            }
        }
Exemplo n.º 6
0
 /// <summary>
 /// Visit the abstract multipart MIME entity.
 /// </summary>
 /// <remarks>
 /// Visits the abstract multipart MIME entity.
 /// </remarks>
 /// <param name="multipart">The multipart body part.</param>
 protected internal virtual void VisitBodyPartMultipart(BodyPartMultipart multipart)
 {
     VisitBodyPart(multipart);
     VisitChildren(multipart);
 }
Exemplo n.º 7
0
		static BodyPart ParseMultipart (ImapEngine engine, string path, string subtype, CancellationToken cancellationToken)
		{
			var prefix = path.Length > 0 ? path + "." : string.Empty;
			var body = new BodyPartMultipart ();
			ImapToken token;
			int index = 1;

			// Note: if subtype is not null, then we are working around a GMail bug...
			if (subtype == null) {
				do {
					body.BodyParts.Add (ParseBody (engine, prefix + index, cancellationToken));
					token = engine.PeekToken (cancellationToken);
					index++;
				} while (token.Type == ImapTokenType.OpenParen);

				subtype = ReadStringToken (engine, cancellationToken);
			}

			body.ContentType = new ContentType ("multipart", subtype);
			body.PartSpecifier = path;

			token = engine.PeekToken (cancellationToken);

			if (token.Type != ImapTokenType.CloseParen) {
				token = engine.ReadToken (cancellationToken);

				if (token.Type != ImapTokenType.OpenParen)
					throw ImapEngine.UnexpectedToken (token, false);

				var builder = new StringBuilder ();
				ContentType contentType;

				builder.AppendFormat ("{0}/{1}", body.ContentType.MediaType, body.ContentType.MediaSubtype);
				ParseParameterList (builder, engine, cancellationToken);

				if (ContentType.TryParse (builder.ToString (), out contentType))
					body.ContentType = contentType;

				token = engine.PeekToken (cancellationToken);
			}

			if (token.Type != ImapTokenType.CloseParen) {
				body.ContentDisposition = ParseContentDisposition (engine, cancellationToken);
				token = engine.PeekToken (cancellationToken);
			}

			if (token.Type != ImapTokenType.CloseParen) {
				body.ContentLanguage = ParseContentLanguage (engine, cancellationToken);
				token = engine.PeekToken (cancellationToken);
			}

			if (token.Type != ImapTokenType.CloseParen) {
				body.ContentLocation = ParseContentLocation (engine, cancellationToken);
				token = engine.PeekToken (cancellationToken);
			}

			if (token.Type != ImapTokenType.CloseParen)
				SkipBodyExtensions (engine, cancellationToken);

			// read the ')'
			token = engine.ReadToken (cancellationToken);

			if (token.Type != ImapTokenType.CloseParen)
				throw ImapEngine.UnexpectedToken (token, false);

			return body;
		}
Exemplo n.º 8
0
 protected override void VisitChildren(BodyPartMultipart multipart)
 {
     indent++;
     base.VisitChildren(multipart);
     indent--;
 }
Exemplo n.º 9
0
        static BodyPart ParseMultipart(ImapEngine engine, string path, CancellationToken cancellationToken)
        {
            var       prefix = path.Length > 0 ? path + "." : string.Empty;
            var       body   = new BodyPartMultipart();
            ImapToken token;
            int       index = 1;

            do
            {
                body.BodyParts.Add(ParseBody(engine, prefix + index, cancellationToken));
                token = engine.PeekToken(cancellationToken);
                index++;
            } while (token.Type == ImapTokenType.OpenParen);

            var subtype = ReadStringToken(engine, cancellationToken);

            body.ContentType   = new ContentType("multipart", subtype);
            body.PartSpecifier = path;

            token = engine.PeekToken(cancellationToken);

            if (token.Type != ImapTokenType.CloseParen)
            {
                token = engine.ReadToken(cancellationToken);

                if (token.Type != ImapTokenType.OpenParen)
                {
                    throw ImapEngine.UnexpectedToken(token, false);
                }

                var         builder = new StringBuilder();
                ContentType contentType;

                builder.AppendFormat("{0}/{1}", body.ContentType.MediaType, body.ContentType.MediaSubtype);
                ParseParameterList(builder, engine, cancellationToken);

                if (ContentType.TryParse(builder.ToString(), out contentType))
                {
                    body.ContentType = contentType;
                }

                token = engine.PeekToken(cancellationToken);
            }

            if (token.Type != ImapTokenType.CloseParen)
            {
                body.ContentDisposition = ParseContentDisposition(engine, cancellationToken);
                token = engine.PeekToken(cancellationToken);
            }

            if (token.Type != ImapTokenType.CloseParen)
            {
                body.ContentLanguage = ParseContentLocation(engine, cancellationToken);
                token = engine.PeekToken(cancellationToken);
            }

            if (token.Type != ImapTokenType.CloseParen)
            {
                body.ContentLocation = ReadNStringToken(engine, false, cancellationToken);
                token = engine.PeekToken(cancellationToken);
            }

            if (token.Type != ImapTokenType.CloseParen)
            {
                SkipBodyExtensions(engine, cancellationToken);
            }

            // read the ')'
            token = engine.ReadToken(cancellationToken);

            if (token.Type != ImapTokenType.CloseParen)
            {
                throw ImapEngine.UnexpectedToken(token, false);
            }

            return(body);
        }
Exemplo n.º 10
0
        static BodyPart ParseMultipart(ImapEngine engine, string path, CancellationToken cancellationToken)
        {
            var prefix = path.Length > 0 ? path + "." : string.Empty;
            var body = new BodyPartMultipart ();
            ImapToken token;
            int index = 1;

            do {
                body.BodyParts.Add (ParseBody (engine, prefix + index, cancellationToken));
                token = engine.PeekToken (cancellationToken);
                index++;
            } while (token.Type == ImapTokenType.OpenParen);

            var subtype = ReadStringToken (engine, cancellationToken);

            body.ContentType = new ContentType ("multipart", subtype);
            body.PartSpecifier = path;

            token = engine.PeekToken (cancellationToken);

            if (token.Type != ImapTokenType.CloseParen) {
                token = engine.ReadToken (cancellationToken);

                if (token.Type != ImapTokenType.OpenParen)
                    throw ImapEngine.UnexpectedToken (token, false);

                ParseParameterList (body.ContentType.Parameters, engine, cancellationToken);
                token = engine.PeekToken (cancellationToken);
            }

            if (token.Type != ImapTokenType.CloseParen) {
                body.ContentDisposition = ParseContentDisposition (engine, cancellationToken);
                token = engine.PeekToken (cancellationToken);
            }

            if (token.Type != ImapTokenType.CloseParen) {
                body.ContentLanguage = ParseContentLocation (engine, cancellationToken);
                token = engine.PeekToken (cancellationToken);
            }

            if (token.Type != ImapTokenType.CloseParen) {
                body.ContentLocation = ReadNStringToken (engine, false, cancellationToken);
                token = engine.PeekToken (cancellationToken);
            }

            if (token.Type != ImapTokenType.CloseParen)
                SkipBodyExtensions (engine, cancellationToken);

            // read the ')'
            token = engine.ReadToken (cancellationToken);

            if (token.Type != ImapTokenType.CloseParen)
                throw ImapEngine.UnexpectedToken (token, false);

            return body;
        }
Exemplo n.º 11
0
        public async Task <string> RenderMultipartRelatedAsync(IMailFolder folder, UniqueId uid, BodyPartMultipart bodyPart)
        {
            var related = await folder.GetBodyPartAsync(uid, bodyPart) as MultipartRelated;

            return(RenderMultipartRelated(related));
        }
Exemplo n.º 12
0
        async void RenderRelated(IMailFolder folder, UniqueId uid, BodyPartMultipart related)
        {
            var          start = related.ContentType.Parameters["start"];
            BodyPartText root  = null;

            if (!string.IsNullOrEmpty(start))
            {
                // if the 'start' parameter is set, it overrides the default behavior of using the first
                // body part as the main document.
                root = related.BodyParts.OfType <BodyPartText> ().FirstOrDefault(x => x.ContentId == start);
            }
            else if (related.BodyParts.Count > 0)
            {
                // this will generally either be a text/html part (which is what we are looking for) or a multipart/alternative
                var multipart = related.BodyParts[0] as BodyPartMultipart;

                if (multipart != null)
                {
                    if (multipart.ContentType.Matches("multipart", "alternative") && multipart.BodyParts.Count > 0)
                    {
                        // find the last text/html part (which will be the closest to what the sender saw in their WYSIWYG editor)
                        // or, failing that, the last text part.
                        for (int i = multipart.BodyParts.Count; i > 0; i--)
                        {
                            var bodyPart = multipart.BodyParts[i - 1] as BodyPartText;

                            if (bodyPart == null)
                            {
                                continue;
                            }

                            if (bodyPart.ContentType.Matches("text", "html"))
                            {
                                root = bodyPart;
                                break;
                            }

                            if (root == null)
                            {
                                root = bodyPart;
                            }
                        }
                    }
                }
                else
                {
                    root = related.BodyParts[0] as BodyPartText;
                }
            }

            if (root == null)
            {
                return;
            }

            var text = await folder.GetBodyPartAsync(uid, root) as TextPart;

            if (text != null && text.ContentType.Matches("text", "html"))
            {
                var      doc   = new HtmlAgilityPack.HtmlDocument();
                var      saved = new Dictionary <MimePart, string> ();
                TextPart html;

                doc.LoadHtml(text.Text);

                // find references to related MIME parts and replace them with links to links to the saved attachments
                foreach (var img in doc.DocumentNode.SelectNodes("//img[@src]"))
                {
                    var src = img.Attributes["src"];
                    int index;
                    Uri uri;

                    if (src == null || src.Value == null)
                    {
                        continue;
                    }

                    // parse the <img src=...> attribute value into a Uri
                    if (Uri.IsWellFormedUriString(src.Value, UriKind.Absolute))
                    {
                        uri = new Uri(src.Value, UriKind.Absolute);
                    }
                    else
                    {
                        uri = new Uri(src.Value, UriKind.Relative);
                    }

                    // locate the index of the attachment within the multipart/related (if it exists)
                    if ((index = related.BodyParts.IndexOf(uri)) != -1)
                    {
                        var bodyPart = related.BodyParts[index] as BodyPartBasic;

                        if (bodyPart == null)
                        {
                            // the body part is not a basic leaf part (IOW it's a multipart or message-part)
                            continue;
                        }

                        var attachment = await folder.GetBodyPartAsync(uid, bodyPart) as MimePart;

                        // make sure the referenced part is a MimePart (as opposed to another Multipart or MessagePart)
                        if (attachment == null)
                        {
                            continue;
                        }

                        string fileName;

                        // save the attachment (if we haven't already saved it)
                        if (!saved.TryGetValue(attachment, out fileName))
                        {
                            fileName = attachment.FileName;

                            if (string.IsNullOrEmpty(fileName))
                            {
                                fileName = Guid.NewGuid().ToString();
                            }

                            if (!Directory.Exists(uid.ToString()))
                            {
                                Directory.CreateDirectory(uid.ToString());
                            }

                            fileName = Path.Combine(uid.ToString(), fileName);

                            using (var stream = File.Create(fileName))
                                attachment.ContentObject.DecodeTo(stream);

                            saved.Add(attachment, fileName);
                        }

                        // replace the <img src=...> value with the local file name
                        src.Value = "file://" + Path.GetFullPath(fileName);
                    }
                }

                if (saved.Count > 0)
                {
                    // we had to make some modifications to the original html part, so create a new
                    // (temporary) text/html part to render
                    html = new TextPart("html");
                    using (var writer = new StringWriter()) {
                        doc.Save(writer);

                        html.Text = writer.GetStringBuilder().ToString();
                    }
                }
                else
                {
                    html = text;
                }

                RenderText(html);
            }
            else if (text != null)
            {
                RenderText(text);
            }
        }
Exemplo n.º 13
0
 public AttachmentBox(BodyPartMultipart multipart)
 {
     top            = multipart;
     attachmentList = new List <BodyPartBasic>();
 }
Exemplo n.º 14
0
        public static async void RenderMultipartRelated(IMailFolder folder, UniqueId uid, BodyPartMultipart bodyPart, WebBrowserEditabil pWebBrowser)
        {
            var related = await folder.GetBodyPartAsync(uid, bodyPart) as MultipartRelated;

            RenderMultipartRelated(related, pWebBrowser);
        }
Exemplo n.º 15
0
		/// <summary>
		/// Visit the abstract multipart MIME entity.
		/// </summary>
		/// <remarks>
		/// Visits the abstract multipart MIME entity.
		/// </remarks>
		/// <param name="multipart">The multipart body part.</param>
		protected internal virtual void VisitBodyPartMultipart (BodyPartMultipart multipart)
		{
			VisitBodyPart (multipart);
			VisitChildren (multipart);
		}
Exemplo n.º 16
0
		/// <summary>
		/// Visit the children of a <see cref="MailKit.BodyPartMultipart"/>.
		/// </summary>
		/// <remarks>
		/// Visits the children of a <see cref="MailKit.BodyPartMultipart"/>.
		/// </remarks>
		/// <param name="multipart">The multipart.</param>
		protected virtual void VisitChildren (BodyPartMultipart multipart)
		{
			for (int i = 0; i < multipart.BodyParts.Count; i++)
				multipart.BodyParts[i].Accept (this);
		}