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.http.impl.nio;
29
30 import java.io.IOException;
31 import java.nio.ByteBuffer;
32 import java.nio.charset.StandardCharsets;
33 import java.util.Arrays;
34
35 import org.apache.hc.core5.http.WritableByteChannelMock;
36 import org.apache.hc.core5.http.impl.BasicHttpTransportMetrics;
37 import org.apache.hc.core5.http.message.BasicHeader;
38 import org.apache.hc.core5.http.nio.SessionOutputBuffer;
39 import org.junit.Assert;
40 import org.junit.Test;
41 import org.mockito.ArgumentMatchers;
42 import org.mockito.Mockito;
43
44
45
46
47 public class TestChunkEncoder {
48
49 @Test
50 public void testBasicCoding() throws Exception {
51 final WritableByteChannelMockChannelMock.html#WritableByteChannelMock">WritableByteChannelMock channel = new WritableByteChannelMock(64);
52 final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
53 final BasicHttpTransportMetrics metrics = new BasicHttpTransportMetrics();
54 final ChunkEncoder encoder = new ChunkEncoder(channel, outbuf, metrics);
55
56 encoder.write(CodecTestUtils.wrap("12345"));
57 encoder.write(CodecTestUtils.wrap("678"));
58 encoder.write(CodecTestUtils.wrap("90"));
59 encoder.complete();
60
61 outbuf.flush(channel);
62
63 final String s = channel.dump(StandardCharsets.US_ASCII);
64
65 Assert.assertTrue(encoder.isCompleted());
66 Assert.assertEquals("5\r\n12345\r\n3\r\n678\r\n2\r\n90\r\n0\r\n\r\n", s);
67 Assert.assertEquals("[chunk-coded; completed: true]", encoder.toString());
68 }
69
70 @Test
71 public void testChunkNoExceed() throws Exception {
72 final WritableByteChannelMockChannelMock.html#WritableByteChannelMock">WritableByteChannelMock channel = new WritableByteChannelMock(64);
73 final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 16);
74 final BasicHttpTransportMetrics metrics = new BasicHttpTransportMetrics();
75 final ChunkEncoder encoder = new ChunkEncoder(channel, outbuf, metrics);
76 encoder.write(CodecTestUtils.wrap("1234"));
77 encoder.complete();
78
79 outbuf.flush(channel);
80
81 final String s = channel.dump(StandardCharsets.US_ASCII);
82
83 Assert.assertTrue(encoder.isCompleted());
84 Assert.assertEquals("4\r\n1234\r\n0\r\n\r\n", s);
85 }
86
87 @Test
88 public void testLimitedChannel() throws Exception {
89 final WritableByteChannelMockChannelMock.html#WritableByteChannelMock">WritableByteChannelMock channel = new WritableByteChannelMock(16, 16);
90 final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(16, 16);
91 final BasicHttpTransportMetrics metrics = new BasicHttpTransportMetrics();
92 final ChunkEncoder encoder = new ChunkEncoder(channel, outbuf, metrics);
93
94
95 channel.write(CodecTestUtils.wrap("0123456789ABCDEF"));
96
97 outbuf.write(CodecTestUtils.wrap("0123456789ABCDEF"));
98
99 final ByteBuffer src = CodecTestUtils.wrap("0123456789ABCDEF");
100 Assert.assertEquals(0, encoder.write(src));
101 Assert.assertEquals(0, encoder.write(src));
102 Assert.assertEquals(0, encoder.write(src));
103
104
105 channel.reset();
106 outbuf.flush(channel);
107 channel.reset();
108
109 Assert.assertEquals(10, encoder.write(src));
110 channel.flush();
111 Assert.assertEquals(6, encoder.write(src));
112 channel.flush();
113 Assert.assertEquals(0, encoder.write(src));
114
115 outbuf.flush(channel);
116 final String s = channel.dump(StandardCharsets.US_ASCII);
117 Assert.assertEquals("4\r\n0123\r\n4\r\n4567\r\n2\r\n89\r\n4\r\nABCD\r\n2\r\nEF\r\n", s);
118 }
119
120 @Test
121 public void testBufferFragments() throws Exception {
122 final WritableByteChannelMockhtml#WritableByteChannelMock">WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(1024));
123 final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 1024);
124 final BasicHttpTransportMetrics metrics = new BasicHttpTransportMetrics();
125 final ChunkEncoder encoder = new ChunkEncoder(channel, outbuf, metrics, 1024);
126
127 Assert.assertEquals(16, encoder.write(CodecTestUtils.wrap("0123456789ABCDEF")));
128 Assert.assertEquals(16, encoder.write(CodecTestUtils.wrap("0123456789ABCDEF")));
129 Assert.assertEquals(16, encoder.write(CodecTestUtils.wrap("0123456789ABCDEF")));
130
131 Mockito.verify(channel, Mockito.never()).write(ArgumentMatchers.<ByteBuffer>any());
132
133 outbuf.flush(channel);
134 final String s = channel.dump(StandardCharsets.US_ASCII);
135 Assert.assertEquals("10\r\n0123456789ABCDEF\r\n10\r\n0123456789ABCDEF\r\n" +
136 "10\r\n0123456789ABCDEF\r\n", s);
137 }
138
139 @Test
140 public void testChunkExceed() throws Exception {
141 final WritableByteChannelMockChannelMock.html#WritableByteChannelMock">WritableByteChannelMock channel = new WritableByteChannelMock(64);
142 final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(16, 16);
143 final BasicHttpTransportMetrics metrics = new BasicHttpTransportMetrics();
144 final ChunkEncoder encoder = new ChunkEncoder(channel, outbuf, metrics);
145
146 final ByteBuffer src = CodecTestUtils.wrap("0123456789ABCDEF");
147
148 Assert.assertEquals(16, encoder.write(src));
149 Assert.assertEquals(0, src.remaining());
150
151 outbuf.flush(channel);
152 final String s = channel.dump(StandardCharsets.US_ASCII);
153 Assert.assertEquals("4\r\n0123\r\n4\r\n4567\r\n4\r\n89AB\r\n4\r\nCDEF\r\n", s);
154
155 }
156
157 @Test
158 public void testCodingEmptyBuffer() throws Exception {
159 final WritableByteChannelMockChannelMock.html#WritableByteChannelMock">WritableByteChannelMock channel = new WritableByteChannelMock(64);
160 final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
161 final BasicHttpTransportMetrics metrics = new BasicHttpTransportMetrics();
162 final ChunkEncoder encoder = new ChunkEncoder(channel, outbuf, metrics);
163
164 encoder.write(CodecTestUtils.wrap("12345"));
165 encoder.write(CodecTestUtils.wrap("678"));
166 encoder.write(CodecTestUtils.wrap("90"));
167
168 final ByteBuffer empty = ByteBuffer.allocate(100);
169 empty.flip();
170 encoder.write(empty);
171 encoder.write(null);
172
173 encoder.complete();
174
175 outbuf.flush(channel);
176
177 final String s = channel.dump(StandardCharsets.US_ASCII);
178
179 Assert.assertTrue(encoder.isCompleted());
180 Assert.assertEquals("5\r\n12345\r\n3\r\n678\r\n2\r\n90\r\n0\r\n\r\n", s);
181 }
182
183 @Test
184 public void testCodingCompleted() throws Exception {
185 final WritableByteChannelMockChannelMock.html#WritableByteChannelMock">WritableByteChannelMock channel = new WritableByteChannelMock(64);
186 final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
187 final BasicHttpTransportMetrics metrics = new BasicHttpTransportMetrics();
188 final ChunkEncoder encoder = new ChunkEncoder(channel, outbuf, metrics);
189
190 encoder.write(CodecTestUtils.wrap("12345"));
191 encoder.write(CodecTestUtils.wrap("678"));
192 encoder.write(CodecTestUtils.wrap("90"));
193 encoder.complete();
194
195 try {
196 encoder.write(CodecTestUtils.wrap("more stuff"));
197 Assert.fail("IllegalStateException should have been thrown");
198 } catch (final IllegalStateException ex) {
199
200 }
201 try {
202 encoder.complete();
203 Assert.fail("IllegalStateException should have been thrown");
204 } catch (final IllegalStateException ex) {
205
206 }
207 }
208
209 @Test
210 public void testInvalidConstructor() {
211 final WritableByteChannelMockChannelMock.html#WritableByteChannelMock">WritableByteChannelMock channel = new WritableByteChannelMock(64);
212 final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
213
214 try {
215 new ChunkEncoder(null, null, null);
216 Assert.fail("NullPointerException should have been thrown");
217 } catch (final NullPointerException ex) {
218
219 }
220 try {
221 new ChunkEncoder(channel, null, null);
222 Assert.fail("NullPointerException should have been thrown");
223 } catch (final NullPointerException ex) {
224
225 }
226 try {
227 new ChunkEncoder(channel, outbuf, null);
228 Assert.fail("NullPointerException should have been thrown");
229 } catch (final NullPointerException ex) {
230
231 }
232 }
233
234 @Test
235 public void testTrailers() throws IOException {
236 final WritableByteChannelMockChannelMock.html#WritableByteChannelMock">WritableByteChannelMock channel = new WritableByteChannelMock(64);
237 final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
238 final BasicHttpTransportMetrics metrics = new BasicHttpTransportMetrics();
239 final ChunkEncoder encoder = new ChunkEncoder(channel, outbuf, metrics, 0);
240 encoder.write(CodecTestUtils.wrap("1"));
241 encoder.write(CodecTestUtils.wrap("23"));
242 encoder.complete(Arrays.asList(new BasicHeader("E", ""), new BasicHeader("Y", "Z")));
243
244 outbuf.flush(channel);
245
246 final String s = channel.dump(StandardCharsets.US_ASCII);
247
248 Assert.assertTrue(encoder.isCompleted());
249 Assert.assertEquals("1\r\n1\r\n2\r\n23\r\n0\r\nE: \r\nY: Z\r\n\r\n", s);
250 Assert.assertEquals("[chunk-coded; completed: true]", encoder.toString());
251 }
252 }