From c2e7618d9a7448493b96f5a301b3a7ccf1dc7fe7 Mon Sep 17 00:00:00 2001 From: Kristian Hellang Date: Fri, 4 Dec 2015 12:20:15 +0100 Subject: [PATCH] Added Name and FileName to IFormFile This commits also gets rid of the name closure in FormFileCollection by interating over the files in the collection instead of using Find and FindAll. Closes #352 and #499 --- .../IFormFile.cs | 4 +++ .../Features/FormFeature.cs | 5 ++- .../Features/FormFile.cs | 22 ++++++------ .../FormFileCollection.cs | 35 +++++++++++-------- .../FormFeatureTests.cs | 2 ++ 5 files changed, 43 insertions(+), 25 deletions(-) diff --git a/src/Microsoft.AspNet.Http.Abstractions/IFormFile.cs b/src/Microsoft.AspNet.Http.Abstractions/IFormFile.cs index 6f8fdaa2..b5e44904 100644 --- a/src/Microsoft.AspNet.Http.Abstractions/IFormFile.cs +++ b/src/Microsoft.AspNet.Http.Abstractions/IFormFile.cs @@ -18,6 +18,10 @@ public interface IFormFile long Length { get; } + string Name { get; } + + string FileName { get; } + Stream OpenReadStream(); } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Http/Features/FormFeature.cs b/src/Microsoft.AspNet.Http/Features/FormFeature.cs index f3ed68e3..198924ba 100644 --- a/src/Microsoft.AspNet.Http/Features/FormFeature.cs +++ b/src/Microsoft.AspNet.Http/Features/FormFeature.cs @@ -149,7 +149,10 @@ private async Task InnerReadFormAsync(CancellationToken cancell // Find the end await section.Body.DrainAsync(cancellationToken); - var file = new FormFile(_request.Body, section.BaseStreamOffset.Value, section.Body.Length) + var name = HeaderUtilities.RemoveQuotes(contentDisposition.Name) ?? string.Empty; + var fileName = HeaderUtilities.RemoveQuotes(contentDisposition.FileName) ?? string.Empty; + + var file = new FormFile(_request.Body, section.BaseStreamOffset.Value, section.Body.Length, name, fileName) { Headers = new HeaderDictionary(section.Headers), }; diff --git a/src/Microsoft.AspNet.Http/Features/FormFile.cs b/src/Microsoft.AspNet.Http/Features/FormFile.cs index 557dc9d5..3fc51136 100644 --- a/src/Microsoft.AspNet.Http/Features/FormFile.cs +++ b/src/Microsoft.AspNet.Http/Features/FormFile.cs @@ -8,15 +8,16 @@ namespace Microsoft.AspNet.Http.Features.Internal { public class FormFile : IFormFile { - private Stream _baseStream; - private long _baseStreamOffset; - private long _length; + private readonly Stream _baseStream; + private readonly long _baseStreamOffset; - public FormFile(Stream baseStream, long baseStreamOffset, long length) + public FormFile(Stream baseStream, long baseStreamOffset, long length, string name, string fileName) { _baseStream = baseStream; _baseStreamOffset = baseStreamOffset; - _length = length; + Length = length; + Name = name; + FileName = fileName; } public string ContentDisposition @@ -33,14 +34,15 @@ public string ContentType public IHeaderDictionary Headers { get; set; } - public long Length - { - get { return _length; } - } + public long Length { get; } + + public string Name { get; } + + public string FileName { get; } public Stream OpenReadStream() { - return new ReferenceReadStream(_baseStream, _baseStreamOffset, _length); + return new ReferenceReadStream(_baseStream, _baseStreamOffset, Length); } } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Http/FormFileCollection.cs b/src/Microsoft.AspNet.Http/FormFileCollection.cs index 43dbf0cb..b7b3ee8e 100644 --- a/src/Microsoft.AspNet.Http/FormFileCollection.cs +++ b/src/Microsoft.AspNet.Http/FormFileCollection.cs @@ -1,34 +1,41 @@ // 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; using System.Collections.Generic; -using Microsoft.Net.Http.Headers; namespace Microsoft.AspNet.Http.Internal { public class FormFileCollection : List, IFormFileCollection { - public IFormFile this[string name] - { - get { return GetFile(name); } - } + public IFormFile this[string name] => GetFile(name); public IFormFile GetFile(string name) { - return Find(file => string.Equals(name, GetName(file.ContentDisposition))); + foreach (var file in this) + { + if (string.Equals(name, file.Name, StringComparison.OrdinalIgnoreCase)) + { + return file; + } + } + + return null; } public IReadOnlyList GetFiles(string name) { - return FindAll(file => string.Equals(name, GetName(file.ContentDisposition))); - } + var files = new List(); - private static string GetName(string contentDisposition) - { - // Content-Disposition: form-data; name="myfile1"; filename="Misc 002.jpg" - ContentDispositionHeaderValue cd; - ContentDispositionHeaderValue.TryParse(contentDisposition, out cd); - return HeaderUtilities.RemoveQuotes(cd?.Name); + foreach (var file in this) + { + if (string.Equals(name, file.Name, StringComparison.OrdinalIgnoreCase)) + { + files.Add(file); + } + } + + return files; } } } \ No newline at end of file diff --git a/test/Microsoft.AspNet.Http.Tests/FormFeatureTests.cs b/test/Microsoft.AspNet.Http.Tests/FormFeatureTests.cs index 4580ac9e..7d7cafc5 100644 --- a/test/Microsoft.AspNet.Http.Tests/FormFeatureTests.cs +++ b/test/Microsoft.AspNet.Http.Tests/FormFeatureTests.cs @@ -215,6 +215,8 @@ public async Task ReadFormAsync_MultipartWithFile_ReturnsParsedFormCollection() Assert.Equal(1, formCollection.Files.Count); var file = formCollection.Files["myfile1"]; + Assert.Equal("myfile1", file.Name); + Assert.Equal("temp.html", file.FileName); Assert.Equal("text/html", file.ContentType); Assert.Equal(@"form-data; name=""myfile1""; filename=""temp.html""", file.ContentDisposition); var body = file.OpenReadStream();