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 
TestStreams(String testName)52     public TestStreams(String testName) {
53         super(testName);
54     }
55 
testChunkedInputStream()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 
testCorruptChunkedInputStream1()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 
testEmptyChunkedInputStream()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 
testContentLengthInputStream()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 
testContentLengthInputStreamSkip()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 
testChunkedConsitance()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 
testChunkedOutputStream()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 
testChunkedOutputStreamLargeChunk()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 
testChunkedOutputStreamSmallChunk()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 
suite()264     public static Test suite() {
265         return new TestSuite(TestStreams.class);
266     }
267 
268     // ------------------------------------------------------------------- Main
main(String args[])269     public static void main(String args[]) {
270         String[] testCaseName = { TestStreams.class.getName() };
271         junit.textui.TestRunner.main(testCaseName);
272     }
273 
274 
testAutoCloseInputStream()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 
322