1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.fileupload;
18
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertFalse;
21 import static org.junit.Assert.assertNull;
22 import static org.junit.Assert.assertTrue;
23 import static org.junit.jupiter.api.Assertions.assertThrows;
24
25 import java.io.ByteArrayOutputStream;
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.io.UnsupportedEncodingException;
29 import java.nio.charset.StandardCharsets;
30 import java.util.List;
31
32 import org.apache.commons.fileupload.disk.DiskFileItemFactory;
33 import org.apache.commons.fileupload.portlet.PortletFileUploadTest;
34 import org.apache.commons.fileupload.servlet.ServletFileUpload;
35 import org.apache.commons.fileupload.servlet.ServletFileUploadTest;
36 import org.apache.commons.fileupload.util.Streams;
37 import org.junit.Test;
38 import org.junit.runner.RunWith;
39 import org.junit.runners.Parameterized;
40 import org.junit.runners.Parameterized.Parameter;
41 import org.junit.runners.Parameterized.Parameters;
42
43
44
45
46
47
48
49
50
51
52 @RunWith(Parameterized.class)
53 public class FileUploadTest {
54
55
56
57
58 @Parameters(name = "{0}")
59 public static Iterable<? extends Object> data() {
60 return Util.fileUploadImplementations();
61 }
62
63
64
65
66 @Parameter
67 public FileUpload upload;
68
69 private void assertHeaders(final String[] headerNames, final String[] headerValues, final FileItem item, final int index) {
70 for (int i = 0; i < headerNames.length; i++) {
71 final String value = item.getHeaders().getHeader(headerNames[i]);
72 if (i == index) {
73 assertEquals(headerValues[i], value);
74 } else {
75 assertNull(value);
76 }
77 }
78 }
79
80
81
82
83 @Test
84 public void testContentTypeAttachment()
85 throws IOException, FileUploadException {
86 final List<FileItem> fileItems = Util.parseUpload(upload,
87 "-----1234\r\n" +
88 "content-disposition: form-data; name=\"field1\"\r\n" +
89 "\r\n" +
90 "Joe Blow\r\n" +
91 "-----1234\r\n" +
92 "content-disposition: form-data; name=\"pics\"\r\n" +
93 "Content-type: multipart/mixed, boundary=---9876\r\n" +
94 "\r\n" +
95 "-----9876\r\n" +
96 "Content-disposition: attachment; filename=\"file1.txt\"\r\n" +
97 "Content-Type: text/plain\r\n" +
98 "\r\n" +
99 "... contents of file1.txt ...\r\n" +
100 "-----9876--\r\n" +
101 "-----1234--\r\n");
102 assertEquals(2, fileItems.size());
103
104 final FileItem field = fileItems.get(0);
105 assertEquals("field1", field.getFieldName());
106 assertTrue(field.isFormField());
107 assertEquals("Joe Blow", field.getString());
108
109 final FileItem file = fileItems.get(1);
110 assertEquals("pics", file.getFieldName());
111 assertFalse(file.isFormField());
112 assertEquals("... contents of file1.txt ...", file.getString());
113 assertEquals("text/plain", file.getContentType());
114 assertEquals("file1.txt", file.getName());
115 }
116
117
118
119
120 @Test
121 public void testEmptyFile()
122 throws UnsupportedEncodingException, FileUploadException {
123 final List<FileItem> fileItems = Util.parseUpload (upload,
124 "-----1234\r\n" +
125 "Content-Disposition: form-data; name=\"file\"; filename=\"\"\r\n" +
126 "\r\n" +
127 "\r\n" +
128 "-----1234--\r\n");
129 assertEquals(1, fileItems.size());
130
131 final FileItem file = fileItems.get(0);
132 assertFalse(file.isFormField());
133 assertEquals("", file.getString());
134 assertEquals("", file.getName());
135 }
136
137 @Test
138 public void testFilenameCaseSensitivity()
139 throws IOException, FileUploadException {
140 final List<FileItem> fileItems = Util.parseUpload(upload,
141 "-----1234\r\n" +
142 "Content-Disposition: form-data; name=\"FiLe\"; filename=\"FOO.tab\"\r\n" +
143 "Content-Type: text/whatever\r\n" +
144 "\r\n" +
145 "This is the content of the file\n" +
146 "\r\n" +
147 "-----1234--\r\n");
148 assertEquals(1, fileItems.size());
149
150 final FileItem file = fileItems.get(0);
151 assertEquals("FiLe", file.getFieldName());
152 assertEquals("FOO.tab", file.getName());
153 }
154
155 @Test
156 public void testFileUpload()
157 throws IOException, FileUploadException {
158 final List<FileItem> fileItems = Util.parseUpload(upload,
159 "-----1234\r\n" +
160 "Content-Disposition: form-data; name=\"file\"; filename=\"foo.tab\"\r\n" +
161 "Content-Type: text/whatever\r\n" +
162 "\r\n" +
163 "This is the content of the file\n" +
164 "\r\n" +
165 "-----1234\r\n" +
166 "Content-Disposition: form-data; name=\"field\"\r\n" +
167 "\r\n" +
168 "fieldValue\r\n" +
169 "-----1234\r\n" +
170 "Content-Disposition: form-data; name=\"multi\"\r\n" +
171 "\r\n" +
172 "value1\r\n" +
173 "-----1234\r\n" +
174 "Content-Disposition: form-data; name=\"multi\"\r\n" +
175 "\r\n" +
176 "value2\r\n" +
177 "-----1234--\r\n");
178 assertEquals(4, fileItems.size());
179
180 final FileItem file = fileItems.get(0);
181 assertEquals("file", file.getFieldName());
182 assertFalse(file.isFormField());
183 assertEquals("This is the content of the file\n", file.getString());
184 assertEquals("text/whatever", file.getContentType());
185 assertEquals("foo.tab", file.getName());
186
187 final FileItem field = fileItems.get(1);
188 assertEquals("field", field.getFieldName());
189 assertTrue(field.isFormField());
190 assertEquals("fieldValue", field.getString());
191
192 final FileItem multi0 = fileItems.get(2);
193 assertEquals("multi", multi0.getFieldName());
194 assertTrue(multi0.isFormField());
195 assertEquals("value1", multi0.getString());
196
197 final FileItem multi1 = fileItems.get(3);
198 assertEquals("multi", multi1.getFieldName());
199 assertTrue(multi1.isFormField());
200 assertEquals("value2", multi1.getString());
201 }
202
203
204
205
206 @Test
207 public void testFileUpload130()
208 throws Exception {
209 final String[] headerNames = {
210 "SomeHeader", "OtherHeader", "YetAnotherHeader", "WhatAHeader"
211 };
212 final String[] headerValues = {
213 "present", "Is there", "Here", "Is That"
214 };
215 final List<FileItem> fileItems = Util.parseUpload(upload,
216 "-----1234\r\n" +
217 "Content-Disposition: form-data; name=\"file\"; filename=\"foo.tab\"\r\n" +
218 "Content-Type: text/whatever\r\n" +
219 headerNames[0] + ": " + headerValues[0] + "\r\n" +
220 "\r\n" +
221 "This is the content of the file\n" +
222 "\r\n" +
223 "-----1234\r\n" +
224 "Content-Disposition: form-data; \r\n" +
225 "\tname=\"field\"\r\n" +
226 headerNames[1] + ": " + headerValues[1] + "\r\n" +
227 "\r\n" +
228 "fieldValue\r\n" +
229 "-----1234\r\n" +
230 "Content-Disposition: form-data;\r\n" +
231 " name=\"multi\"\r\n" +
232 headerNames[2] + ": " + headerValues[2] + "\r\n" +
233 "\r\n" +
234 "value1\r\n" +
235 "-----1234\r\n" +
236 "Content-Disposition: form-data; name=\"multi\"\r\n" +
237 headerNames[3] + ": " + headerValues[3] + "\r\n" +
238 "\r\n" +
239 "value2\r\n" +
240 "-----1234--\r\n");
241 assertEquals(4, fileItems.size());
242
243 final FileItem file = fileItems.get(0);
244 assertHeaders(headerNames, headerValues, file, 0);
245
246 final FileItem field = fileItems.get(1);
247 assertHeaders(headerNames, headerValues, field, 1);
248
249 final FileItem multi0 = fileItems.get(2);
250 assertHeaders(headerNames, headerValues, multi0, 2);
251
252 final FileItem multi1 = fileItems.get(3);
253 assertHeaders(headerNames, headerValues, multi1, 3);
254 }
255
256
257
258
259 @Test
260 public void testFILEUPLOAD62() throws Exception {
261 final String contentType = "multipart/form-data; boundary=AaB03x";
262 final String request =
263 "--AaB03x\r\n" +
264 "content-disposition: form-data; name=\"field1\"\r\n" +
265 "\r\n" +
266 "Joe Blow\r\n" +
267 "--AaB03x\r\n" +
268 "content-disposition: form-data; name=\"pics\"\r\n" +
269 "Content-type: multipart/mixed; boundary=BbC04y\r\n" +
270 "\r\n" +
271 "--BbC04y\r\n" +
272 "Content-disposition: attachment; filename=\"file1.txt\"\r\n" +
273 "Content-Type: text/plain\r\n" +
274 "\r\n" +
275 "... contents of file1.txt ...\r\n" +
276 "--BbC04y\r\n" +
277 "Content-disposition: attachment; filename=\"file2.gif\"\r\n" +
278 "Content-type: image/gif\r\n" +
279 "Content-Transfer-Encoding: binary\r\n" +
280 "\r\n" +
281 "...contents of file2.gif...\r\n" +
282 "--BbC04y--\r\n" +
283 "--AaB03x--";
284 final List<FileItem> fileItems = Util.parseUpload(upload, request.getBytes("US-ASCII"), contentType);
285 assertEquals(3, fileItems.size());
286 final FileItem item0 = fileItems.get(0);
287 assertEquals("field1", item0.getFieldName());
288 assertNull(item0.getName());
289 assertEquals("Joe Blow", new String(item0.get()));
290 final FileItem item1 = fileItems.get(1);
291 assertEquals("pics", item1.getFieldName());
292 assertEquals("file1.txt", item1.getName());
293 assertEquals("... contents of file1.txt ...", new String(item1.get()));
294 final FileItem item2 = fileItems.get(2);
295 assertEquals("pics", item2.getFieldName());
296 assertEquals("file2.gif", item2.getName());
297 assertEquals("...contents of file2.gif...", new String(item2.get()));
298 }
299
300
301
302
303 @Test
304 public void testFoldedHeaders()
305 throws IOException, FileUploadException {
306 final List<FileItem> fileItems = Util.parseUpload(upload, "-----1234\r\n" +
307 "Content-Disposition: form-data; name=\"file\"; filename=\"foo.tab\"\r\n" +
308 "Content-Type: text/whatever\r\n" +
309 "\r\n" +
310 "This is the content of the file\n" +
311 "\r\n" +
312 "-----1234\r\n" +
313 "Content-Disposition: form-data; \r\n" +
314 "\tname=\"field\"\r\n" +
315 "\r\n" +
316 "fieldValue\r\n" +
317 "-----1234\r\n" +
318 "Content-Disposition: form-data;\r\n" +
319 " name=\"multi\"\r\n" +
320 "\r\n" +
321 "value1\r\n" +
322 "-----1234\r\n" +
323 "Content-Disposition: form-data; name=\"multi\"\r\n" +
324 "\r\n" +
325 "value2\r\n" +
326 "-----1234--\r\n");
327 assertEquals(4, fileItems.size());
328
329 final FileItem file = fileItems.get(0);
330 assertEquals("file", file.getFieldName());
331 assertFalse(file.isFormField());
332 assertEquals("This is the content of the file\n", file.getString());
333 assertEquals("text/whatever", file.getContentType());
334 assertEquals("foo.tab", file.getName());
335
336 final FileItem field = fileItems.get(1);
337 assertEquals("field", field.getFieldName());
338 assertTrue(field.isFormField());
339 assertEquals("fieldValue", field.getString());
340
341 final FileItem multi0 = fileItems.get(2);
342 assertEquals("multi", multi0.getFieldName());
343 assertTrue(multi0.isFormField());
344 assertEquals("value1", multi0.getString());
345
346 final FileItem multi1 = fileItems.get(3);
347 assertEquals("multi", multi1.getFieldName());
348 assertTrue(multi1.isFormField());
349 assertEquals("value2", multi1.getString());
350 }
351
352
353
354
355
356
357 @Test
358 public void testIE5MacBug()
359 throws UnsupportedEncodingException, FileUploadException {
360 final List<FileItem> fileItems = Util.parseUpload(upload,
361 "-----1234\r\n" +
362 "Content-Disposition: form-data; name=\"field1\"\r\n" +
363 "\r\n" +
364 "fieldValue\r\n" +
365 "-----1234\n" +
366 "Content-Disposition: form-data; name=\"submitName.x\"\r\n" +
367 "\r\n" +
368 "42\r\n" +
369 "-----1234\n" +
370 "Content-Disposition: form-data; name=\"submitName.y\"\r\n" +
371 "\r\n" +
372 "21\r\n" +
373 "-----1234\r\n" +
374 "Content-Disposition: form-data; name=\"field2\"\r\n" +
375 "\r\n" +
376 "fieldValue2\r\n" +
377 "-----1234--\r\n");
378
379 assertEquals(4, fileItems.size());
380
381 final FileItem field1 = fileItems.get(0);
382 assertEquals("field1", field1.getFieldName());
383 assertTrue(field1.isFormField());
384 assertEquals("fieldValue", field1.getString());
385
386 final FileItem submitX = fileItems.get(1);
387 assertEquals("submitName.x", submitX.getFieldName());
388 assertTrue(submitX.isFormField());
389 assertEquals("42", submitX.getString());
390
391 final FileItem submitY = fileItems.get(2);
392 assertEquals("submitName.y", submitY.getFieldName());
393 assertTrue(submitY.isFormField());
394 assertEquals("21", submitY.getString());
395
396 final FileItem field2 = fileItems.get(3);
397 assertEquals("field2", field2.getFieldName());
398 assertTrue(field2.isFormField());
399 assertEquals("fieldValue2", field2.getString());
400 }
401
402
403
404
405
406 @Test
407 public void testMultipartRelated() throws FileUploadException {
408 final String soapEnvelope =
409 "<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\">\r\n" +
410 " <soap:Header></soap:Header>\r\n" +
411 " <soap:Body>\r\n" +
412 " <ns1:Test xmlns:ns1=\"http://www.test.org/some-test-namespace\">\r\n" +
413 " <ns1:Attachment>\r\n" +
414 " <xop:Include xmlns:xop=\"http://www.w3.org/2004/08/xop/include\"" +
415 " href=\"ref-to-attachment%40some.domain.org\"/>\r\n" +
416 " </ns1:Attachment>\r\n" +
417 " </ns1:Test>\r\n" +
418 " </soap:Body>\r\n" +
419 "</soap:Envelope>";
420
421 final String content = "-----1234\r\n" +
422 "content-type: application/xop+xml; type=\"application/soap+xml\"\r\n" +
423 "\r\n" +
424 soapEnvelope + "\r\n" +
425 "-----1234\r\n" +
426 "Content-type: text/plain\r\n" +
427 "content-id: <ref-to-attachment@some.domain.org>\r\n" +
428 "\r\n" +
429 "some text/plain content\r\n" +
430 "-----1234--\r\n";
431
432 final List<FileItem> fileItems = Util.parseUpload(upload, content.getBytes(StandardCharsets.US_ASCII),
433 "multipart/related; boundary=---1234;" +
434 " type=\"application/xop+xml\"; start-info=\"application/soap+xml\"");
435 assertEquals(2, fileItems.size());
436
437 final FileItem part1 = fileItems.get(0);
438 assertNull(part1.getFieldName());
439 assertFalse(part1.isFormField());
440 assertEquals(soapEnvelope, part1.getString());
441
442 final FileItem part2 = fileItems.get(1);
443 assertNull(part2.getFieldName());
444 assertFalse(part2.isFormField());
445 assertEquals("some text/plain content", part2.getString());
446 assertEquals("text/plain", part2.getContentType());
447 assertNull(part2.getName());
448 }
449
450
451 @Test
452 public void testOpenStreamSecondCall() throws IOException, FileUploadException {
453 final String request =
454 "-----1234\r\n" +
455 "Content-Disposition: form-data; name=\"file1\"; filename=\"foo1.tab\"\r\n" +
456 "Content-Type: text/whatever\r\n" +
457 "Content-Length: 10\r\n" +
458 "\r\n" +
459 "This is the content of the file\n" +
460 "\r\n" +
461 "-----1234--\r\n";
462
463 final ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory());
464 upload.setFileSizeMax(-1);
465 upload.setSizeMax(300);
466
467
468
469
470
471 final MockHttpServletRequest req = new MockHttpServletRequest(
472 request.getBytes("US-ASCII"), Constants.CONTENT_TYPE);
473 req.setContentLength(-1);
474 req.setReadLimit(10);
475
476 final FileItemIterator it = upload.getItemIterator(req);
477 assertTrue(it.hasNext());
478
479 final FileItemStream item = it.next();
480 assertFalse(item.isFormField());
481 assertEquals("file1", item.getFieldName());
482 assertEquals("foo1.tab", item.getName());
483
484 try (InputStream stream = item.openStream()) {
485 final ByteArrayOutputStream baos = new ByteArrayOutputStream();
486 Streams.copy(stream, baos, true);
487 }
488
489 assertThrows(IOException.class, item::openStream, "Attempt to open a closed stream did not throw an exception");
490
491 assertFalse(it.hasNext());
492 }
493 }