View Javadoc
1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  
28  package org.apache.hc.core5.http.impl.io;
29  
30  import java.io.ByteArrayInputStream;
31  import java.io.ByteArrayOutputStream;
32  import java.io.IOException;
33  import java.io.InputStream;
34  import java.nio.charset.StandardCharsets;
35  
36  import org.apache.hc.core5.http.ConnectionClosedException;
37  import org.apache.hc.core5.http.StreamClosedException;
38  import org.apache.hc.core5.http.io.SessionInputBuffer;
39  import org.junit.jupiter.api.Assertions;
40  import org.junit.jupiter.api.Test;
41  
42  public class TestContentLengthInputStream {
43  
44      @Test
45      public void testBasics() throws IOException {
46          final String s = "1234567890123456";
47          final ByteArrayInputStream inputStream = new ByteArrayInputStream(s.getBytes(StandardCharsets.ISO_8859_1));
48          final SessionInputBuffer inBuffer = new SessionInputBufferImpl(16);
49          final InputStream in = new ContentLengthInputStream(inBuffer, inputStream, 10L);
50          final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
51  
52          final byte[] buffer = new byte[50];
53          int len = in.read(buffer, 0, 2);
54          outputStream.write(buffer, 0, len);
55          len = in.read(buffer);
56          outputStream.write(buffer, 0, len);
57  
58          final String result = new String(outputStream.toByteArray(), StandardCharsets.ISO_8859_1);
59          Assertions.assertEquals(result, "1234567890");
60          in.close();
61      }
62  
63      @Test
64      public void testSkip() throws IOException {
65          final ByteArrayInputStream inputStream1 = new ByteArrayInputStream(new byte[20]);
66          final SessionInputBuffer inBuffer1 = new SessionInputBufferImpl(16);
67          final InputStream in1 = new ContentLengthInputStream(inBuffer1, inputStream1, 10L);
68          Assertions.assertEquals(10, in1.skip(10));
69          Assertions.assertEquals(-1, in1.read());
70          in1.close();
71  
72          final ByteArrayInputStream inputStream2 = new ByteArrayInputStream(new byte[20]);
73          final SessionInputBuffer inBuffer2 = new SessionInputBufferImpl(16);
74          final InputStream in2 = new ContentLengthInputStream(inBuffer2, inputStream2, 10L);
75          in2.read();
76          Assertions.assertEquals(9, in2.skip(10));
77          Assertions.assertEquals(-1, in2.read());
78          in2.close();
79  
80          final ByteArrayInputStream inputStream3 = new ByteArrayInputStream(new byte[20]);
81          final SessionInputBuffer inBuffer3 = new SessionInputBufferImpl(16);
82          final InputStream in3 = new ContentLengthInputStream(inBuffer3, inputStream3, 2L);
83          in3.read();
84          in3.read();
85          Assertions.assertTrue(in3.skip(10) <= 0);
86          Assertions.assertEquals(0, in3.skip(-1));
87          Assertions.assertEquals(-1, in3.read());
88          in3.close();
89  
90          final ByteArrayInputStream inputStream4 = new ByteArrayInputStream(new byte[20]);
91          final SessionInputBuffer inBuffer4 = new SessionInputBufferImpl(16);
92          final InputStream in4 = new ContentLengthInputStream(inBuffer4, inputStream4, 10L);
93          Assertions.assertEquals(5,in4.skip(5));
94          Assertions.assertEquals(5, in4.read(new byte[20]));
95          in4.close();
96      }
97  
98      @Test
99      public void testAvailable() throws IOException {
100         final ByteArrayInputStream inputStream = new ByteArrayInputStream(new byte[] {1, 2, 3});
101         final SessionInputBuffer inBuffer = new SessionInputBufferImpl(16);
102         final InputStream in = new ContentLengthInputStream(inBuffer, inputStream, 3L);
103         Assertions.assertEquals(0, in.available());
104         in.read();
105         Assertions.assertEquals(2, in.available());
106         in.close();
107     }
108 
109     @Test
110     public void testClose() throws IOException {
111         final String s = "1234567890123456-";
112         final ByteArrayInputStream inputStream = new ByteArrayInputStream(s.getBytes(StandardCharsets.ISO_8859_1));
113         final SessionInputBuffer inBuffer = new SessionInputBufferImpl(16);
114         final InputStream in = new ContentLengthInputStream(inBuffer, inputStream, 16L);
115         in.close();
116         in.close();
117         Assertions.assertThrows(StreamClosedException.class, in::read);
118         final byte[] tmp = new byte[10];
119         Assertions.assertThrows(StreamClosedException.class, () -> in.read(tmp));
120         Assertions.assertThrows(StreamClosedException.class, () -> in.read(tmp, 0, tmp.length));
121         Assertions.assertEquals('-', inBuffer.read(inputStream));
122     }
123 
124     @Test
125     public void testTruncatedContent() throws IOException {
126         final String s = "1234567890123456";
127         final ByteArrayInputStream inputStream = new ByteArrayInputStream(s.getBytes(StandardCharsets.ISO_8859_1));
128         final SessionInputBuffer inBuffer = new SessionInputBufferImpl(16);
129         final InputStream in = new ContentLengthInputStream(inBuffer, inputStream, 32L);
130         final byte[] tmp = new byte[32];
131         final int byteRead = in.read(tmp);
132         Assertions.assertEquals(16, byteRead);
133         Assertions.assertThrows(ConnectionClosedException.class, () -> in.read(tmp));
134         Assertions.assertThrows(ConnectionClosedException.class, () -> in.read());
135         Assertions.assertThrows(ConnectionClosedException.class, () -> in.close());
136     }
137 
138 }
139