private static void MultipartWriteSegmentAsyncComplete(IAsyncResult result) { Contract.Assert(result != null, "result cannot be null."); MultipartAsyncContext context = (MultipartAsyncContext)result.AsyncState; Contract.Assert(context != null, "context cannot be null"); MimeBodyPart part = context.PartsEnumerator.Current; try { Stream output = context.PartsEnumerator.Current.GetOutputStream(); output.EndWrite(result); } catch (Exception e) { part.Dispose(); context.TaskCompletionSource.TrySetException(new IOException(Properties.Resources.ReadAsMimeMultipartErrorWriting, e)); } if (!MoveNextSegment(context)) { MoveNextPart(context); } }
private static async Task <bool> MoveToNextSegmentAsync(MultipartAsyncContext context) { Contract.Assert(context != null, "context cannot be null"); if (context.SegmentsEnumerator.MoveNext()) { Stream output = context.PartsEnumerator.Current.GetOutputStream(context.Parent); try { ArraySegment <byte> segment = (ArraySegment <byte>)context.SegmentsEnumerator.Current; await output.WriteAsync(segment.Array, segment.Offset, segment.Count); if (!await MoveToNextSegmentAsync(context)) { await MoveToNextPartAsync(context); } return(true); } catch (Exception e) { context.PartsEnumerator.Current.Dispose(); throw new IOException(Properties.Resources.ReadAsMimeMultipartErrorWriting, e); } } return(CheckIsFinalPart(context.PartsEnumerator.Current, context.Result)); }
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; })); }
private static bool MoveNextSegment(MultipartAsyncContext context) { Contract.Assert(context != null, "context cannot be null"); try { if (context.SegmentsEnumerator.MoveNext()) { MultipartWriteSegmentAsync(context); return(true); } else if (CheckPartCompletion(context.PartsEnumerator.Current, context.Result)) { // We are done parsing context.TaskCompletionSource.TrySetResult(true); return(true); } } catch (Exception e) { context.TaskCompletionSource.TrySetException(e); return(true); } return(false); }
/// <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); } }
private static async Task MultipartReadAsync( MultipartAsyncContext context, CancellationToken cancellationToken ) { Contract.Assert(context != null, "context cannot be null"); while (true) { int bytesRead; try { bytesRead = await context.ContentStream.ReadAsync( context.Data, 0, context.Data.Length, cancellationToken ); } catch (Exception e) { throw new IOException(Properties.Resources.ReadAsMimeMultipartErrorReading, e); } IEnumerable <MimeBodyPart> parts = context.MimeParser.ParseBuffer( context.Data, bytesRead ); foreach (MimeBodyPart part in parts) { foreach (ArraySegment <byte> segment in part.Segments) { try { await part.WriteSegment(segment, cancellationToken); } catch (Exception e) { part.Dispose(); throw new IOException( Properties.Resources.ReadAsMimeMultipartErrorWriting, e ); } } if (CheckIsFinalPart(part, context.Result)) { return; } } } }
private static async Task MoveToNextPartAsync(MultipartAsyncContext context) { Contract.Assert(context != null, "context cannot be null"); while (context.PartsEnumerator.MoveNext()) { context.SegmentsEnumerator = context.PartsEnumerator.Current.Segments.GetEnumerator(); if (await MoveToNextSegmentAsync(context)) { return; } } await MultipartReadAsync(context); }
private static void MoveNextPart(MultipartAsyncContext context) { Contract.Assert(context != null, "context cannot be null"); while (context.PartsEnumerator.MoveNext()) { context.SegmentsEnumerator = context.PartsEnumerator.Current.Segments.GetEnumerator(); if (MoveNextSegment(context)) { return; } } // Read some more MultipartReadAsync(context); }
private static void OnMultipartReadAsyncComplete(IAsyncResult result) { if (result.CompletedSynchronously) { return; } MultipartAsyncContext context = (MultipartAsyncContext)result.AsyncState; Contract.Assert(context != null, "context cannot be null"); try { MultipartReadAsyncComplete(result); } catch (Exception e) { context.TaskCompletionSource.TrySetException(e); } }
private static void MultipartReadAsync(MultipartAsyncContext context) { Contract.Assert(context != null, "context cannot be null"); IAsyncResult result = null; try { result = context.ContentStream.BeginRead(context.Data, 0, context.Data.Length, _onMultipartReadAsyncComplete, context); if (result.CompletedSynchronously) { MultipartReadAsyncComplete(result); } } catch (Exception e) { Exception exception = (result != null && result.CompletedSynchronously) ? e : new IOException(Properties.Resources.ReadAsMimeMultipartErrorReading, e); context.TaskCompletionSource.TrySetException(exception); } }
private static async Task MultipartReadAsync(MultipartAsyncContext context) { Contract.Assert(context != null, "context cannot be null"); int bytesRead = 0; try { bytesRead = await context.ContentStream.ReadAsync(context.Data, 0, context.Data.Length); } catch (Exception e) { throw new IOException(Properties.Resources.ReadAsMimeMultipartErrorReading, e); } IEnumerable <MimeBodyPart> parts = context.MimeParser.ParseBuffer(context.Data, bytesRead); context.PartsEnumerator = parts.GetEnumerator(); await MoveToNextPartAsync(context); }
private static void MultipartReadAsyncComplete(IAsyncResult result) { Contract.Assert(result != null, "result cannot be null"); MultipartAsyncContext context = (MultipartAsyncContext)result.AsyncState; int bytesRead = 0; try { bytesRead = context.ContentStream.EndRead(result); } catch (Exception e) { context.TaskCompletionSource.TrySetException(new IOException(Properties.Resources.ReadAsMimeMultipartErrorReading, e)); } IEnumerable <MimeBodyPart> parts = context.MimeParser.ParseBuffer(context.Data, bytesRead); context.PartsEnumerator = parts.GetEnumerator(); MoveNextPart(context); }
private static void MultipartWriteSegmentAsync(MultipartAsyncContext context) { Contract.Assert(context != null, "context cannot be null."); Stream output = context.PartsEnumerator.Current.GetOutputStream(); ArraySegment <byte> segment = (ArraySegment <byte>)context.SegmentsEnumerator.Current; try { IAsyncResult result = output.BeginWrite(segment.Array, segment.Offset, segment.Count, _onMultipartWriteSegmentAsyncComplete, context); if (result.CompletedSynchronously) { MultipartWriteSegmentAsyncComplete(result); } } catch (Exception e) { context.PartsEnumerator.Current.Dispose(); context.TaskCompletionSource.TrySetException(new IOException(Properties.Resources.ReadAsMimeMultipartErrorWriting, e)); } }
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)); }
private static void MoveNextPart(MultipartAsyncContext context) { Contract.Assert(context != null, "context cannot be null"); try { while (context.PartsEnumerator.MoveNext()) { context.SegmentsEnumerator = context.PartsEnumerator.Current.Segments.GetEnumerator(); if (MoveNextSegment(context)) { return; } } } catch (Exception e) { context.TaskCompletionSource.TrySetException(e); return; } // Read some more MultipartReadAsync(context); }
private static bool MoveNextSegment(MultipartAsyncContext context) { Contract.Assert(context != null, "context cannot be null"); if (context.SegmentsEnumerator.MoveNext()) { MultipartWriteSegmentAsync(context); return true; } else if (CheckPartCompletion(context.PartsEnumerator.Current, context.Result)) { // We are done parsing context.TaskCompletionSource.TrySetResult(context.Result); return true; } return false; }
private static void MultipartWriteSegmentAsync(MultipartAsyncContext context) { Contract.Assert(context != null, "context cannot be null."); Stream output = context.PartsEnumerator.Current.GetOutputStream(); ArraySegment<byte> segment = (ArraySegment<byte>)context.SegmentsEnumerator.Current; try { IAsyncResult result = output.BeginWrite(segment.Array, segment.Offset, segment.Count, _onMultipartWriteSegmentAsyncComplete, context); if (result.CompletedSynchronously) { MultipartWriteSegmentAsyncComplete(result); } } catch (Exception e) { context.PartsEnumerator.Current.Dispose(); context.TaskCompletionSource.TrySetException(new IOException(Properties.Resources.ReadAsMimeMultipartErrorWriting, e)); } }
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; }); }