Ejemplo n.º 1
0
        public static Task <IEnumerable <HttpContent> > ReadAsMultipartAsync(this HttpContent content, IMultipartStreamProvider streamProvider, int bufferSize)
        {
            if (content == null)
            {
                throw new ArgumentNullException("content");
            }

            if (streamProvider == null)
            {
                throw new ArgumentNullException("streamProvider");
            }

            if (bufferSize < MinBufferSize)
            {
                throw new ArgumentOutOfRangeException("bufferSize", bufferSize, RS.Format(Properties.Resources.ArgumentMustBeGreaterThanOrEqualTo, MinBufferSize));
            }

            return(content.ReadAsStreamAsync().Then(stream =>
            {
                TaskCompletionSource <IEnumerable <HttpContent> > taskCompletionSource = new TaskCompletionSource <IEnumerable <HttpContent> >();
                MimeMultipartBodyPartParser parser = new MimeMultipartBodyPartParser(content, streamProvider);
                byte[] data = new byte[bufferSize];
                MultipartAsyncContext context = new MultipartAsyncContext(stream, taskCompletionSource, parser, data);

                // Start async read/write loop
                MultipartReadAsync(context);

                // Return task and complete later
                return taskCompletionSource.Task;
            }));
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Determines whether the specified content is MIME multipart content.
        /// </summary>
        /// <param name="content">The content.</param>
        /// <returns>
        ///   <c>true</c> if the specified content is MIME multipart content; otherwise, <c>false</c>.
        /// </returns>
        public static bool IsMimeMultipartContent(this HttpContent content)
        {
            if (content == null)
            {
                throw Error.ArgumentNull("content");
            }

            return(MimeMultipartBodyPartParser.IsMimeMultipartContent(content));
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Reads all body parts within a MIME multipart message using the provided <see cref="MultipartStreamProvider"/> instance
        /// to determine where the contents of each body part is written and <paramref name="bufferSize"/> as read buffer size.
        /// </summary>
        /// <typeparam name="T">The <see cref="MultipartStreamProvider"/> with which to process the data.</typeparam>
        /// <param name="content">An existing <see cref="HttpContent"/> instance to use for the object's content.</param>
        /// <param name="streamProvider">A stream provider providing output streams for where to write body parts as they are parsed.</param>
        /// <param name="bufferSize">Size of the buffer used to read the contents.</param>
        /// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
        /// <returns>A <see cref="Task{T}"/> representing the tasks of getting the result of reading the MIME content.</returns>
        public static async Task <T> ReadAsMultipartAsync <T>(
            this HttpContent content,
            T streamProvider,
            int bufferSize,
            CancellationToken cancellationToken
            ) where T : MultipartStreamProvider
        {
            if (content == null)
            {
                throw Error.ArgumentNull("content");
            }

            if (streamProvider == null)
            {
                throw Error.ArgumentNull("streamProvider");
            }

            if (bufferSize < MinBufferSize)
            {
                throw Error.ArgumentMustBeGreaterThanOrEqualTo(
                          "bufferSize",
                          bufferSize,
                          MinBufferSize
                          );
            }

            Stream stream;

            try
            {
                stream = await content.ReadAsStreamAsync();
            }
            catch (Exception e)
            {
                throw new IOException(Properties.Resources.ReadAsMimeMultipartErrorReading, e);
            }

            using (var parser = new MimeMultipartBodyPartParser(content, streamProvider))
            {
                byte[] data = new byte[bufferSize];
                MultipartAsyncContext context = new MultipartAsyncContext(
                    stream,
                    parser,
                    data,
                    streamProvider.Contents
                    );

                // Start async read/write loop
                await MultipartReadAsync(context, cancellationToken);

                // Let the stream provider post-process when everything is complete
                await streamProvider.ExecutePostProcessingAsync(cancellationToken);

                return(streamProvider);
            }
        }
Ejemplo n.º 4
0
            public MultipartAsyncContext(Stream contentStream, MimeMultipartBodyPartParser mimeParser, byte[] data, ICollection <HttpContent> result)
            {
                Contract.Assert(contentStream != null);
                Contract.Assert(mimeParser != null);
                Contract.Assert(data != null);

                ContentStream = contentStream;
                Result        = result;
                MimeParser    = mimeParser;
                Data          = data;
            }
Ejemplo n.º 5
0
            /// <summary>
            /// Initializes a new instance of the <see cref="MultipartAsyncContext"/> class.
            /// </summary>
            /// <param name="contentStream">The content stream.</param>
            /// <param name="taskCompletionSource">The task completion source.</param>
            /// <param name="mimeParser">The MIME parser.</param>
            /// <param name="data">The buffer that we read data from.</param>
            public MultipartAsyncContext(Stream contentStream, TaskCompletionSource <IEnumerable <HttpContent> > taskCompletionSource, MimeMultipartBodyPartParser mimeParser, byte[] data)
            {
                Contract.Assert(contentStream != null, "contentStream cannot be null");
                Contract.Assert(taskCompletionSource != null, "task cannot be null");
                Contract.Assert(mimeParser != null, "mimeParser cannot be null");
                Contract.Assert(data != null, "data cannot be null");

                ContentStream        = contentStream;
                Result               = new List <HttpContent>();
                TaskCompletionSource = taskCompletionSource;
                MimeParser           = mimeParser;
                Data = data;
            }
            public MultipartAsyncContext(HttpContent parent, Stream contentStream, TaskCompletionSource <bool> taskCompletionSource, MimeMultipartBodyPartParser mimeParser, byte[] data, ICollection <HttpContent> result)
            {
                Contract.Assert(parent != null);
                Contract.Assert(contentStream != null);
                Contract.Assert(taskCompletionSource != null);
                Contract.Assert(mimeParser != null);
                Contract.Assert(data != null);

                Parent               = parent;
                ContentStream        = contentStream;
                Result               = result;
                TaskCompletionSource = taskCompletionSource;
                MimeParser           = mimeParser;
                Data = data;
            }
        public static Task <T> ReadAsMultipartAsync <T>(this HttpContent content, T streamProvider, int bufferSize) where T : MultipartStreamProvider
        {
            if (content == null)
            {
                throw Error.ArgumentNull("content");
            }

            if (streamProvider == null)
            {
                throw Error.ArgumentNull("streamProvider");
            }

            if (bufferSize < MinBufferSize)
            {
                throw Error.ArgumentMustBeGreaterThanOrEqualTo("bufferSize", bufferSize, MinBufferSize);
            }

            MimeMultipartBodyPartParser parser = null;

            return(content.ReadAsStreamAsync().Then(stream =>
            {
                TaskCompletionSource <bool> taskCompletionSource = new TaskCompletionSource <bool>();
                parser = new MimeMultipartBodyPartParser(content, streamProvider);
                byte[] data = new byte[bufferSize];
                MultipartAsyncContext context = new MultipartAsyncContext(content, stream, taskCompletionSource, parser, data, streamProvider.Contents);

                // Start async read/write loop
                MultipartReadAsync(context);

                // Return task and complete when we have run the post processing step.
                return taskCompletionSource.Task.Then(() => streamProvider.ExecutePostProcessingAsync().ToTask <T>(result: streamProvider));
            }).Finally(() =>
            {
                if (parser != null)
                {
                    parser.Dispose();
                }
            }, runSynchronously: true));
        }
        /// <summary>
        /// Reads all body parts within a MIME multipart message using the provided <see cref="MultipartStreamProvider"/> instance
        /// to determine where the contents of each body part is written and <paramref name="bufferSize"/> as read buffer size.
        /// </summary>
        /// <typeparam name="T">The <see cref="MultipartStreamProvider"/> with which to process the data.</typeparam>
        /// <param name="content">An existing <see cref="HttpContent"/> instance to use for the object's content.</param>
        /// <param name="streamProvider">A stream provider providing output streams for where to write body parts as they are parsed.</param>
        /// <param name="bufferSize">Size of the buffer used to read the contents.</param>
        /// <returns>A <see cref="Task{T}"/> representing the tasks of getting the result of reading the MIME content.</returns>
#if NETFX_CORE
        public static async Task <T> ReadAsMultipartAsync <T>(this HttpContent content, T streamProvider, int bufferSize) where T : MultipartStreamProvider
        {
            if (content == null)
            {
                throw Error.ArgumentNull("content");
            }

            if (streamProvider == null)
            {
                throw Error.ArgumentNull("streamProvider");
            }

            if (bufferSize < MinBufferSize)
            {
                throw Error.ArgumentMustBeGreaterThanOrEqualTo("bufferSize", bufferSize, MinBufferSize);
            }

            try
            {
                Stream stream = await content.ReadAsStreamAsync();

                List <HttpContent> childContents = new List <HttpContent>();

                using (var parser = new MimeMultipartBodyPartParser(content, streamProvider))
                {
                    byte[] buffer    = new byte[bufferSize];
                    bool   finalPart = false;

                    while (!finalPart)
                    {
                        int readCount = await stream.ReadAsync(buffer, 0, buffer.Length);

                        // The parser returns one or more parsed parts, depending on how much data was returned
                        // from the network read. The last part may be incomplete (partial), so we only dispose
                        // of the parts once we know they're finished. Regardless of whether the part is complete
                        // or not, we send the bytes to the desired output stream. We loop back for more data
                        // until we've completely read the complete, final part.
                        foreach (MimeBodyPart part in parser.ParseBuffer(buffer, readCount))
                        {
                            try
                            {
                                Stream output = part.GetOutputStream(content);

                                foreach (ArraySegment <byte> segment in part.Segments)
                                {
                                    await output.WriteAsync(segment.Array, segment.Offset, segment.Count);
                                }

                                if (part.IsComplete)
                                {
                                    if (part.HttpContent != null)
                                    {
                                        childContents.Add(part.HttpContent);
                                    }

                                    finalPart = part.IsFinal;
                                    part.Dispose();
                                    break;
                                }
                            }
                            catch (Exception)
                            {
                                // Clean up the part if we got an error in the middle of parsing, because we normally
                                // won't dispose a part until it's complete.
                                part.Dispose();
                                throw;
                            }
                        }
                    }

                    // Let the stream provider post-process when everything is complete
                    await streamProvider.ExecutePostProcessingAsync();

                    return(streamProvider);
                }
            }
            catch (Exception e)
            {
                throw new IOException(Properties.Resources.ReadAsMimeMultipartErrorReading, e);
            }
        }