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.nio;
29
30 import java.nio.ByteBuffer;
31
32 import org.apache.hc.core5.http.ConnectionClosedException;
33 import org.apache.hc.core5.http2.H2ConnectionException;
34 import org.apache.hc.core5.http2.H2CorruptFrameException;
35 import org.apache.hc.core5.http2.ReadableByteChannelMock;
36 import org.apache.hc.core5.http2.WritableByteChannelMock;
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 WritableByteChannelMockMock.html#WritableByteChannelMock">WritableByteChannelMock writableChannel = new WritableByteChannelMock(1024);
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, writableChannel);
55
56 final FrameInputBuffer inBuffer = new FrameInputBuffer(16 * 1024);
57 final byte[] bytes = writableChannel.toByteArray();
58 Assert.assertEquals(FrameConsts.HEAD_LEN + 5, bytes.length);
59
60 Assert.assertEquals(1, outbuffer.getMetrics().getFramesTransferred());
61 Assert.assertEquals(bytes.length, outbuffer.getMetrics().getBytesTransferred());
62
63 final ReadableByteChannelMockMock.html#ReadableByteChannelMock">ReadableByteChannelMock readableChannel = new ReadableByteChannelMock(bytes);
64 final RawFrame frame2 = inBuffer.read(readableChannel);
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, readableChannel.read(ByteBuffer.allocate(1024)));
77
78 Assert.assertEquals(1, inBuffer.getMetrics().getFramesTransferred());
79 Assert.assertEquals(bytes.length, inBuffer.getMetrics().getBytesTransferred());
80
81 final RawFrame frame3 = inBuffer.read(ByteBuffer.wrap(bytes), readableChannel);
82 Assert.assertEquals(FrameType.DATA.getValue(), frame3.getType());
83 Assert.assertEquals(0, frame3.getFlags());
84 Assert.assertEquals(1L, frame3.getStreamId());
85 final ByteBuffer payload3 = frame3.getPayloadContent();
86 Assert.assertNotNull(payload3);
87 Assert.assertEquals(5, payload3.remaining());
88 Assert.assertEquals(1, payload3.get());
89 Assert.assertEquals(2, payload3.get());
90 Assert.assertEquals(3, payload3.get());
91 Assert.assertEquals(4, payload3.get());
92 Assert.assertEquals(5, payload3.get());
93
94 Assert.assertEquals(2, inBuffer.getMetrics().getFramesTransferred());
95 Assert.assertEquals(bytes.length * 2, inBuffer.getMetrics().getBytesTransferred());
96 }
97
98 @Test
99 public void testPartialFrameWrite() throws Exception {
100 final WritableByteChannelMockMock.html#WritableByteChannelMock">WritableByteChannelMock writableChannel = new WritableByteChannelMock(1024, FrameConsts.HEAD_LEN + 10);
101 final FrameOutputBuffer outbuffer = new FrameOutputBuffer(16 * 1024);
102 final RawFrame frame = new RawFrame(FrameType.DATA.getValue(), FrameFlag.END_STREAM.getValue(), 5,
103 ByteBuffer.wrap(new byte[]{'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}));
104
105 outbuffer.write(frame, writableChannel);
106 Assert.assertArrayEquals(new byte[] {0,0,16,0,1,0,0,0,5,48,49,50,51,52,53,54,55,56,57},
107 writableChannel.toByteArray());
108
109 Assert.assertFalse(outbuffer.isEmpty());
110 outbuffer.flush(writableChannel);
111 Assert.assertArrayEquals(new byte[] {0,0,16,0,1,0,0,0,5,48,49,50,51,52,53,54,55,56,57},
112 writableChannel.toByteArray());
113
114 writableChannel.flush();
115 outbuffer.flush(writableChannel);
116 Assert.assertArrayEquals(new byte[] {0,0,16,0,1,0,0,0,5,48,49,50,51,52,53,54,55,56,57,97,98,99,100,101,102},
117 writableChannel.toByteArray());
118 }
119
120 @Test
121 public void testReadFrameMultiple() throws Exception {
122 final FrameInputBuffer inBuffer = new FrameInputBuffer(16 * 1024);
123 final ReadableByteChannelMockMock.html#ReadableByteChannelMock">ReadableByteChannelMock readableChannel = new ReadableByteChannelMock(
124 new byte[] {
125 0,0,10,0,8,0,0,0,8,4,0,1,2,3,4,0,0,0,0,
126 0,0,10,0,9,0,0,0,8,4,5,6,7,8,9,0,0,0,0
127 });
128
129 final RawFrame frame1 = inBuffer.read(readableChannel);
130 Assert.assertEquals(FrameType.DATA, FrameType.valueOf(frame1.getType()));
131 Assert.assertEquals(8, frame1.getFlags());
132 Assert.assertEquals(8, frame1.getStreamId());
133 final ByteBuffer payload1 = frame1.getPayloadContent();
134 Assert.assertNotNull(payload1);
135 Assert.assertEquals(5, payload1.remaining());
136 Assert.assertEquals(0, payload1.get());
137 Assert.assertEquals(1, payload1.get());
138 Assert.assertEquals(2, payload1.get());
139 Assert.assertEquals(3, payload1.get());
140 Assert.assertEquals(4, payload1.get());
141
142 final RawFrame frame2 = inBuffer.read(readableChannel);
143 Assert.assertEquals(FrameType.DATA, FrameType.valueOf(frame2.getType()));
144 Assert.assertEquals(FrameFlag.of(FrameFlag.END_STREAM, FrameFlag.PADDED), frame2.getFlags());
145 Assert.assertEquals(8, frame2.getStreamId());
146 final ByteBuffer payload2 = frame2.getPayloadContent();
147 Assert.assertNotNull(payload2);
148 Assert.assertEquals(5, payload2.remaining());
149 Assert.assertEquals(5, payload2.get());
150 Assert.assertEquals(6, payload2.get());
151 Assert.assertEquals(7, payload2.get());
152 Assert.assertEquals(8, payload2.get());
153 Assert.assertEquals(9, payload2.get());
154
155 Assert.assertEquals(-1, readableChannel.read(ByteBuffer.allocate(1024)));
156 }
157
158 @Test
159 public void testReadFrameMultipleSmallBuffer() throws Exception {
160 final FrameInputBuffer inBuffer = new FrameInputBuffer(new BasicH2TransportMetrics(), 20, 10);
161 final ReadableByteChannelMockMock.html#ReadableByteChannelMock">ReadableByteChannelMock readableChannel = new ReadableByteChannelMock(
162 new byte[] {
163 0,0,10,0,8,0,0,0,8,4,1,1,1,1,1,0,0,0,0,
164 0,0,5,0,0,0,0,0,8,2,2,2,2,2,
165 0,0,10,0,9,0,0,0,8,4,3,3,3,3,3,0,0,0,0
166 });
167
168 final RawFrame frame1 = inBuffer.read(readableChannel);
169 Assert.assertEquals(FrameType.DATA, FrameType.valueOf(frame1.getType()));
170 Assert.assertEquals(8, frame1.getFlags());
171 Assert.assertEquals(8, frame1.getStreamId());
172 final ByteBuffer payload1 = frame1.getPayloadContent();
173 Assert.assertNotNull(payload1);
174 Assert.assertEquals(5, payload1.remaining());
175 Assert.assertEquals(1, payload1.get());
176 Assert.assertEquals(1, payload1.get());
177 Assert.assertEquals(1, payload1.get());
178 Assert.assertEquals(1, payload1.get());
179 Assert.assertEquals(1, payload1.get());
180
181 final RawFrame frame2 = inBuffer.read(readableChannel);
182 Assert.assertEquals(FrameType.DATA, FrameType.valueOf(frame2.getType()));
183 Assert.assertEquals(0, frame2.getFlags());
184 Assert.assertEquals(8, frame2.getStreamId());
185 final ByteBuffer payload2 = frame2.getPayloadContent();
186 Assert.assertNotNull(payload2);
187 Assert.assertEquals(5, payload2.remaining());
188 Assert.assertEquals(2, payload2.get());
189 Assert.assertEquals(2, payload2.get());
190 Assert.assertEquals(2, payload2.get());
191 Assert.assertEquals(2, payload2.get());
192 Assert.assertEquals(2, payload2.get());
193
194 final RawFrame frame3 = inBuffer.read(readableChannel);
195 Assert.assertEquals(FrameType.DATA, FrameType.valueOf(frame3.getType()));
196 Assert.assertEquals(FrameFlag.of(FrameFlag.END_STREAM, FrameFlag.PADDED), frame3.getFlags());
197 Assert.assertEquals(8, frame3.getStreamId());
198 final ByteBuffer payload3 = frame3.getPayloadContent();
199 Assert.assertNotNull(payload3);
200 Assert.assertEquals(5, payload3.remaining());
201 Assert.assertEquals(3, payload3.get());
202 Assert.assertEquals(3, payload3.get());
203 Assert.assertEquals(3, payload3.get());
204 Assert.assertEquals(3, payload3.get());
205 Assert.assertEquals(3, payload3.get());
206
207 Assert.assertEquals(-1, readableChannel.read(ByteBuffer.allocate(1024)));
208 }
209
210 @Test
211 public void testReadFramePartialReads() throws Exception {
212 final FrameInputBuffer inBuffer = new FrameInputBuffer(16 * 1024);
213 final ReadableByteChannelMockMock.html#ReadableByteChannelMock">ReadableByteChannelMock readableChannel = new ReadableByteChannelMock(
214 new byte[] {0,0},
215 new byte[] {10,0,9,0},
216 new byte[] {0,0,8},
217 new byte[] {4},
218 new byte[] {1,2,3,4},
219 new byte[] {5,0},
220 new byte[] {0,0,0});
221
222 final RawFrame frame = inBuffer.read(readableChannel);
223 Assert.assertEquals(FrameType.DATA, FrameType.valueOf(frame.getType()));
224 Assert.assertEquals(FrameFlag.of(FrameFlag.END_STREAM, FrameFlag.PADDED), frame.getFlags());
225 Assert.assertEquals(8, frame.getStreamId());
226 final ByteBuffer payload = frame.getPayloadContent();
227 Assert.assertNotNull(payload);
228 Assert.assertEquals(5, payload.remaining());
229 Assert.assertEquals(1, payload.get());
230 Assert.assertEquals(2, payload.get());
231 Assert.assertEquals(3, payload.get());
232 Assert.assertEquals(4, payload.get());
233 Assert.assertEquals(5, payload.get());
234
235 Assert.assertEquals(-1, readableChannel.read(ByteBuffer.allocate(1024)));
236 }
237
238 @Test
239 public void testReadEmptyFrame() throws Exception {
240 final FrameInputBuffer inBuffer = new FrameInputBuffer(16 * 1024);
241 final ReadableByteChannelMockMock.html#ReadableByteChannelMock">ReadableByteChannelMock readableChannel = new ReadableByteChannelMock(
242 new byte[] {0,0,0,0,0,0,0,0,0});
243
244 final RawFrame frame = inBuffer.read(readableChannel);
245 Assert.assertEquals(FrameType.DATA, FrameType.valueOf(frame.getType()));
246 Assert.assertEquals(0, frame.getFlags());
247 Assert.assertEquals(0, frame.getStreamId());
248 final ByteBuffer payload = frame.getPayloadContent();
249 Assert.assertNull(payload);
250 }
251
252 @Test(expected = ConnectionClosedException.class)
253 public void testReadFrameConnectionClosed() throws Exception {
254 final FrameInputBuffer inBuffer = new FrameInputBuffer(16 * 1024);
255 final ReadableByteChannelMockMock.html#ReadableByteChannelMock">ReadableByteChannelMock readableChannel = new ReadableByteChannelMock(new byte[] {});
256
257 Assert.assertEquals(null, inBuffer.read(readableChannel));
258 inBuffer.read(readableChannel);
259 }
260
261 @Test(expected = H2CorruptFrameException.class)
262 public void testReadFrameCorruptFrame() throws Exception {
263 final FrameInputBuffer inBuffer = new FrameInputBuffer(16 * 1024);
264 final ReadableByteChannelMockMock.html#ReadableByteChannelMock">ReadableByteChannelMock readableChannel = new ReadableByteChannelMock(new byte[] {0,0});
265
266 Assert.assertEquals(null, inBuffer.read(readableChannel));
267 inBuffer.read(readableChannel);
268 }
269
270 @Test(expected = IllegalArgumentException.class)
271 public void testWriteFrameExceedingLimit() throws Exception {
272 final WritableByteChannelMockMock.html#WritableByteChannelMock">WritableByteChannelMock writableChannel = new WritableByteChannelMock(1024);
273 final FrameOutputBuffer outbuffer = new FrameOutputBuffer(1024);
274
275 final RawFrame frame = new RawFrame(FrameType.DATA.getValue(), 0, 1,
276 ByteBuffer.wrap(new byte[2048]));
277 outbuffer.write(frame, writableChannel);
278 }
279
280 @Test(expected = H2ConnectionException.class)
281 public void testReadFrameExceedingLimit() throws Exception {
282 final FrameInputBuffer inBuffer = new FrameInputBuffer(16 * 1024);
283 final ReadableByteChannelMockMock.html#ReadableByteChannelMock">ReadableByteChannelMock readableChannel = new ReadableByteChannelMock(
284 new byte[] {0,-128,-128,0,0,0,0,0,1});
285
286 Assert.assertEquals(null, inBuffer.read(readableChannel));
287 inBuffer.read(readableChannel);
288 }
289
290 }
291