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