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