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 }