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.assertNotNull;
22  import static org.junit.Assert.assertNull;
23  import static org.junit.Assert.assertTrue;
24  import static org.junit.Assert.fail;
25  
26  import java.io.File;
27  import java.io.IOException;
28  import java.io.OutputStream;
29  import java.util.Arrays;
30  
31  import org.junit.Test;
32  
33  /**
34   * Unit tests for {@link org.apache.commons.fileupload.DefaultFileItem}.
35   */
36  @SuppressWarnings({"deprecation", "javadoc"}) // unit tests for deprecated class
37  public class DefaultFileItemTest {
38  
39      /**
40       * Content type for regular form items.
41       */
42      private static final String textContentType = "text/plain";
43  
44      /**
45       * Content type for file uploads.
46       */
47      private static final String fileContentType = "application/octet-stream";
48  
49      /**
50       * Very low threshold for testing memory versus disk options.
51       */
52      private static final int threshold = 16;
53  
54      /**
55       * Test construction of a regular text field.
56       */
57      @Test
58      public void testTextFieldConstruction() {
59          FileItemFactory factory = createFactory(null);
60          String textFieldName = "textField";
61  
62          FileItem item = factory.createItem(
63                  textFieldName,
64                  textContentType,
65                  true,
66                  null
67          );
68          assertNotNull(item);
69          assertEquals(item.getFieldName(), textFieldName);
70          assertEquals(item.getContentType(), textContentType);
71          assertTrue(item.isFormField());
72          assertNull(item.getName());
73      }
74  
75      /**
76       * Test construction of a file field.
77       */
78      @Test
79      public void testFileFieldConstruction() {
80          FileItemFactory factory = createFactory(null);
81          String fileFieldName = "fileField";
82          String fileName = "originalFileName";
83  
84          FileItem item = factory.createItem(
85                  fileFieldName,
86                  fileContentType,
87                  false,
88                  fileName
89          );
90          assertNotNull(item);
91          assertEquals(item.getFieldName(), fileFieldName);
92          assertEquals(item.getContentType(), fileContentType);
93          assertFalse(item.isFormField());
94          assertEquals(item.getName(), fileName);
95      }
96  
97      /**
98       * Test creation of a field for which the amount of data falls below the
99       * configured threshold.
100      */
101     @Test
102     public void testBelowThreshold() {
103         FileItemFactory factory = createFactory(null);
104         String textFieldName = "textField";
105         String textFieldValue = "0123456789";
106         byte[] testFieldValueBytes = textFieldValue.getBytes();
107 
108         FileItem item = factory.createItem(
109                 textFieldName,
110                 textContentType,
111                 true,
112                 null
113         );
114         assertNotNull(item);
115 
116         try {
117             OutputStream os = item.getOutputStream();
118             os.write(testFieldValueBytes);
119             os.close();
120         } catch(IOException e) {
121             fail("Unexpected IOException");
122         }
123         assertTrue(item.isInMemory());
124         assertEquals(item.getSize(), testFieldValueBytes.length);
125         assertTrue(Arrays.equals(item.get(), testFieldValueBytes));
126         assertEquals(item.getString(), textFieldValue);
127     }
128 
129     /**
130      * Test creation of a field for which the amount of data falls above the
131      * configured threshold, where no specific repository is configured.
132      */
133     @Test
134     public void testAboveThresholdDefaultRepository() {
135         doTestAboveThreshold(null);
136     }
137 
138     /**
139      * Test creation of a field for which the amount of data falls above the
140      * configured threshold, where a specific repository is configured.
141      */
142     @Test
143     public void testAboveThresholdSpecifiedRepository() {
144         String tempPath = System.getProperty("java.io.tmpdir");
145         String tempDirName = "testAboveThresholdSpecifiedRepository";
146         File tempDir = new File(tempPath, tempDirName);
147         tempDir.mkdir();
148         doTestAboveThreshold(tempDir);
149         assertTrue(tempDir.delete());
150     }
151 
152     /**
153      * Common code for cases where the amount of data is above the configured
154      * threshold, but the ultimate destination of the data has not yet been
155      * determined.
156      *
157      * @param repository The directory within which temporary files will be
158      *                   created.
159      */
160     public void doTestAboveThreshold(File repository) {
161         FileItemFactory factory = createFactory(repository);
162         String textFieldName = "textField";
163         String textFieldValue = "01234567890123456789";
164         byte[] testFieldValueBytes = textFieldValue.getBytes();
165 
166         FileItem item = factory.createItem(
167                 textFieldName,
168                 textContentType,
169                 true,
170                 null
171         );
172         assertNotNull(item);
173 
174         try {
175             OutputStream os = item.getOutputStream();
176             os.write(testFieldValueBytes);
177             os.close();
178         } catch(IOException e) {
179             fail("Unexpected IOException");
180         }
181         assertFalse(item.isInMemory());
182         assertEquals(item.getSize(), testFieldValueBytes.length);
183         assertTrue(Arrays.equals(item.get(), testFieldValueBytes));
184         assertEquals(item.getString(), textFieldValue);
185 
186         assertTrue(item instanceof DefaultFileItem);
187         DefaultFileItem dfi = (DefaultFileItem) item;
188         File storeLocation = dfi.getStoreLocation();
189         assertNotNull(storeLocation);
190         assertTrue(storeLocation.exists());
191         assertEquals(storeLocation.length(), testFieldValueBytes.length);
192 
193         if (repository != null) {
194             assertEquals(storeLocation.getParentFile(), repository);
195         }
196 
197         item.delete();
198     }
199 
200 
201     /**
202      * Creates a new <code>FileItemFactory</code> and returns it, obscuring
203      * from the caller the underlying implementation of this interface.
204      *
205      * @param repository The directory within which temporary files will be
206      *                   created.
207      * @return the new <code>FileItemFactory</code> instance.
208      */
209     protected FileItemFactory createFactory(File repository) {
210         return new DefaultFileItemFactory(threshold, repository);
211     }
212 
213     static final String CHARSET_ISO88591 = "ISO-8859-1";
214 
215     static final String CHARSET_ASCII = "US-ASCII";
216 
217     static final String CHARSET_UTF8 = "UTF-8";
218 
219     static final String CHARSET_KOI8_R = "KOI8_R";
220 
221     static final String CHARSET_WIN1251 = "Cp1251";
222 
223     static final int SWISS_GERMAN_STUFF_UNICODE [] = {
224         0x47, 0x72, 0xFC, 0x65, 0x7A, 0x69, 0x5F, 0x7A, 0xE4, 0x6D, 0xE4
225     };
226 
227     static final int SWISS_GERMAN_STUFF_ISO8859_1 [] = {
228         0x47, 0x72, 0xFC, 0x65, 0x7A, 0x69, 0x5F, 0x7A, 0xE4, 0x6D, 0xE4
229     };
230 
231     static final int SWISS_GERMAN_STUFF_UTF8 [] = {
232         0x47, 0x72, 0xC3, 0xBC, 0x65, 0x7A, 0x69, 0x5F, 0x7A, 0xC3, 0xA4,
233         0x6D, 0xC3, 0xA4
234     };
235 
236     static final int RUSSIAN_STUFF_UNICODE [] = {
237         0x412, 0x441, 0x435, 0x43C, 0x5F, 0x43F, 0x440, 0x438,
238         0x432, 0x435, 0x442
239     };
240 
241     static final int RUSSIAN_STUFF_UTF8 [] = {
242         0xD0, 0x92, 0xD1, 0x81, 0xD0, 0xB5, 0xD0, 0xBC, 0x5F,
243         0xD0, 0xBF, 0xD1, 0x80, 0xD0, 0xB8, 0xD0, 0xB2, 0xD0,
244         0xB5, 0xD1, 0x82
245     };
246 
247     static final int RUSSIAN_STUFF_KOI8R [] = {
248         0xF7, 0xD3, 0xC5, 0xCD, 0x5F, 0xD0, 0xD2, 0xC9, 0xD7,
249         0xC5, 0xD4
250     };
251 
252     static final int RUSSIAN_STUFF_WIN1251 [] = {
253         0xC2, 0xF1, 0xE5, 0xEC, 0x5F, 0xEF, 0xF0, 0xE8, 0xE2,
254         0xE5, 0xF2
255     };
256 
257     private static String constructString(int[] unicodeChars) {
258         StringBuilder buffer = new StringBuilder();
259         if (unicodeChars != null) {
260             for (int unicodeChar : unicodeChars) {
261                 buffer.append((char) unicodeChar);
262             }
263         }
264         return buffer.toString();
265     }
266 
267     /**
268      * Test construction of content charset.
269      */
270     public void testContentCharSet() throws Exception {
271         FileItemFactory factory = createFactory(null);
272 
273         String teststr = constructString(SWISS_GERMAN_STUFF_UNICODE);
274 
275         FileItem item =
276             factory.createItem(
277                 "doesnotmatter",
278                 "text/plain; charset=" + CHARSET_ISO88591,
279                 true,
280                 null);
281         OutputStream outstream = item.getOutputStream();
282         for (int element : SWISS_GERMAN_STUFF_ISO8859_1) {
283             outstream.write(element);
284         }
285         outstream.close();
286         assertEquals(teststr, teststr, item.getString());
287 
288         item =
289             factory.createItem(
290                 "doesnotmatter",
291                 "text/plain; charset=" + CHARSET_UTF8,
292                 true,
293                 null);
294         outstream = item.getOutputStream();
295         for (int element : SWISS_GERMAN_STUFF_UTF8) {
296             outstream.write(element);
297         }
298         outstream.close();
299         assertEquals(teststr, teststr, item.getString());
300 
301         teststr = constructString(RUSSIAN_STUFF_UNICODE);
302 
303         item =
304             factory.createItem(
305                 "doesnotmatter",
306                 "text/plain; charset=" + CHARSET_KOI8_R,
307                 true,
308                 null);
309         outstream = item.getOutputStream();
310         for (int element : RUSSIAN_STUFF_KOI8R) {
311             outstream.write(element);
312         }
313         outstream.close();
314         assertEquals(teststr, teststr, item.getString());
315 
316         item =
317             factory.createItem(
318                 "doesnotmatter",
319                 "text/plain; charset=" + CHARSET_WIN1251,
320                 true,
321                 null);
322         outstream = item.getOutputStream();
323         for (int element : RUSSIAN_STUFF_WIN1251) {
324             outstream.write(element);
325         }
326         outstream.close();
327         assertEquals(teststr, teststr, item.getString());
328 
329         item =
330             factory.createItem(
331                 "doesnotmatter",
332                 "text/plain; charset=" + CHARSET_UTF8,
333                 true,
334                 null);
335         outstream = item.getOutputStream();
336         for (int element : RUSSIAN_STUFF_UTF8) {
337             outstream.write(element);
338         }
339         outstream.close();
340         assertEquals(teststr, teststr, item.getString());
341     }
342 
343 }