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