View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
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  
24  import java.io.IOException;
25  import java.io.UnsupportedEncodingException;
26  import java.util.List;
27  
28  import org.apache.commons.fileupload.portlet.PortletFileUploadTest;
29  import org.apache.commons.fileupload.servlet.ServletFileUploadTest;
30  import org.junit.Test;
31  import org.junit.runner.RunWith;
32  import org.junit.runners.Parameterized;
33  import org.junit.runners.Parameterized.Parameter;
34  import org.junit.runners.Parameterized.Parameters;
35  
36  /**
37   * Common tests for implementations of {@link FileUpload}. This is a parameterized test.
38   * Tests must be valid and common to all implementations of FileUpload added as parameter
39   * in this class.
40   *
41   * @see ServletFileUploadTest
42   * @see PortletFileUploadTest
43   * @since 1.4
44   */
45  @RunWith(Parameterized.class)
46  public class FileUploadTest {
47  
48      /**
49       * @return {@link FileUpload} classes under test.
50       */
51      @Parameters(name="{0}")
52      public static Iterable<? extends Object> data() {
53          return Util.fileUploadImplementations();
54      }
55  
56      /**
57       * Current parameterized FileUpload.
58       */
59      @Parameter
60      public FileUpload upload;
61  
62      // --- Test methods common to all implementations of a FileUpload
63  
64      @Test
65      public void testFileUpload()
66              throws IOException, FileUploadException {
67          List<FileItem> fileItems = Util.parseUpload(upload,
68                                                 "-----1234\r\n" +
69                                                 "Content-Disposition: form-data; name=\"file\"; filename=\"foo.tab\"\r\n" +
70                                                 "Content-Type: text/whatever\r\n" +
71                                                 "\r\n" +
72                                                 "This is the content of the file\n" +
73                                                 "\r\n" +
74                                                 "-----1234\r\n" +
75                                                 "Content-Disposition: form-data; name=\"field\"\r\n" +
76                                                 "\r\n" +
77                                                 "fieldValue\r\n" +
78                                                 "-----1234\r\n" +
79                                                 "Content-Disposition: form-data; name=\"multi\"\r\n" +
80                                                 "\r\n" +
81                                                 "value1\r\n" +
82                                                 "-----1234\r\n" +
83                                                 "Content-Disposition: form-data; name=\"multi\"\r\n" +
84                                                 "\r\n" +
85                                                 "value2\r\n" +
86                                                 "-----1234--\r\n");
87          assertEquals(4, fileItems.size());
88  
89          FileItem file = fileItems.get(0);
90          assertEquals("file", file.getFieldName());
91          assertFalse(file.isFormField());
92          assertEquals("This is the content of the file\n", file.getString());
93          assertEquals("text/whatever", file.getContentType());
94          assertEquals("foo.tab", file.getName());
95  
96          FileItem field = fileItems.get(1);
97          assertEquals("field", field.getFieldName());
98          assertTrue(field.isFormField());
99          assertEquals("fieldValue", field.getString());
100 
101         FileItem multi0 = fileItems.get(2);
102         assertEquals("multi", multi0.getFieldName());
103         assertTrue(multi0.isFormField());
104         assertEquals("value1", multi0.getString());
105 
106         FileItem multi1 = fileItems.get(3);
107         assertEquals("multi", multi1.getFieldName());
108         assertTrue(multi1.isFormField());
109         assertEquals("value2", multi1.getString());
110     }
111 
112     @Test
113     public void testFilenameCaseSensitivity()
114             throws IOException, FileUploadException {
115         List<FileItem> fileItems = Util.parseUpload(upload,
116                                                "-----1234\r\n" +
117                                                "Content-Disposition: form-data; name=\"FiLe\"; filename=\"FOO.tab\"\r\n" +
118                                                "Content-Type: text/whatever\r\n" +
119                                                "\r\n" +
120                                                "This is the content of the file\n" +
121                                                "\r\n" +
122                                                "-----1234--\r\n");
123         assertEquals(1, fileItems.size());
124 
125         FileItem file = fileItems.get(0);
126         assertEquals("FiLe", file.getFieldName());
127         assertEquals("FOO.tab", file.getName());
128     }
129 
130     /**
131      * This is what the browser does if you submit the form without choosing a file.
132      */
133     @Test
134     public void testEmptyFile()
135             throws UnsupportedEncodingException, FileUploadException {
136         List<FileItem> fileItems = Util.parseUpload (upload,
137                                                 "-----1234\r\n" +
138                                                 "Content-Disposition: form-data; name=\"file\"; filename=\"\"\r\n" +
139                                                 "\r\n" +
140                                                 "\r\n" +
141                                                 "-----1234--\r\n");
142         assertEquals(1, fileItems.size());
143 
144         FileItem file = fileItems.get(0);
145         assertFalse(file.isFormField());
146         assertEquals("", file.getString());
147         assertEquals("", file.getName());
148     }
149 
150     /**
151      * Internet Explorer 5 for the Mac has a bug where the carriage
152      * return is missing on any boundary line immediately preceding
153      * an input with type=image. (type=submit does not have the bug.)
154      */
155     @Test
156     public void testIE5MacBug()
157             throws UnsupportedEncodingException, FileUploadException {
158         List<FileItem> fileItems = Util.parseUpload(upload,
159                                                "-----1234\r\n" +
160                                                "Content-Disposition: form-data; name=\"field1\"\r\n" +
161                                                "\r\n" +
162                                                "fieldValue\r\n" +
163                                                "-----1234\n" + // NOTE \r missing
164                                                "Content-Disposition: form-data; name=\"submitName.x\"\r\n" +
165                                                "\r\n" +
166                                                "42\r\n" +
167                                                "-----1234\n" + // NOTE \r missing
168                                                "Content-Disposition: form-data; name=\"submitName.y\"\r\n" +
169                                                "\r\n" +
170                                                "21\r\n" +
171                                                "-----1234\r\n" +
172                                                "Content-Disposition: form-data; name=\"field2\"\r\n" +
173                                                "\r\n" +
174                                                "fieldValue2\r\n" +
175                                                "-----1234--\r\n");
176 
177         assertEquals(4, fileItems.size());
178 
179         FileItem field1 = fileItems.get(0);
180         assertEquals("field1", field1.getFieldName());
181         assertTrue(field1.isFormField());
182         assertEquals("fieldValue", field1.getString());
183 
184         FileItem submitX = fileItems.get(1);
185         assertEquals("submitName.x", submitX.getFieldName());
186         assertTrue(submitX.isFormField());
187         assertEquals("42", submitX.getString());
188 
189         FileItem submitY = fileItems.get(2);
190         assertEquals("submitName.y", submitY.getFieldName());
191         assertTrue(submitY.isFormField());
192         assertEquals("21", submitY.getString());
193 
194         FileItem field2 = fileItems.get(3);
195         assertEquals("field2", field2.getFieldName());
196         assertTrue(field2.isFormField());
197         assertEquals("fieldValue2", field2.getString());
198     }
199 
200     /**
201      * Test for <a href="http://issues.apache.org/jira/browse/FILEUPLOAD-62">FILEUPLOAD-62</a>
202      */
203     @Test
204     public void testFILEUPLOAD62() throws Exception {
205         final String contentType = "multipart/form-data; boundary=AaB03x";
206         final String request =
207             "--AaB03x\r\n" +
208             "content-disposition: form-data; name=\"field1\"\r\n" +
209             "\r\n" +
210             "Joe Blow\r\n" +
211             "--AaB03x\r\n" +
212             "content-disposition: form-data; name=\"pics\"\r\n" +
213             "Content-type: multipart/mixed; boundary=BbC04y\r\n" +
214             "\r\n" +
215             "--BbC04y\r\n" +
216             "Content-disposition: attachment; filename=\"file1.txt\"\r\n" +
217             "Content-Type: text/plain\r\n" +
218             "\r\n" +
219             "... contents of file1.txt ...\r\n" +
220             "--BbC04y\r\n" +
221             "Content-disposition: attachment; filename=\"file2.gif\"\r\n" +
222             "Content-type: image/gif\r\n" +
223             "Content-Transfer-Encoding: binary\r\n" +
224             "\r\n" +
225             "...contents of file2.gif...\r\n" +
226             "--BbC04y--\r\n" +
227             "--AaB03x--";
228         List<FileItem> fileItems = Util.parseUpload(upload, request.getBytes("US-ASCII"), contentType);
229         assertEquals(3, fileItems.size());
230         FileItem item0 = fileItems.get(0);
231         assertEquals("field1", item0.getFieldName());
232         assertNull(item0.getName());
233         assertEquals("Joe Blow", new String(item0.get()));
234         FileItem item1 = fileItems.get(1);
235         assertEquals("pics", item1.getFieldName());
236         assertEquals("file1.txt", item1.getName());
237         assertEquals("... contents of file1.txt ...", new String(item1.get()));
238         FileItem item2 = fileItems.get(2);
239         assertEquals("pics", item2.getFieldName());
240         assertEquals("file2.gif", item2.getName());
241         assertEquals("...contents of file2.gif...", new String(item2.get()));
242     }
243 
244     /**
245      * Test for <a href="http://issues.apache.org/jira/browse/FILEUPLOAD-111">FILEUPLOAD-111</a>
246      */
247     @Test
248     public void testFoldedHeaders()
249             throws IOException, FileUploadException {
250         List<FileItem> fileItems = Util.parseUpload(upload, "-----1234\r\n" +
251                 "Content-Disposition: form-data; name=\"file\"; filename=\"foo.tab\"\r\n" +
252                 "Content-Type: text/whatever\r\n" +
253                 "\r\n" +
254                 "This is the content of the file\n" +
255                 "\r\n" +
256                 "-----1234\r\n" +
257                 "Content-Disposition: form-data; \r\n" +
258                 "\tname=\"field\"\r\n" +
259                 "\r\n" +
260                 "fieldValue\r\n" +
261                 "-----1234\r\n" +
262                 "Content-Disposition: form-data;\r\n" +
263                 "     name=\"multi\"\r\n" +
264                 "\r\n" +
265                 "value1\r\n" +
266                 "-----1234\r\n" +
267                 "Content-Disposition: form-data; name=\"multi\"\r\n" +
268                 "\r\n" +
269                 "value2\r\n" +
270                 "-----1234--\r\n");
271         assertEquals(4, fileItems.size());
272 
273         FileItem file = fileItems.get(0);
274         assertEquals("file", file.getFieldName());
275         assertFalse(file.isFormField());
276         assertEquals("This is the content of the file\n", file.getString());
277         assertEquals("text/whatever", file.getContentType());
278         assertEquals("foo.tab", file.getName());
279 
280         FileItem field = fileItems.get(1);
281         assertEquals("field", field.getFieldName());
282         assertTrue(field.isFormField());
283         assertEquals("fieldValue", field.getString());
284 
285         FileItem multi0 = fileItems.get(2);
286         assertEquals("multi", multi0.getFieldName());
287         assertTrue(multi0.isFormField());
288         assertEquals("value1", multi0.getString());
289 
290         FileItem multi1 = fileItems.get(3);
291         assertEquals("multi", multi1.getFieldName());
292         assertTrue(multi1.isFormField());
293         assertEquals("value2", multi1.getString());
294     }
295 
296     /**
297      * Test case for <a href="http://issues.apache.org/jira/browse/FILEUPLOAD-130">
298      */
299     @Test
300     public void testFileUpload130()
301             throws Exception {
302         final String[] headerNames = new String[]
303         {
304             "SomeHeader", "OtherHeader", "YetAnotherHeader", "WhatAHeader"
305         };
306         final String[] headerValues = new String[]
307         {
308             "present", "Is there", "Here", "Is That"
309         };
310         List<FileItem> fileItems = Util.parseUpload(upload,
311                                                "-----1234\r\n" +
312                                                "Content-Disposition: form-data; name=\"file\"; filename=\"foo.tab\"\r\n" +
313                                                "Content-Type: text/whatever\r\n" +
314                                                headerNames[0] + ": " + headerValues[0] + "\r\n" +
315                                                "\r\n" +
316                                                "This is the content of the file\n" +
317                                                "\r\n" +
318                                                "-----1234\r\n" +
319                                                "Content-Disposition: form-data; \r\n" +
320                                                "\tname=\"field\"\r\n" +
321                                                headerNames[1] + ": " + headerValues[1] + "\r\n" +
322                                                "\r\n" +
323                                                "fieldValue\r\n" +
324                                                "-----1234\r\n" +
325                                                "Content-Disposition: form-data;\r\n" +
326                                                "     name=\"multi\"\r\n" +
327                                                headerNames[2] + ": " + headerValues[2] + "\r\n" +
328                                                "\r\n" +
329                                                "value1\r\n" +
330                                                "-----1234\r\n" +
331                                                "Content-Disposition: form-data; name=\"multi\"\r\n" +
332                                                headerNames[3] + ": " + headerValues[3] + "\r\n" +
333                                                "\r\n" +
334                                                "value2\r\n" +
335                                                "-----1234--\r\n");
336         assertEquals(4, fileItems.size());
337 
338         FileItem file = fileItems.get(0);
339         assertHeaders(headerNames, headerValues, file, 0);
340 
341         FileItem field = fileItems.get(1);
342         assertHeaders(headerNames, headerValues, field, 1);
343 
344         FileItem multi0 = fileItems.get(2);
345         assertHeaders(headerNames, headerValues, multi0, 2);
346 
347         FileItem multi1 = fileItems.get(3);
348         assertHeaders(headerNames, headerValues, multi1, 3);
349     }
350 
351     /**
352      * Test for <a href="http://issues.apache.org/jira/browse/FILEUPLOAD-239">FILEUPLOAD-239</a>
353      */
354     @Test
355     public void testContentTypeAttachment()
356             throws IOException, FileUploadException {
357         List<FileItem> fileItems = Util.parseUpload(upload,
358                 "-----1234\r\n" +
359                 "content-disposition: form-data; name=\"field1\"\r\n" +
360                 "\r\n" +
361                 "Joe Blow\r\n" +
362                 "-----1234\r\n" +
363                 "content-disposition: form-data; name=\"pics\"\r\n" +
364                 "Content-type: multipart/mixed, boundary=---9876\r\n" +
365                 "\r\n" +
366                 "-----9876\r\n" +
367                 "Content-disposition: attachment; filename=\"file1.txt\"\r\n" +
368                 "Content-Type: text/plain\r\n" +
369                 "\r\n" +
370                 "... contents of file1.txt ...\r\n" +
371                 "-----9876--\r\n" +
372                 "-----1234--\r\n");
373         assertEquals(2, fileItems.size());
374 
375         FileItem field = fileItems.get(0);
376         assertEquals("field1", field.getFieldName());
377         assertTrue(field.isFormField());
378         assertEquals("Joe Blow", field.getString());
379 
380         FileItem file = fileItems.get(1);
381         assertEquals("pics", file.getFieldName());
382         assertFalse(file.isFormField());
383         assertEquals("... contents of file1.txt ...", file.getString());
384         assertEquals("text/plain", file.getContentType());
385         assertEquals("file1.txt", file.getName());
386     }
387 
388     private void assertHeaders(String[] pHeaderNames, String[] pHeaderValues,
389             FileItem pItem, int pIndex) {
390         for (int i = 0; i < pHeaderNames.length; i++) {
391             final String value = pItem.getHeaders().getHeader(pHeaderNames[i]);
392             if (i == pIndex) {
393                 assertEquals(pHeaderValues[i], value);
394             } else {
395                 assertNull(value);
396             }
397         }
398     }
399 }