Use filename* for files in multipart forms when available #651

This commit is contained in:
John Luo 2016-06-29 11:14:27 -07:00
parent 3c0c02112d
commit 4986137ffe
2 changed files with 61 additions and 1 deletions

View File

@ -181,7 +181,9 @@ namespace Microsoft.AspNetCore.Http.Features
await section.Body.DrainAsync(cancellationToken);
var name = HeaderUtilities.RemoveQuotes(contentDisposition.Name) ?? string.Empty;
var fileName = HeaderUtilities.RemoveQuotes(contentDisposition.FileName) ?? string.Empty;
var fileName = HeaderUtilities.RemoveQuotes(contentDisposition.FileNameStar) ??
HeaderUtilities.RemoveQuotes(contentDisposition.FileName) ??
string.Empty;
FormFile file;
if (section.BaseStreamOffset.HasValue)

View File

@ -63,6 +63,12 @@ namespace Microsoft.AspNetCore.Http.Features
"Content-Disposition: form-data; name=\"myfile1\"; filename=\"temp.html\"\r\n" +
"Content-Type: text/html\r\n" +
"\r\n" +
"<html><body>Hello World</body></html>\r\n";
private const string MultipartFormEncodedFilename = "--WebKitFormBoundary5pDRpGheQXaM8k3T\r\n" +
"Content-Disposition: form-data; name=\"myfile1\"; filename=\"temp.html\"; filename*=utf-8\'\'t%c3%a9mp.html\r\n" +
"Content-Type: text/html\r\n" +
"\r\n" +
"<html><body>Hello World</body></html>\r\n";
private const string MultipartFormWithField =
@ -78,6 +84,10 @@ namespace Microsoft.AspNetCore.Http.Features
MultipartFormFile +
MultipartFormEnd;
private const string MultipartFormWithEncodedFilename =
MultipartFormEncodedFilename +
MultipartFormEnd;
[Theory]
[InlineData(true)]
[InlineData(false)]
@ -198,6 +208,54 @@ namespace Microsoft.AspNetCore.Http.Features
await responseFeature.CompleteAsync();
}
[Theory]
[InlineData(true)]
[InlineData(false)]
public async Task ReadFormAsync_MultipartWithEncodedFilename_ReturnsParsedFormCollection(bool bufferRequest)
{
var formContent = Encoding.UTF8.GetBytes(MultipartFormWithEncodedFilename);
var context = new DefaultHttpContext();
var responseFeature = new FakeResponseFeature();
context.Features.Set<IHttpResponseFeature>(responseFeature);
context.Request.ContentType = MultipartContentType;
context.Request.Body = new NonSeekableReadStream(formContent);
IFormFeature formFeature = new FormFeature(context.Request, new FormOptions() { BufferBody = bufferRequest });
context.Features.Set<IFormFeature>(formFeature);
var formCollection = await context.Request.ReadFormAsync();
Assert.NotNull(formCollection);
// Cached
formFeature = context.Features.Get<IFormFeature>();
Assert.NotNull(formFeature);
Assert.NotNull(formFeature.Form);
Assert.Same(formFeature.Form, formCollection);
Assert.Same(formCollection, context.Request.Form);
// Content
Assert.Equal(0, formCollection.Count);
Assert.NotNull(formCollection.Files);
Assert.Equal(1, formCollection.Files.Count);
var file = formCollection.Files["myfile1"];
Assert.Equal("myfile1", file.Name);
Assert.Equal("t\u00e9mp.html", file.FileName);
Assert.Equal("text/html", file.ContentType);
Assert.Equal(@"form-data; name=""myfile1""; filename=""temp.html""; filename*=utf-8''t%c3%a9mp.html", file.ContentDisposition);
var body = file.OpenReadStream();
using (var reader = new StreamReader(body))
{
Assert.True(body.CanSeek);
var content = reader.ReadToEnd();
Assert.Equal(content, "<html><body>Hello World</body></html>");
}
await responseFeature.CompleteAsync();
}
[Theory]
[InlineData(true)]
[InlineData(false)]