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.http2.impl.io;
29  
30  import java.io.ByteArrayInputStream;
31  import java.io.ByteArrayOutputStream;
32  import java.nio.ByteBuffer;
33  
34  import org.apache.hc.core5.http.ConnectionClosedException;
35  import org.apache.hc.core5.http2.H2ConnectionException;
36  import org.apache.hc.core5.http2.H2CorruptFrameException;
37  import org.apache.hc.core5.http2.frame.FrameConsts;
38  import org.apache.hc.core5.http2.frame.FrameFlag;
39  import org.apache.hc.core5.http2.frame.FrameType;
40  import org.apache.hc.core5.http2.frame.RawFrame;
41  import org.apache.hc.core5.http2.impl.BasicH2TransportMetrics;
42  import org.junit.Assert;
43  import org.junit.Test;
44  
45  public class TestFrameInOutBuffers {
46  
47      @Test
48      public void testReadWriteFrame() throws Exception {
49          final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
50          final FrameOutputBuffer outbuffer = new FrameOutputBuffer(16 * 1024);
51  
52          final RawFrame frame = new RawFrame(FrameType.DATA.getValue(), 0, 1,
53                  ByteBuffer.wrap(new byte[]{1,2,3,4,5}));
54          outbuffer.write(frame, outputStream);
55  
56          final FrameInputBuffer inBuffer = new FrameInputBuffer(16 * 1024);
57          final byte[] bytes = outputStream.toByteArray();
58          final ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
59          Assert.assertEquals(FrameConsts.HEAD_LEN + 5, bytes.length);
60  
61          Assert.assertEquals(1, outbuffer.getMetrics().getFramesTransferred());
62          Assert.assertEquals(bytes.length, outbuffer.getMetrics().getBytesTransferred());
63  
64          final RawFrame frame2 = inBuffer.read(inputStream);
65          Assert.assertEquals(FrameType.DATA.getValue(), frame2.getType());
66          Assert.assertEquals(0, frame2.getFlags());
67          Assert.assertEquals(1L, frame2.getStreamId());
68          final ByteBuffer payload2 = frame2.getPayloadContent();
69          Assert.assertNotNull(payload2);
70          Assert.assertEquals(5, payload2.remaining());
71          Assert.assertEquals(1, payload2.get());
72          Assert.assertEquals(2, payload2.get());
73          Assert.assertEquals(3, payload2.get());
74          Assert.assertEquals(4, payload2.get());
75          Assert.assertEquals(5, payload2.get());
76          Assert.assertEquals(-1, inputStream.read());
77  
78          Assert.assertEquals(1, inBuffer.getMetrics().getFramesTransferred());
79          Assert.assertEquals(bytes.length, inBuffer.getMetrics().getBytesTransferred());
80      }
81  
82      @Test
83      public void testReadFrameMultiple() throws Exception {
84          final FrameInputBuffer inBuffer = new FrameInputBuffer(16 * 1024);
85          final ByteArrayInputStream inputStream = new ByteArrayInputStream(
86                  new byte[] {
87                          0,0,10,0,8,0,0,0,8,4,0,1,2,3,4,0,0,0,0,
88                          0,0,10,0,9,0,0,0,8,4,5,6,7,8,9,0,0,0,0
89                  });
90  
91          final RawFrame frame1 = inBuffer.read(inputStream);
92          Assert.assertEquals(FrameType.DATA, FrameType.valueOf(frame1.getType()));
93          Assert.assertEquals(8, frame1.getFlags());
94          Assert.assertEquals(8, frame1.getStreamId());
95          final ByteBuffer payload1 = frame1.getPayloadContent();
96          Assert.assertNotNull(payload1);
97          Assert.assertEquals(5, payload1.remaining());
98          Assert.assertEquals(0, payload1.get());
99          Assert.assertEquals(1, payload1.get());
100         Assert.assertEquals(2, payload1.get());
101         Assert.assertEquals(3, payload1.get());
102         Assert.assertEquals(4, payload1.get());
103 
104         final RawFrame frame2 = inBuffer.read(inputStream);
105         Assert.assertEquals(FrameType.DATA, FrameType.valueOf(frame2.getType()));
106         Assert.assertEquals(FrameFlag.of(FrameFlag.END_STREAM, FrameFlag.PADDED), frame2.getFlags());
107         Assert.assertEquals(8, frame2.getStreamId());
108         final ByteBuffer payload2 = frame2.getPayloadContent();
109         Assert.assertNotNull(payload2);
110         Assert.assertEquals(5, payload2.remaining());
111         Assert.assertEquals(5, payload2.get());
112         Assert.assertEquals(6, payload2.get());
113         Assert.assertEquals(7, payload2.get());
114         Assert.assertEquals(8, payload2.get());
115         Assert.assertEquals(9, payload2.get());
116 
117         Assert.assertEquals(-1, inputStream.read());
118     }
119 
120     @Test
121     public void testReadFrameMultipleSmallBuffer() throws Exception {
122         final FrameInputBuffer inBuffer = new FrameInputBuffer(new BasicH2TransportMetrics(), 20, 10);
123         final ByteArrayInputStream inputStream = new ByteArrayInputStream(
124                 new byte[] {
125                         0,0,10,0,8,0,0,0,8,4,1,1,1,1,1,0,0,0,0,
126                         0,0,5,0,0,0,0,0,8,2,2,2,2,2,
127                         0,0,10,0,9,0,0,0,8,4,3,3,3,3,3,0,0,0,0
128                 });
129 
130         final RawFrame frame1 = inBuffer.read(inputStream);
131         Assert.assertEquals(FrameType.DATA, FrameType.valueOf(frame1.getType()));
132         Assert.assertEquals(8, frame1.getFlags());
133         Assert.assertEquals(8, frame1.getStreamId());
134         final ByteBuffer payload1 = frame1.getPayloadContent();
135         Assert.assertNotNull(payload1);
136         Assert.assertEquals(5, payload1.remaining());
137         Assert.assertEquals(1, payload1.get());
138         Assert.assertEquals(1, payload1.get());
139         Assert.assertEquals(1, payload1.get());
140         Assert.assertEquals(1, payload1.get());
141         Assert.assertEquals(1, payload1.get());
142 
143         final RawFrame frame2 = inBuffer.read(inputStream);
144         Assert.assertEquals(FrameType.DATA, FrameType.valueOf(frame2.getType()));
145         Assert.assertEquals(0, frame2.getFlags());
146         Assert.assertEquals(8, frame2.getStreamId());
147         final ByteBuffer payload2 = frame2.getPayloadContent();
148         Assert.assertNotNull(payload2);
149         Assert.assertEquals(5, payload2.remaining());
150         Assert.assertEquals(2, payload2.get());
151         Assert.assertEquals(2, payload2.get());
152         Assert.assertEquals(2, payload2.get());
153         Assert.assertEquals(2, payload2.get());
154         Assert.assertEquals(2, payload2.get());
155 
156         final RawFrame frame3 = inBuffer.read(inputStream);
157         Assert.assertEquals(FrameType.DATA, FrameType.valueOf(frame3.getType()));
158         Assert.assertEquals(FrameFlag.of(FrameFlag.END_STREAM, FrameFlag.PADDED), frame3.getFlags());
159         Assert.assertEquals(8, frame3.getStreamId());
160         final ByteBuffer payload3 = frame3.getPayloadContent();
161         Assert.assertNotNull(payload3);
162         Assert.assertEquals(5, payload3.remaining());
163         Assert.assertEquals(3, payload3.get());
164         Assert.assertEquals(3, payload3.get());
165         Assert.assertEquals(3, payload3.get());
166         Assert.assertEquals(3, payload3.get());
167         Assert.assertEquals(3, payload3.get());
168 
169         Assert.assertEquals(-1, inputStream.read());
170     }
171 
172     @Test
173     public void testReadFramePartialReads() throws Exception {
174         final FrameInputBuffer inBuffer = new FrameInputBuffer(16 * 1024);
175         final MultiByteArrayInputStreamArrayInputStream.html#MultiByteArrayInputStream">MultiByteArrayInputStream inputStream = new MultiByteArrayInputStream(
176                 new byte[] {0,0},
177                 new byte[] {10,0,9,0},
178                 new byte[] {0,0,8},
179                 new byte[] {4},
180                 new byte[] {1,2,3,4},
181                 new byte[] {5,0},
182                 new byte[] {0,0,0});
183 
184         final RawFrame frame = inBuffer.read(inputStream);
185         Assert.assertEquals(FrameType.DATA, FrameType.valueOf(frame.getType()));
186         Assert.assertEquals(FrameFlag.of(FrameFlag.END_STREAM, FrameFlag.PADDED), frame.getFlags());
187         Assert.assertEquals(8, frame.getStreamId());
188         final ByteBuffer payload = frame.getPayloadContent();
189         Assert.assertNotNull(payload);
190         Assert.assertEquals(5, payload.remaining());
191         Assert.assertEquals(1, payload.get());
192         Assert.assertEquals(2, payload.get());
193         Assert.assertEquals(3, payload.get());
194         Assert.assertEquals(4, payload.get());
195         Assert.assertEquals(5, payload.get());
196         Assert.assertEquals(-1, inputStream.read());
197     }
198 
199     @Test
200     public void testReadEmptyFrame() throws Exception {
201         final FrameInputBuffer inBuffer = new FrameInputBuffer(16 * 1024);
202         final ByteArrayInputStream inputStream = new ByteArrayInputStream(new byte[] {0,0,0,0,0,0,0,0,0});
203 
204         final RawFrame frame = inBuffer.read(inputStream);
205         Assert.assertEquals(FrameType.DATA, FrameType.valueOf(frame.getType()));
206         Assert.assertEquals(0, frame.getFlags());
207         Assert.assertEquals(0, frame.getStreamId());
208         final ByteBuffer payload = frame.getPayloadContent();
209         Assert.assertNull(payload);
210     }
211 
212     @Test(expected = ConnectionClosedException.class)
213     public void testReadFrameConnectionClosed() throws Exception {
214         final FrameInputBuffer inBuffer = new FrameInputBuffer(16 * 1024);
215         final ByteArrayInputStream inputStream = new ByteArrayInputStream(new byte[] {});
216 
217         inBuffer.read(inputStream);
218     }
219 
220     @Test(expected = H2CorruptFrameException.class)
221     public void testReadFrameCorruptFrame() throws Exception {
222         final FrameInputBuffer inBuffer = new FrameInputBuffer(16 * 1024);
223         final ByteArrayInputStream inputStream = new ByteArrayInputStream(new byte[] {0,0});
224 
225         inBuffer.read(inputStream);
226     }
227 
228     @Test(expected = H2ConnectionException.class)
229     public void testWriteFrameExceedingLimit() throws Exception {
230         final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
231         final FrameOutputBuffer outbuffer = new FrameOutputBuffer(1024);
232 
233         final RawFrame frame = new RawFrame(FrameType.DATA.getValue(), 0, 1,
234                 ByteBuffer.wrap(new byte[2048]));
235         outbuffer.write(frame, outputStream);
236     }
237 
238     @Test(expected = H2ConnectionException.class)
239     public void testReadFrameExceedingLimit() throws Exception {
240         final FrameInputBuffer inBuffer = new FrameInputBuffer(16 * 1024);
241         final ByteArrayInputStream inputStream = new ByteArrayInputStream(
242                 new byte[] {0,-128,-128,0,0,0,0,0,1});
243 
244         inBuffer.read(inputStream);
245     }
246 
247 }
248