@@ -63,6 +63,12 @@ public async Task ReadFormAsync_SimpleData_ReturnsParsedFormCollection(bool buff
63
63
"Content-Disposition: form-data; name=\" myfile1\" ; filename=\" temp.html\" \r \n " +
64
64
"Content-Type: text/html\r \n " +
65
65
"\r \n " +
66
+ "<html><body>Hello World</body></html>\r \n " ;
67
+
68
+ private const string MultipartFormEncodedFilename = "--WebKitFormBoundary5pDRpGheQXaM8k3T\r \n " +
69
+ "Content-Disposition: form-data; name=\" myfile1\" ; filename=\" temp.html\" ; filename*=utf-8\' \' t%c3%a9mp.html\r \n " +
70
+ "Content-Type: text/html\r \n " +
71
+ "\r \n " +
66
72
"<html><body>Hello World</body></html>\r \n " ;
67
73
68
74
private const string MultipartFormWithField =
@@ -78,6 +84,10 @@ public async Task ReadFormAsync_SimpleData_ReturnsParsedFormCollection(bool buff
78
84
MultipartFormFile +
79
85
MultipartFormEnd ;
80
86
87
+ private const string MultipartFormWithEncodedFilename =
88
+ MultipartFormEncodedFilename +
89
+ MultipartFormEnd ;
90
+
81
91
[ Theory ]
82
92
[ InlineData ( true ) ]
83
93
[ InlineData ( false ) ]
@@ -198,6 +208,54 @@ public async Task ReadFormAsync_MultipartWithFile_ReturnsParsedFormCollection(bo
198
208
await responseFeature . CompleteAsync ( ) ;
199
209
}
200
210
211
+ [ Theory ]
212
+ [ InlineData ( true ) ]
213
+ [ InlineData ( false ) ]
214
+ public async Task ReadFormAsync_MultipartWithEncodedFilename_ReturnsParsedFormCollection ( bool bufferRequest )
215
+ {
216
+ var formContent = Encoding . UTF8 . GetBytes ( MultipartFormWithEncodedFilename ) ;
217
+ var context = new DefaultHttpContext ( ) ;
218
+ var responseFeature = new FakeResponseFeature ( ) ;
219
+ context . Features . Set < IHttpResponseFeature > ( responseFeature ) ;
220
+ context . Request . ContentType = MultipartContentType ;
221
+ context . Request . Body = new NonSeekableReadStream ( formContent ) ;
222
+
223
+ IFormFeature formFeature = new FormFeature ( context . Request , new FormOptions ( ) { BufferBody = bufferRequest } ) ;
224
+ context . Features . Set < IFormFeature > ( formFeature ) ;
225
+
226
+ var formCollection = await context . Request . ReadFormAsync ( ) ;
227
+
228
+ Assert . NotNull ( formCollection ) ;
229
+
230
+ // Cached
231
+ formFeature = context . Features . Get < IFormFeature > ( ) ;
232
+ Assert . NotNull ( formFeature ) ;
233
+ Assert . NotNull ( formFeature . Form ) ;
234
+ Assert . Same ( formFeature . Form , formCollection ) ;
235
+ Assert . Same ( formCollection , context . Request . Form ) ;
236
+
237
+ // Content
238
+ Assert . Equal ( 0 , formCollection . Count ) ;
239
+
240
+ Assert . NotNull ( formCollection . Files ) ;
241
+ Assert . Equal ( 1 , formCollection . Files . Count ) ;
242
+
243
+ var file = formCollection . Files [ "myfile1" ] ;
244
+ Assert . Equal ( "myfile1" , file . Name ) ;
245
+ Assert . Equal ( "t\u00e9 mp.html" , file . FileName ) ;
246
+ Assert . Equal ( "text/html" , file . ContentType ) ;
247
+ Assert . Equal ( @"form-data; name=""myfile1""; filename=""temp.html""; filename*=utf-8''t%c3%a9mp.html" , file . ContentDisposition ) ;
248
+ var body = file . OpenReadStream ( ) ;
249
+ using ( var reader = new StreamReader ( body ) )
250
+ {
251
+ Assert . True ( body . CanSeek ) ;
252
+ var content = reader . ReadToEnd ( ) ;
253
+ Assert . Equal ( content , "<html><body>Hello World</body></html>" ) ;
254
+ }
255
+
256
+ await responseFeature . CompleteAsync ( ) ;
257
+ }
258
+
201
259
[ Theory ]
202
260
[ InlineData ( true ) ]
203
261
[ InlineData ( false ) ]
0 commit comments