// 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.IO; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Features; using Microsoft.AspNet.Mvc.Core; using Microsoft.Framework.Internal; using Microsoft.Net.Http.Headers; namespace Microsoft.AspNet.Mvc { /// /// A on execution will write a file from disk to the response /// using mechanisms provided by the host. /// public class PhysicalFileProviderResult : FileResult { private const int DefaultBufferSize = 0x1000; private string _fileName; /// /// Creates a new instance with /// the provided and the provided . /// /// The path to the file. The path must be an absolute path. /// The Content-Type header of the response. public PhysicalFileProviderResult([NotNull] string fileName, [NotNull] string contentType) : this(fileName, new MediaTypeHeaderValue(contentType)) { } /// /// Creates a new instance with /// the provided and the provided . /// /// The path to the file. The path must be an absolute path. /// The Content-Type header of the response. public PhysicalFileProviderResult([NotNull] string fileName, [NotNull] MediaTypeHeaderValue contentType) : base(contentType) { FileName = fileName; } /// /// Gets or sets the path to the file that will be sent back as the response. /// public string FileName { get { return _fileName; } [param: NotNull] set { _fileName = value; } } /// protected override async Task WriteFileAsync(HttpResponse response, CancellationToken cancellation) { if (!Path.IsPathRooted(FileName)) { throw new FileNotFoundException(Resources.FormatFileResult_InvalidPath(FileName), FileName); } var sendFile = response.HttpContext.Features.Get(); if (sendFile != null) { await sendFile.SendFileAsync( FileName, offset: 0, length: null, cancellation: cancellation); return; } else { var fileStream = GetFileStream(FileName); using (fileStream) { await fileStream.CopyToAsync(response.Body, DefaultBufferSize, cancellation); } return; } } /// /// Returns for the specified . /// /// The path for which the is needed. /// for the specified . protected virtual Stream GetFileStream([NotNull]string path) { return new FileStream( path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, DefaultBufferSize, FileOptions.Asynchronous | FileOptions.SequentialScan); } } }