Esempio n. 1
0
        public void TestBase64Encode()
        {
            using (var original = new MemoryStream()) {
                using (var file = File.OpenRead("../../TestData/encoders/photo.b64")) {
                    using (var filtered = new FilteredStream(original)) {
                        filtered.Add(new Dos2UnixFilter());
                        file.CopyTo(filtered, 4096);
                        filtered.Flush();
                    }
                }

                using (var encoded = new MemoryStream()) {
                    using (var filtered = new FilteredStream(encoded)) {
                        filtered.Add(EncoderFilter.Create(ContentEncoding.Base64));

                        using (var file = File.OpenRead("../../TestData/encoders/photo.jpg"))
                            file.CopyTo(filtered, 4096);

                        filtered.Flush();
                    }

                    var buf0 = original.GetBuffer();
                    var buf1 = encoded.GetBuffer();
                    int n    = (int)original.Length;

                    Assert.AreEqual(original.Length, encoded.Length, "Encoded length is incorrect.");

                    for (int i = 0; i < n; i++)
                    {
                        Assert.AreEqual(buf0[i], buf1[i], "The byte at offset {0} does not match.", i);
                    }
                }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Asynchronously writes the <see cref="MimeKit.MimePart"/> to the specified output stream.
        /// </summary>
        /// <remarks>
        /// Writes the MIME part to the output stream.
        /// </remarks>
        /// <param name="options">The formatting options.</param>
        /// <param name="stream">The output stream.</param>
        /// <param name="contentOnly"><c>true</c> if only the content should be written; otherwise, <c>false</c>.</param>
        /// <param name="cancellationToken">The 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 async Task WriteToAsync(FormatOptions options, Stream stream, bool contentOnly, CancellationToken cancellationToken = default(CancellationToken))
        {
            await base.WriteToAsync(options, stream, contentOnly, cancellationToken).ConfigureAwait(false);

            if (Content == null)
            {
                return;
            }

            if (Content.Encoding != encoding)
            {
                if (encoding == ContentEncoding.UUEncode)
                {
                    var begin  = string.Format("begin 0644 {0}", FileName ?? "unknown");
                    var buffer = Encoding.UTF8.GetBytes(begin);

                    await stream.WriteAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false);

                    await stream.WriteAsync(options.NewLineBytes, 0, options.NewLineBytes.Length, cancellationToken).ConfigureAwait(false);
                }

                // transcode the content into the desired Content-Transfer-Encoding
                using (var filtered = new FilteredStream(stream)) {
                    filtered.Add(EncoderFilter.Create(encoding));

                    if (encoding != ContentEncoding.Binary)
                    {
                        filtered.Add(options.CreateNewLineFilter(EnsureNewLine));
                    }

                    await Content.DecodeToAsync(filtered, cancellationToken).ConfigureAwait(false);

                    await filtered.FlushAsync(cancellationToken).ConfigureAwait(false);
                }

                if (encoding == ContentEncoding.UUEncode)
                {
                    var buffer = Encoding.ASCII.GetBytes("end");

                    await stream.WriteAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false);

                    await stream.WriteAsync(options.NewLineBytes, 0, options.NewLineBytes.Length, cancellationToken).ConfigureAwait(false);
                }
            }
            else if (encoding != ContentEncoding.Binary)
            {
                using (var filtered = new FilteredStream(stream)) {
                    // Note: if we are writing the top-level MimePart, make sure it ends with a new-line so that
                    // MimeMessage.WriteTo() *always* ends with a new-line.
                    filtered.Add(options.CreateNewLineFilter(EnsureNewLine));
                    await Content.WriteToAsync(filtered, cancellationToken).ConfigureAwait(false);

                    await filtered.FlushAsync(cancellationToken).ConfigureAwait(false);
                }
            }
            else
            {
                await Content.WriteToAsync(stream, cancellationToken).ConfigureAwait(false);
            }
        }
