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.assertTrue;
    22  import static org.junit.Assert.fail;
    23
    24  import java.io.ByteArrayOutputStream;
    25  import java.io.IOException;
    26  import java.io.InputStream;
    27
    28  import org.apache.commons.fileupload.servlet.ServletFileUpload;
    29  import org.junit.Test;
    30
    31  /**
    32   * Tests the {@link ProgressListener}.
    33   */
    34  public class ProgressListenerTest {
    35
    36      private static class ProgressListenerImpl implements ProgressListener {
    37
    38          /** Expected content length. */
    39          private final long expectedContentLength;
    40
    41          /** Expected item count. */
    42          private final int expectedItems;
    43
    44          /** Bytes read count. */
    45          private Long bytesRead;
    46
    47          /** Item count. */
    48          private Integer items;
    49
    50          ProgressListenerImpl(final long expectedContentLength, final int expectedItems) {
    51              this.expectedContentLength = expectedContentLength;
    52              this.expectedItems = expectedItems;
    53          }
    54
    55          void checkFinished() {
    56              assertEquals(expectedContentLength, bytesRead.longValue());
    57              assertEquals(expectedItems, items.intValue());
    58          }
    59
    60          @Override
    61          public void update(final long actualBytesRead, final long actualContentLength, final int actualItems) {
    62              assertTrue(actualBytesRead >= 0 && actualBytesRead <= expectedContentLength);
    63              assertTrue(actualContentLength == -1 || actualContentLength == expectedContentLength);
    64              assertTrue(actualItems >= 0 && actualItems <= expectedItems);
    65              assertTrue(this.bytesRead == null || actualBytesRead >= this.bytesRead.longValue());
    66              this.bytesRead = Long.valueOf(actualBytesRead);
    67              assertTrue(items == null || actualItems >= items.intValue());
    68              this.items = Integer.valueOf(actualItems);
    69          }
    70      }
    71
    72      private void runTest(final int numItems, final long contentLength, final MockHttpServletRequest request) throws FileUploadException, IOException {
    73          final ServletFileUpload upload = new ServletFileUpload();
    74          final ProgressListenerImpl listener = new ProgressListenerImpl(contentLength, numItems);
    75          upload.setProgressListener(listener);
    76          final FileItemIterator iter = upload.getItemIterator(request);
    77          for (int i = 0; i < numItems; i++) {
    78              final FileItemStream stream = iter.next();
    79              try (InputStream istream = stream.openStream()) {
    80                  final int maxIn = 16384;
    81                  for (int j = 0; j < maxIn + i; j++) {
    82                      /**
    83                       * This used to be assertEquals((byte) j, (byte) istream.read()); but this seems to trigger a bug in JRockit, so we express the same like
    84                       * this:
    85                       */
    86                      final byte b1 = (byte) j;
    87                      final byte b2 = (byte) istream.read();
    88                      if (b1 != b2) {
    89                          fail("Expected " + b1 + ", got " + b2);
    90                      }
    91                  }
    92                  assertEquals(-1, istream.read());
    93              }
    94          }
    95          assertTrue(!iter.hasNext());
    96          listener.checkFinished();
    97      }
    98
    99      /**
    100      * Parse a very long file upload by using a progress listener.
    101      */
    102     @Test
    103     public void testProgressListener() throws Exception {
    104         final int numItems = 512;
    105         final ByteArrayOutputStream baos = new ByteArrayOutputStream();
    106         for (int i = 0; i < numItems; i++) {
    107             final String header = "-----1234\r\n" + "Content-Disposition: form-data; name=\"field" + (i + 1) + "\"\r\n" + "\r\n";
    108             baos.write(header.getBytes("US-ASCII"));
    109             final int maxOut = 16384;
    110             for (int j = 0; j < maxOut + i; j++) {
    111                 baos.write((byte) j);
    112             }
    113             baos.write("\r\n".getBytes("US-ASCII"));
    114         }
    115         baos.write("-----1234--\r\n".getBytes("US-ASCII"));
    116         final byte[] contents = baos.toByteArray();
    117         MockHttpServletRequest request = new MockHttpServletRequest(contents, Constants.CONTENT_TYPE);
    118         runTest(numItems, contents.length, request);
    119         request = new MockHttpServletRequest(contents, Constants.CONTENT_TYPE) {
    120
    121             @Override
    122             public int getContentLength() {
    123                 return -1;
    124             }
    125         };
    126         runTest(numItems, contents.length, request);
    127     }
    128 }