// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Collections.Specialized; using System.IO; using System.Net.Http.Formatting.Internal; using System.Net.Http.Headers; using System.Threading; using System.Threading.Tasks; namespace System.Net.Http { /// /// A implementation suited for use with HTML file uploads for writing file /// content to a . The stream provider looks at the Content-Disposition header /// field and determines an output based on the presence of a filename parameter. /// If a filename parameter is present in the Content-Disposition header field then the body /// part is written to a , otherwise it is written to a . /// This makes it convenient to process MIME Multipart HTML Form data which is a combination of form /// data and file content. /// public class MultipartFormDataStreamProvider : MultipartFileStreamProvider { // pass around cancellation token through field to maintain backward compat. private CancellationToken _cancellationToken; /// /// Initializes a new instance of the class. /// /// The root path where the content of MIME multipart body parts are written to. public MultipartFormDataStreamProvider(string rootPath) : base(rootPath) { FormData = HttpValueCollection.Create(); } /// /// Initializes a new instance of the class. /// /// The root path where the content of MIME multipart body parts are written to. /// The number of bytes buffered for writes to the file. public MultipartFormDataStreamProvider(string rootPath, int bufferSize) : base(rootPath, bufferSize) { FormData = HttpValueCollection.Create(); } /// /// Gets a of form data passed as part of the multipart form data. /// public NameValueCollection FormData { get; private set; } /// /// This body part stream provider examines the headers provided by the MIME multipart parser /// and decides whether it should return a file stream or a memory stream for the body part to be /// written to. /// /// The parent MIME multipart HttpContent instance. /// Header fields describing the body part /// The instance where the message body part is written to. public override Stream GetStream(HttpContent parent, HttpContentHeaders headers) { if (MultipartFormDataStreamProviderHelper.IsFileContent(parent, headers)) { return base.GetStream(parent, headers); } return new MemoryStream(); } /// /// Read the non-file contents as form data. /// /// A representing the post processing. public override Task ExecutePostProcessingAsync() { // This method predates support for cancellation, and we need to make sure it is always invoked when // ExecutePostProcessingAsync is called for compatability. return MultipartFormDataStreamProviderHelper.ReadFormDataAsync(Contents, FormData, _cancellationToken); } /// /// Read the non-file contents as form data. /// /// The token to monitor for cancellation requests. /// A representing the post processing. public override Task ExecutePostProcessingAsync(CancellationToken cancellationToken) { _cancellationToken = cancellationToken; return ExecutePostProcessingAsync(); } } }