Esempio n. 3
0
        public void TestCreateEncoders()
        {
            Assert.Throws <ArgumentNullException> (() => EncoderFilter.Create(null));
            Assert.Throws <ArgumentNullException> (() => DecoderFilter.Create(null));

            AssertIsEncoderFilter(ContentEncoding.Base64, ContentEncoding.Base64);
            AssertIsEncoderFilter("base64", ContentEncoding.Base64);

            Assert.IsInstanceOf <PassThroughFilter> (EncoderFilter.Create(ContentEncoding.Binary));
            Assert.IsInstanceOf <PassThroughFilter> (EncoderFilter.Create("binary"));

            Assert.IsInstanceOf <PassThroughFilter> (EncoderFilter.Create(ContentEncoding.Default));
            Assert.IsInstanceOf <PassThroughFilter> (EncoderFilter.Create("x-invalid"));

            Assert.IsInstanceOf <PassThroughFilter> (EncoderFilter.Create(ContentEncoding.EightBit));
            Assert.IsInstanceOf <PassThroughFilter> (EncoderFilter.Create("8bit"));

            AssertIsEncoderFilter(ContentEncoding.QuotedPrintable, ContentEncoding.QuotedPrintable);
            AssertIsEncoderFilter("quoted-printable", ContentEncoding.QuotedPrintable);

            Assert.IsInstanceOf <PassThroughFilter> (EncoderFilter.Create(ContentEncoding.SevenBit));
            Assert.IsInstanceOf <PassThroughFilter> (EncoderFilter.Create("7bit"));

            AssertIsEncoderFilter(ContentEncoding.UUEncode, ContentEncoding.UUEncode);
            AssertIsEncoderFilter("x-uuencode", ContentEncoding.UUEncode);
            AssertIsEncoderFilter("uuencode", ContentEncoding.UUEncode);
        }
Esempio n. 4
0
        /// <summary>
        /// Writes the <see cref="MimeKit.MimePart"/> to the specified output stream.
        /// </summary>
        /// <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)
        {
            base.WriteTo(options, stream, cancellationToken);

            if (ContentObject == null)
            {
                return;
            }

            if (ContentObject.Encoding != encoding)
            {
                if (encoding == ContentEncoding.UUEncode)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    var begin  = string.Format("begin 0644 {0}", FileName ?? "unknown");
                    var buffer = Encoding.UTF8.GetBytes(begin);
                    stream.Write(buffer, 0, buffer.Length);
                    stream.Write(options.NewLineBytes, 0, options.NewLineBytes.Length);
                }

                // transcode the content into the desired Content-Transfer-Encoding
                using (var filtered = new FilteredStream(stream)) {
                    filtered.Add(EncoderFilter.Create(encoding));

                    if (encoding != ContentEncoding.Binary)
                    {
                        filtered.Add(options.CreateNewLineFilter());
                    }

                    ContentObject.DecodeTo(filtered, cancellationToken);
                    filtered.Flush();
                }

                if (encoding == ContentEncoding.UUEncode)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    var buffer = Encoding.ASCII.GetBytes("end");
                    stream.Write(buffer, 0, buffer.Length);
                    stream.Write(options.NewLineBytes, 0, options.NewLineBytes.Length);
                }
            }
            else if (encoding != ContentEncoding.Binary)
            {
                using (var filtered = new FilteredStream(stream)) {
                    filtered.Add(options.CreateNewLineFilter());
                    ContentObject.WriteTo(filtered, cancellationToken);
                    filtered.Flush();
                }
            }
            else
            {
                ContentObject.WriteTo(stream, cancellationToken);
            }
        }
Esempio n. 5
0
        static void AssertIsEncoderFilter(string encoding, ContentEncoding expected)
        {
            var filter = EncoderFilter.Create(encoding);

            Assert.IsInstanceOf <EncoderFilter> (filter, "Expected EncoderFilter for \"{0}\"", encoding);

            var encoder = (EncoderFilter)filter;

            Assert.AreEqual(expected, encoder.Encoding, "Expected encoder's Encoding to be ContentEncoding.{0}", expected);
        }
Esempio n. 6
0
        void TestEncoder(ContentEncoding encoding, byte[] rawData, string encodedFile, int bufferSize)
        {
            int n;

            using (var original = new MemoryStream()) {
                using (var file = File.OpenRead(Path.Combine(dataDir, encodedFile))) {
                    using (var filtered = new FilteredStream(original)) {
                        filtered.Add(new Dos2UnixFilter());
                        file.CopyTo(filtered, 4096);
                        filtered.Flush();
                    }
                }

                using (var encoded = new MemoryStream()) {
                    if (encoding == ContentEncoding.UUEncode)
                    {
                        var begin = Encoding.ASCII.GetBytes("begin 644 photo.jpg\n");
                        encoded.Write(begin, 0, begin.Length);
                    }

                    using (var filtered = new FilteredStream(encoded)) {
                        filtered.Add(EncoderFilter.Create(encoding));

                        using (var memory = new MemoryStream(rawData, false)) {
                            var buffer = new byte[bufferSize];

                            while ((n = memory.Read(buffer, 0, bufferSize)) > 0)
                            {
                                filtered.Write(buffer, 0, n);
                            }
                        }

                        filtered.Flush();
                    }

                    if (encoding == ContentEncoding.UUEncode)
                    {
                        var end = Encoding.ASCII.GetBytes("end\n");
                        encoded.Write(end, 0, end.Length);
                    }

                    var buf0 = original.GetBuffer();
                    var buf1 = encoded.GetBuffer();
                    n = (int)original.Length;

                    Assert.AreEqual(original.Length, encoded.Length, "Encoded length is incorrect.");

                    for (int i = 0; i < n; i++)
                    {
                        Assert.AreEqual(buf0[i], buf1[i], "The byte at offset {0} does not match.", i);
                    }
                }
            }
        }
