    1   /*
    2    * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/test/org/apache/commons/httpclient/TestStreams.java,v 1.19 2004/10/31 14:04:13 olegk Exp $
    3    * $Revision: 505890 $
    4    * $Date: 2007-02-11 12:25:25 +0100 (Sun, 11 Feb 2007) $
    5    * ====================================================================
    6    *
    7    *  Licensed to the Apache Software Foundation (ASF) under one or more
    8    *  contributor license agreements.  See the NOTICE file distributed with
    9    *  this work for additional information regarding copyright ownership.
    10   *  The ASF licenses this file to You under the Apache License, Version 2.0
    11   *  (the "License"); you may not use this file except in compliance with
    12   *  the License.  You may obtain a copy of the License at
    13   *
    14   *      http://www.apache.org/licenses/LICENSE-2.0
    15   *
    16   *  Unless required by applicable law or agreed to in writing, software
    17   *  distributed under the License is distributed on an "AS IS" BASIS,
    18   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    19   *  See the License for the specific language governing permissions and
    20   *  limitations under the License.
    21   * ====================================================================
    22   *
    23   * This software consists of voluntary contributions made by many
    24   * individuals on behalf of the Apache Software Foundation.  For more
    25   * information on the Apache Software Foundation, please see
    26   * <http://www.apache.org/>.
    27   *
    28   * [Additional notices, if required by prior licensing conditions]
    29   *
    30   */
    31
    32  package org.apache.commons.httpclient;
    33
    34  import java.io.ByteArrayInputStream;
    35  import java.io.ByteArrayOutputStream;
    36  import java.io.IOException;
    37  import java.io.InputStream;
    38  import java.io.OutputStream;
    39
    40  import junit.framework.Test;
    41  import junit.framework.TestCase;
    42  import junit.framework.TestSuite;
    43
    44  import org.apache.commons.httpclient.methods.GetMethod;
    45  import org.apache.commons.httpclient.util.EncodingUtil;
    46
    47
    48  public class TestStreams extends TestCase {
    49
    50      private static final String CONTENT_CHARSET = "ISO-8859-1";
    51
    52      public TestStreams(String testName) {
    53          super(testName);
    54      }
    55
    56      public void testChunkedInputStream() throws IOException {
    57          String correctInput = "10;key=\"value\r\nnewline\"\r\n1234567890123456\r\n5\r\n12345\r\n0\r\nFooter1: abcde\r\nFooter2: fghij\r\n";
    58          String correctResult = "123456789012345612345";
    59          HttpMethod method = new FakeHttpMethod();
    60
    61          //Test for when buffer is larger than chunk size
    62          InputStream in = new ChunkedInputStream(new ByteArrayInputStream(
    63              EncodingUtil.getBytes(correctInput, CONTENT_CHARSET)), method);
    64          byte[] buffer = new byte[300];
    65          ByteArrayOutputStream out = new ByteArrayOutputStream();
    66          int len;
    67          while ((len = in.read(buffer)) > 0) {
    68              out.write(buffer, 0, len);
    69          }
    70          String result = EncodingUtil.getString(out.toByteArray(), CONTENT_CHARSET);
    71          assertEquals(result, correctResult);
    72          Header footer = method.getResponseFooter("footer1");
    73          assertEquals(footer.getValue(), "abcde");
    74          footer = method.getResponseFooter("footer2");
    75          assertEquals(footer.getValue(), "fghij");
    76
    77          method = new FakeHttpMethod();
    78
    79          //Test for when buffer is smaller than chunk size.
    80          in = new ChunkedInputStream(new ByteArrayInputStream(
    81              EncodingUtil.getBytes(correctInput, CONTENT_CHARSET)), method);
    82          buffer = new byte[7];
    83          out = new ByteArrayOutputStream();
    84          while ((len = in.read(buffer)) > 0) {
    85              out.write(buffer, 0, len);
    86          }
    87          result = EncodingUtil.getString(out.toByteArray(), CONTENT_CHARSET);
    88          assertEquals(result, correctResult);
    89          footer = method.getResponseFooter("footer1");
    90          assertEquals(footer.getValue(), "abcde");
    91          footer = method.getResponseFooter("footer2");
    92          assertEquals(footer.getValue(), "fghij");
    93      }
    94
    95      public void testCorruptChunkedInputStream1() throws IOException {
    96          //missing \r\n at the end of the first chunk
    97          String corrupInput = "10;key=\"value\"\r\n123456789012345\r\n5\r\n12345\r\n0\r\nFooter1: abcde\r\nFooter2: fghij\r\n";
    98          HttpMethod method = new FakeHttpMethod();
    99
    100         InputStream in = new ChunkedInputStream(new ByteArrayInputStream(
    101             EncodingUtil.getBytes(corrupInput, CONTENT_CHARSET)), method);
    102         byte[] buffer = new byte[300];
    103         ByteArrayOutputStream out = new ByteArrayOutputStream();
    104         int len;
    105         try {
    106             while ((len = in.read(buffer)) > 0) {
    107                 out.write(buffer, 0, len);
    108             }
    109             fail("Should have thrown exception");
    110         } catch(IOException e) {
    111             /* expected exception */
    112         }
    113     }
    114
    115     public void testEmptyChunkedInputStream() throws IOException {
    116         String input = "0\r\n";
    117         HttpMethod method = new FakeHttpMethod();
    118
    119         InputStream in = new ChunkedInputStream(new ByteArrayInputStream(
    120             EncodingUtil.getBytes(input, CONTENT_CHARSET)), method);
    121         byte[] buffer = new byte[300];
    122         ByteArrayOutputStream out = new ByteArrayOutputStream();
    123         int len;
    124         while ((len = in.read(buffer)) > 0) {
    125             out.write(buffer, 0, len);
    126         }
    127         assertEquals(0, out.size());
    128     }
    129
    130     public void testContentLengthInputStream() throws IOException {
    131         String correct = "1234567890123456";
    132         InputStream in = new ContentLengthInputStream(new ByteArrayInputStream(
    133             EncodingUtil.getBytes(correct, CONTENT_CHARSET)), 10L);
    134         byte[] buffer = new byte[50];
    135         int len = in.read(buffer);
    136         ByteArrayOutputStream out = new ByteArrayOutputStream();
    137         out.write(buffer, 0, len);
    138         String result = EncodingUtil.getString(out.toByteArray(), CONTENT_CHARSET);
    139         assertEquals(result, "1234567890");
    140     }
    141
    142     public void testContentLengthInputStreamSkip() throws IOException {
    143         InputStream in = new ContentLengthInputStream(new ByteArrayInputStream(new byte[20]), 10L);
    144         assertEquals(10, in.skip(10));
    145         assertTrue(in.read() == -1);
    146
    147         in = new ContentLengthInputStream(new ByteArrayInputStream(new byte[20]), 10L);
    148         in.read();
    149         assertEquals(9, in.skip(10));
    150         assertTrue(in.read() == -1);
    151
    152         in = new ContentLengthInputStream(new ByteArrayInputStream(new byte[20]), 2L);
    153         in.read();
    154         in.read();
    155         assertTrue(in.skip(10) <= 0);
    156         assertTrue(in.read() == -1);
    157     }
    158
    159     public void testChunkedConsitance() throws IOException {
    160         String input = "76126;27823abcd;:q38a-\nkjc\rk%1ad\tkh/asdui\r\njkh+?\\suweb";
    161         ByteArrayOutputStream buffer = new ByteArrayOutputStream();
    162         OutputStream out = new ChunkedOutputStream(buffer);
    163         out.write(EncodingUtil.getBytes(input, CONTENT_CHARSET));
    164         out.close();
    165         buffer.close();
    166         InputStream in = new ChunkedInputStream(new ByteArrayInputStream(buffer.toByteArray()), new GetMethod());
    167
    168         byte[] d = new byte[10];
    169         ByteArrayOutputStream result = new ByteArrayOutputStream();
    170         int len = 0;
    171         while ((len = in.read(d)) > 0) {
    172             result.write(d, 0, len);
    173         }
    174
    175         String output = EncodingUtil.getString(result.toByteArray(), CONTENT_CHARSET);
    176         assertEquals(input, output);
    177     }
    178
    179     public void testChunkedOutputStream() throws IOException {
    180         ByteArrayOutputStream buffer = new ByteArrayOutputStream();
    181         ChunkedOutputStream out = new ChunkedOutputStream(buffer, 2);
    182         out.write('1');
    183         out.write('2');
    184         out.write('3');
    185         out.write('4');
    186         out.finish();
    187         out.close();
    188
    189         byte [] rawdata =  buffer.toByteArray();
    190
    191         assertEquals(19, rawdata.length);
    192         assertEquals('2', rawdata[0]);
    193         assertEquals('\r', rawdata[1]);
    194         assertEquals('\n', rawdata[2]);
    195         assertEquals('1', rawdata[3]);
    196         assertEquals('2', rawdata[4]);
    197         assertEquals('\r', rawdata[5]);
    198         assertEquals('\n', rawdata[6]);
    199         assertEquals('2', rawdata[7]);
    200         assertEquals('\r', rawdata[8]);
    201         assertEquals('\n', rawdata[9]);
    202         assertEquals('3', rawdata[10]);
    203         assertEquals('4', rawdata[11]);
    204         assertEquals('\r', rawdata[12]);
    205         assertEquals('\n', rawdata[13]);
    206         assertEquals('0', rawdata[14]);
    207         assertEquals('\r', rawdata[15]);
    208         assertEquals('\n', rawdata[16]);
    209         assertEquals('\r', rawdata[17]);
    210         assertEquals('\n', rawdata[18]);
    211     }
    212
    213     public void testChunkedOutputStreamLargeChunk() throws IOException {
    214         ByteArrayOutputStream buffer = new ByteArrayOutputStream();
    215         ChunkedOutputStream out = new ChunkedOutputStream(buffer, 2);
    216         out.write(new byte[] {'1', '2', '3', '4'});
    217         out.finish();
    218         out.close();
    219
    220         byte [] rawdata =  buffer.toByteArray();
    221
    222         assertEquals(14, rawdata.length);
    223         assertEquals('4', rawdata[0]);
    224         assertEquals('\r', rawdata[1]);
    225         assertEquals('\n', rawdata[2]);
    226         assertEquals('1', rawdata[3]);
    227         assertEquals('2', rawdata[4]);
    228         assertEquals('3', rawdata[5]);
    229         assertEquals('4', rawdata[6]);
    230         assertEquals('\r', rawdata[7]);
    231         assertEquals('\n', rawdata[8]);
    232         assertEquals('0', rawdata[9]);
    233         assertEquals('\r', rawdata[10]);
    234         assertEquals('\n', rawdata[11]);
    235         assertEquals('\r', rawdata[12]);
    236         assertEquals('\n', rawdata[13]);
    237     }
    238
    239     public void testChunkedOutputStreamSmallChunk() throws IOException {
    240         ByteArrayOutputStream buffer = new ByteArrayOutputStream();
    241         ChunkedOutputStream out = new ChunkedOutputStream(buffer, 2);
    242         out.write('1');
    243         out.finish();
    244         out.close();
    245
    246         byte [] rawdata =  buffer.toByteArray();
    247
    248         assertEquals(11, rawdata.length);
    249         assertEquals('1', rawdata[0]);
    250         assertEquals('\r', rawdata[1]);
    251         assertEquals('\n', rawdata[2]);
    252         assertEquals('1', rawdata[3]);
    253         assertEquals('\r', rawdata[4]);
    254         assertEquals('\n', rawdata[5]);
    255         assertEquals('0', rawdata[6]);
    256         assertEquals('\r', rawdata[7]);
    257         assertEquals('\n', rawdata[8]);
    258         assertEquals('\r', rawdata[9]);
    259         assertEquals('\n', rawdata[10]);
    260     }
    261
    262     // ------------------------------------------------------- TestCase Methods
    263
    264     public static Test suite() {
    265         return new TestSuite(TestStreams.class);
    266     }
    267
    268     // ------------------------------------------------------------------- Main
    269     public static void main(String args[]) {
    270         String[] testCaseName = { TestStreams.class.getName() };
    271         junit.textui.TestRunner.main(testCaseName);
    272     }
    273
    274
    275     public void testAutoCloseInputStream() throws IOException {
    276         // The purpose of this test is to check EOF handling of ACIS with
    277         // respect to exceptions being thrown. Putting it on top of a
    278         // plain ByteArrayInputStream won't do, since BAIS can't be closed.
    279         ByteArrayInputStream bais =
    280             new ByteArrayInputStream("whatever".getBytes());
    281         InputStream fbais = new java.io.FilterInputStream(bais) {
    282                 private boolean closed = false;
    283                 public void close() throws IOException {
    284                     closed = true;
    285                     super.close();
    286                 }
    287                 public int available() throws IOException {
    288                     if (closed)
    289                         throw new IOException("closed");
    290                     return super.available();
    291                 }
    292             };
    293
    294         AutoCloseInputStream acis = new AutoCloseInputStream(fbais, null);
    295         byte[] data = new byte[16];
    296         int count = 0;
    297         while (count >= 0) {
    298             count = acis.read(data);
    299         }
    300         // We're at EOF. The underlying stream should be closed,
    301         // but the ACIS itself not.
    302         try {
    303             fbais.available();
    304             fail("underlying stream not auto-closed");
    305         } catch (IOException x) {
    306             // expected, pis should be closed
    307         }
    308
    309         // don't want to see an exception being thrown here
    310         acis.available();
    311
    312         acis.close();
    313         try {
    314             acis.available();
    315             fail("auto-close stream not closed");
    316         } catch (IOException x) {
    317             // expected, acis should be closed
    318         }
    319     }
    320 }
    321