Beispiel #1
0
        /// <summary>
        /// Computes the MD5 checksum of the content.
        /// </summary>
        /// <remarks>
        /// Computes the MD5 checksum of the MIME content in its canonical
        /// format and then base64-encodes the result.
        /// </remarks>
        /// <returns>The md5sum of the content.</returns>
        /// <exception cref="System.InvalidOperationException">
        /// The <see cref="ContentObject"/> is <c>null</c>.
        /// </exception>
        public string ComputeContentMd5()
        {
            if (ContentObject == null)
            {
                throw new InvalidOperationException("Cannot compute Md5 checksum without a ContentObject.");
            }

            using (var stream = ContentObject.Open()) {
                byte[] checksum;

                using (var filtered = new FilteredStream(stream)) {
                    if (ContentType.Matches("text", "*"))
                    {
                        filtered.Add(new Unix2DosFilter());
                    }

                    using (var md5 = new MD5())
                        checksum = md5.ComputeHash(filtered);
                }

                var base64 = new Base64Encoder(true);
                var digest = new byte[base64.EstimateOutputLength(checksum.Length)];
                int n      = base64.Flush(checksum, 0, checksum.Length, digest);

                return(Encoding.ASCII.GetString(digest, 0, n));
            }
        }
Beispiel #2
0
        /// <summary>
        /// Writes the <see cref="MimeKit.Multipart"/> to the specified output stream.
        /// </summary>
        /// <remarks>
        /// Writes the multipart MIME entity and its subparts to the output stream.
        /// </remarks>
        /// <param name="options">The formatting options.</param>
        /// <param name="stream">The output stream.</param>
        /// <param name="cancellationToken">A cancellation token.</param>
        /// <exception cref="System.ArgumentNullException">
        /// <para><paramref name="options"/> is <c>null</c>.</para>
        /// <para>-or-</para>
        /// <para><paramref name="stream"/> is <c>null</c>.</para>
        /// </exception>
        /// <exception cref="System.OperationCanceledException">
        /// The operation was canceled via the cancellation token.
        /// </exception>
        /// <exception cref="System.IO.IOException">
        /// An I/O error occurred.
        /// </exception>
        public override void WriteTo(FormatOptions options, Stream stream, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (Boundary == null)
            {
                Boundary = GenerateBoundary();
            }

            base.WriteTo(options, stream, cancellationToken);

            if (options.International && ContentType.Matches("multipart", "signed"))
            {
                // don't reformat the headers or content of any children of a multipart/signed
                options = options.Clone();
                options.HiddenHeaders.Clear();
                options.International = false;
            }

            var cancellable = stream as ICancellableStream;

            if (RawPreamble != null && RawPreamble.Length > 0)
            {
                WriteBytes(options, stream, RawPreamble, cancellationToken);
            }

            var boundary = Encoding.ASCII.GetBytes("--" + Boundary + "--");

            if (cancellable != null)
            {
                for (int i = 0; i < children.Count; i++)
                {
                    cancellable.Write(boundary, 0, boundary.Length - 2, cancellationToken);
                    cancellable.Write(options.NewLineBytes, 0, options.NewLineBytes.Length, cancellationToken);
                    children[i].WriteTo(options, stream, cancellationToken);
                    cancellable.Write(options.NewLineBytes, 0, options.NewLineBytes.Length, cancellationToken);
                }

                cancellable.Write(boundary, 0, boundary.Length, cancellationToken);
                cancellable.Write(options.NewLineBytes, 0, options.NewLineBytes.Length, cancellationToken);
            }
            else
            {
                for (int i = 0; i < children.Count; i++)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    stream.Write(boundary, 0, boundary.Length - 2);
                    stream.Write(options.NewLineBytes, 0, options.NewLineBytes.Length);
                    children[i].WriteTo(options, stream, cancellationToken);
                    stream.Write(options.NewLineBytes, 0, options.NewLineBytes.Length);
                }

                cancellationToken.ThrowIfCancellationRequested();
                stream.Write(boundary, 0, boundary.Length);
                stream.Write(options.NewLineBytes, 0, options.NewLineBytes.Length);
            }

            if (RawEpilogue != null && RawEpilogue.Length > 0)
            {
                WriteBytes(options, stream, RawEpilogue, cancellationToken);
            }
        }
Beispiel #3
0
        MimePart CreateAttachment(ContentType contentType, string fileName, Stream stream)
        {
            MimePart attachment;

            if (contentType.Matches("text", "*"))
            {
                attachment = new TextPart(contentType.MediaSubtype);
                foreach (var param in contentType.Parameters)
                {
                    attachment.ContentType.Parameters.Add(param);
                }

                // TODO: should we try to auto-detect charsets if no charset parameter is specified?
            }
            else
            {
                attachment = new MimePart(contentType);
            }

            attachment.FileName     = Path.GetFileName(fileName);
            attachment.IsAttachment = true;

            if (linked)
            {
                attachment.ContentLocation = new Uri(Path.GetFileName(fileName), UriKind.Relative);
            }

            LoadContent(attachment, stream);

            return(attachment);
        }
Beispiel #4
0
        ContentType GetContentType(ContentType parent)
        {
            ContentType type;

            for (int i = 0; i < headers.Count; i++) {
                if (icase.Compare (headers[i].Field, "Content-Type") != 0)
                    continue;

                if (!ContentType.TryParse (options, headers[i].RawValue, out type))
                    return new ContentType ("application", "octet-stream");

                return type;
            }

            if (parent == null || !parent.Matches ("multipart", "digest"))
                return new ContentType ("text", "plain");

            return new ContentType ("message", "rfc822");
        }