Esempio n. 7
0
 public void TestFilterArguments()
 {
     AssertFilterArguments(new Dos2UnixFilter());
     AssertFilterArguments(new Unix2DosFilter());
     AssertFilterArguments(new ArmoredFromFilter());
     AssertFilterArguments(new BestEncodingFilter());
     AssertFilterArguments(new CharsetFilter("iso-8859-1", "utf-8"));
     AssertFilterArguments(DecoderFilter.Create(ContentEncoding.Base64));
     AssertFilterArguments(EncoderFilter.Create(ContentEncoding.Base64));
     AssertFilterArguments(DecoderFilter.Create(ContentEncoding.QuotedPrintable));
     AssertFilterArguments(EncoderFilter.Create(ContentEncoding.QuotedPrintable));
     AssertFilterArguments(DecoderFilter.Create(ContentEncoding.UUEncode));
     AssertFilterArguments(EncoderFilter.Create(ContentEncoding.UUEncode));
     AssertFilterArguments(new TrailingWhitespaceFilter());
     AssertFilterArguments(new DkimRelaxedBodyFilter());
     AssertFilterArguments(new DkimSimpleBodyFilter());
 }
Esempio n. 8
0
        public void TestUUEncode()
        {
            using (var original = new MemoryStream()) {
                using (var file = File.OpenRead("../../TestData/encoders/photo.uu")) {
                    using (var filtered = new FilteredStream(original)) {
                        filtered.Add(new Dos2UnixFilter());
                        file.CopyTo(filtered, 4096);
                        filtered.Flush();
                    }
                }

                using (var encoded = new MemoryStream()) {
                    var begin = Encoding.ASCII.GetBytes("begin 644 photo.jpg\n");
                    var end   = Encoding.ASCII.GetBytes("end\n");

                    encoded.Write(begin, 0, begin.Length);

                    using (var filtered = new FilteredStream(encoded)) {
                        filtered.Add(EncoderFilter.Create(ContentEncoding.UUEncode));

                        using (var file = File.OpenRead("../../TestData/encoders/photo.jpg"))
                            file.CopyTo(filtered, 4096);

                        filtered.Flush();
                    }

                    encoded.Write(end, 0, end.Length);

                    var buf0 = original.GetBuffer();
                    var buf1 = encoded.GetBuffer();
                    int n    = (int)original.Length;

                    Assert.AreEqual(original.Length, encoded.Length, "Encoded length is incorrect.");

                    for (int i = 0; i < n; i++)
                    {
                        Assert.AreEqual(buf0[i], buf1[i], "The byte at offset {0} does not match.", i);
                    }
                }
            }
        }
Esempio n. 9
0
        /// <summary>
        /// Writes the <see cref="MimeKit.MimePart"/> to the specified output stream.
        /// </summary>
        /// <remarks>
        /// Writes the MIME part to the output stream.
        /// </remarks>
        /// <param name="options">The formatting options.</param>
        /// <param name="stream">The output stream.</param>
        /// <param name="contentOnly"><c>true</c> if only the content should be written; otherwise, <c>false</c>.</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, bool contentOnly, CancellationToken cancellationToken = default(CancellationToken))
        {
            base.WriteTo(options, stream, contentOnly, cancellationToken);

            if (ContentObject == null)
            {
                return;
            }

            var cancellable = stream as ICancellableStream;

            if (ContentObject.Encoding != encoding)
            {
                if (encoding == ContentEncoding.UUEncode)
                {
                    var begin  = string.Format("begin 0644 {0}", FileName ?? "unknown");
                    var buffer = Encoding.UTF8.GetBytes(begin);

                    if (cancellable != null)
                    {
                        cancellable.Write(buffer, 0, buffer.Length, cancellationToken);
                        cancellable.Write(options.NewLineBytes, 0, options.NewLineBytes.Length, cancellationToken);
                    }
                    else
                    {
                        cancellationToken.ThrowIfCancellationRequested();
                        stream.Write(buffer, 0, buffer.Length);
                        stream.Write(options.NewLineBytes, 0, options.NewLineBytes.Length);
                    }
                }

                // transcode the content into the desired Content-Transfer-Encoding
                using (var filtered = new FilteredStream(stream)) {
                    filtered.Add(EncoderFilter.Create(encoding));

                    if (encoding != ContentEncoding.Binary)
                    {
                        filtered.Add(options.CreateNewLineFilter(true));
                    }

                    ContentObject.DecodeTo(filtered, cancellationToken);
                    filtered.Flush(cancellationToken);
                }

                if (encoding == ContentEncoding.UUEncode)
                {
                    var buffer = Encoding.ASCII.GetBytes("end");

                    if (cancellable != null)
                    {
                        cancellable.Write(buffer, 0, buffer.Length, cancellationToken);
                        cancellable.Write(options.NewLineBytes, 0, options.NewLineBytes.Length, cancellationToken);
                    }
                    else
                    {
                        cancellationToken.ThrowIfCancellationRequested();
                        stream.Write(buffer, 0, buffer.Length);
                        stream.Write(options.NewLineBytes, 0, options.NewLineBytes.Length);
                    }
                }
            }
            else if (encoding != ContentEncoding.Binary)
            {
                using (var filtered = new FilteredStream(stream)) {
                    // Note: if we are writing the top-level MimePart, make sure it ends with a new-line so that
                    // MimeMessage.WriteTo() *always* ends with a new-line.
                    filtered.Add(options.CreateNewLineFilter(EnsureNewLine));
                    ContentObject.WriteTo(filtered, cancellationToken);
                    filtered.Flush(cancellationToken);
                }
            }
            else
            {
                ContentObject.WriteTo(stream, cancellationToken);
            }
        }
