1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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