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