Esempio n. 10
0
        /// <summary>
        /// Asynchronously write the <see cref="MimePart"/> to the specified output stream.
        /// </summary>
        /// <remarks>
        /// Asynchronously writes the MIME part to the output stream.
        /// </remarks>
        /// <returns>An awaitable task.</returns>
        /// <param name="options">The formatting options.</param>
        /// <param name="stream">The output stream.</param>
        /// <param name="contentOnly"><c>true</c> if only the content should be written; otherwise, <c>false</c>.</param>
        /// <param name="cancellationToken">The 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 async Task WriteToAsync(FormatOptions options, Stream stream, bool contentOnly, CancellationToken cancellationToken = default(CancellationToken))
        {
            await base.WriteToAsync(options, stream, contentOnly, cancellationToken).ConfigureAwait(false);

            if (Content == null)
            {
                return;
            }

            var isText = ContentType.IsMimeType("text", "*") || ContentType.IsMimeType("message", "*");

            if (Content.Encoding != encoding)
            {
                if (encoding == ContentEncoding.UUEncode)
                {
                    var begin  = string.Format("begin 0644 {0}", FileName ?? "unknown");
                    var buffer = Encoding.UTF8.GetBytes(begin);

                    await stream.WriteAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false);

                    await stream.WriteAsync(options.NewLineBytes, 0, options.NewLineBytes.Length, cancellationToken).ConfigureAwait(false);
                }

                // transcode the content into the desired Content-Transfer-Encoding
                using (var filtered = new FilteredStream(stream)) {
                    filtered.Add(EncoderFilter.Create(encoding));

                    if (encoding != ContentEncoding.Binary)
                    {
                        filtered.Add(options.CreateNewLineFilter(EnsureNewLine));
                    }

                    await Content.DecodeToAsync(filtered, cancellationToken).ConfigureAwait(false);

                    await filtered.FlushAsync(cancellationToken).ConfigureAwait(false);
                }

                if (encoding == ContentEncoding.UUEncode)
                {
                    var buffer = Encoding.ASCII.GetBytes("end");

                    await stream.WriteAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false);

                    await stream.WriteAsync(options.NewLineBytes, 0, options.NewLineBytes.Length, cancellationToken).ConfigureAwait(false);
                }
            }
            else if (encoding == ContentEncoding.Binary)
            {
                // Do not alter binary content.
                await Content.WriteToAsync(stream, cancellationToken).ConfigureAwait(false);
            }
            else if (options.VerifyingSignature && Content.NewLineFormat.HasValue && Content.NewLineFormat.Value == NewLineFormat.Mixed)
            {
                // Allow pass-through of the original parsed content without canonicalization when verifying signatures
                // if the content contains a mix of line-endings.
                //
                // See https://github.com/jstedfast/MimeKit/issues/569 for details.
                await Content.WriteToAsync(stream, cancellationToken).ConfigureAwait(false);
            }
            else
            {
                using (var filtered = new FilteredStream(stream)) {
                    // Note: if we are writing the top-level MimePart, make sure it ends with a new-line so that
                    // MimeMessage.WriteTo() *always* ends with a new-line.
                    filtered.Add(options.CreateNewLineFilter(EnsureNewLine));
                    await Content.WriteToAsync(filtered, cancellationToken).ConfigureAwait(false);

                    await filtered.FlushAsync(cancellationToken).ConfigureAwait(false);
                }
            }
        }