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.http.impl.nio.codecs;
29
30 import java.io.IOException;
31 import java.nio.ByteBuffer;
32 import java.nio.channels.ReadableByteChannel;
33
34 import org.apache.http.ConnectionClosedException;
35 import org.apache.http.Consts;
36 import org.apache.http.Header;
37 import org.apache.http.MalformedChunkCodingException;
38 import org.apache.http.MessageConstraintException;
39 import org.apache.http.ReadableByteChannelMock;
40 import org.apache.http.TruncatedChunkException;
41 import org.apache.http.config.MessageConstraints;
42 import org.apache.http.impl.io.HttpTransportMetricsImpl;
43 import org.apache.http.impl.nio.reactor.SessionInputBufferImpl;
44 import org.apache.http.nio.reactor.SessionInputBuffer;
45 import org.junit.Assert;
46 import org.junit.Test;
47
48
49
50
51 public class TestChunkDecoder {
52
53 @Test
54 public void testBasicDecoding() throws Exception {
55 final String s = "5\r\n01234\r\n5\r\n56789\r\n6\r\nabcdef\r\n0\r\n\r\n";
56 final ReadableByteChannel channel = new ReadableByteChannelMock(
57 new String[] {s}, Consts.ASCII);
58 final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
59 final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
60 final ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
61
62 final ByteBuffer dst = ByteBuffer.allocate(1024);
63
64 int bytesRead = decoder.read(dst);
65 Assert.assertEquals(16, bytesRead);
66 Assert.assertEquals("0123456789abcdef", CodecTestUtils.convert(dst));
67 final Header[] footers = decoder.getFooters();
68 Assert.assertEquals(0, footers.length);
69
70 dst.clear();
71 bytesRead = decoder.read(dst);
72 Assert.assertEquals(-1, bytesRead);
73 Assert.assertTrue(decoder.isCompleted());
74 Assert.assertEquals("[chunk-coded; completed: true]", decoder.toString());
75 }
76
77 @Test
78 public void testComplexDecoding() throws Exception {
79 final String s = "10;key=\"value\"\r\n1234567890123456\r\n" +
80 "5\r\n12345\r\n5\r\n12345\r\n0\r\nFooter1: abcde\r\nFooter2: fghij\r\n\r\n";
81 final ReadableByteChannel channel = new ReadableByteChannelMock(
82 new String[] {s}, Consts.ASCII);
83
84 final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
85 final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
86 final ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
87
88 final ByteBuffer dst = ByteBuffer.allocate(1024);
89
90 int bytesRead = 0;
91 while (dst.hasRemaining() && !decoder.isCompleted()) {
92 final int i = decoder.read(dst);
93 if (i > 0) {
94 bytesRead += i;
95 }
96 }
97
98 Assert.assertEquals(26, bytesRead);
99 Assert.assertEquals("12345678901234561234512345", CodecTestUtils.convert(dst));
100
101 final Header[] footers = decoder.getFooters();
102 Assert.assertEquals(2, footers.length);
103 Assert.assertEquals("Footer1", footers[0].getName());
104 Assert.assertEquals("abcde", footers[0].getValue());
105 Assert.assertEquals("Footer2", footers[1].getName());
106 Assert.assertEquals("fghij", footers[1].getValue());
107
108 dst.clear();
109 bytesRead = decoder.read(dst);
110 Assert.assertEquals(-1, bytesRead);
111 Assert.assertTrue(decoder.isCompleted());
112 }
113
114 @Test
115 public void testDecodingWithSmallBuffer() throws Exception {
116 final String s1 = "5\r\n01234\r\n5\r\n5678";
117 final String s2 = "9\r\n6\r\nabcdef\r\n0\r\n\r\n";
118 final ReadableByteChannel channel = new ReadableByteChannelMock(
119 new String[] {s1, s2}, Consts.ASCII);
120
121 final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
122 final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
123 final ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
124
125 final ByteBuffer dst = ByteBuffer.allocate(1024);
126 final ByteBuffer tmp = ByteBuffer.allocate(4);
127
128 int bytesRead = 0;
129 while (dst.hasRemaining() && !decoder.isCompleted()) {
130 final int i = decoder.read(tmp);
131 if (i > 0) {
132 bytesRead += i;
133 }
134 tmp.flip();
135 dst.put(tmp);
136 tmp.compact();
137 }
138
139 Assert.assertEquals(16, bytesRead);
140 Assert.assertEquals("0123456789abcdef", CodecTestUtils.convert(dst));
141 Assert.assertTrue(decoder.isCompleted());
142
143 dst.clear();
144 bytesRead = decoder.read(dst);
145 Assert.assertEquals(-1, bytesRead);
146 Assert.assertTrue(decoder.isCompleted());
147 }
148
149 @Test
150 public void testMalformedChunk() throws Exception {
151 final String s = "5\r\n01234----------------------------------------------------------" +
152 "-----------------------------------------------------------------------------" +
153 "-----------------------------------------------------------------------------";
154 final ReadableByteChannel channel = new ReadableByteChannelMock(
155 new String[] {s}, Consts.ASCII);
156
157 final SessionInputBuffer inbuf = new SessionInputBufferImpl(32, 32, Consts.ASCII);
158 final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
159 final ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
160
161 final ByteBuffer dst = ByteBuffer.allocate(1024);
162
163 try {
164 decoder.read(dst);
165 Assert.fail("MalformedChunkCodingException should have been thrown");
166 } catch (final MalformedChunkCodingException ex) {
167
168 }
169 }
170
171 @Test
172 public void testIncompleteChunkDecoding() throws Exception {
173 final String[] chunks = {
174 "10;",
175 "key=\"value\"\r",
176 "\n123456789012345",
177 "6\r\n5\r\n12",
178 "345\r\n6\r",
179 "\nabcdef\r",
180 "\n0\r\nFoot",
181 "er1: abcde\r\nFooter2: f",
182 "ghij\r\n\r\n"
183 };
184 final ReadableByteChannel channel = new ReadableByteChannelMock(
185 chunks, Consts.ASCII);
186
187 final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
188 final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
189 final ByteBuffer dst = ByteBuffer.allocate(1024);
190
191 final ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
192
193 int bytesRead = 0;
194 while (dst.hasRemaining() && !decoder.isCompleted()) {
195 final int i = decoder.read(dst);
196 if (i > 0) {
197 bytesRead += i;
198 }
199 }
200
201 Assert.assertEquals(27, bytesRead);
202 Assert.assertEquals("123456789012345612345abcdef", CodecTestUtils.convert(dst));
203 Assert.assertTrue(decoder.isCompleted());
204
205 final Header[] footers = decoder.getFooters();
206 Assert.assertEquals(2, footers.length);
207 Assert.assertEquals("Footer1", footers[0].getName());
208 Assert.assertEquals("abcde", footers[0].getValue());
209 Assert.assertEquals("Footer2", footers[1].getName());
210 Assert.assertEquals("fghij", footers[1].getValue());
211
212 dst.clear();
213 bytesRead = decoder.read(dst);
214 Assert.assertEquals(-1, bytesRead);
215 Assert.assertTrue(decoder.isCompleted());
216 }
217
218 @Test(expected=MalformedChunkCodingException.class)
219 public void testMalformedChunkSizeDecoding() throws Exception {
220 final String s = "5\r\n01234\r\n5zz\r\n56789\r\n6\r\nabcdef\r\n0\r\n\r\n";
221 final ReadableByteChannel channel = new ReadableByteChannelMock(
222 new String[] {s}, Consts.ASCII);
223
224 final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
225 final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
226 final ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
227
228 final ByteBuffer dst = ByteBuffer.allocate(1024);
229 decoder.read(dst);
230 }
231
232 @Test(expected=MalformedChunkCodingException.class)
233 public void testMalformedChunkEndingDecoding() throws Exception {
234 final String s = "5\r\n01234\r\n5\r\n56789\r\r6\r\nabcdef\r\n0\r\n\r\n";
235 final ReadableByteChannel channel = new ReadableByteChannelMock(
236 new String[] {s}, Consts.ASCII);
237
238 final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
239 final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
240 final ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
241
242 final ByteBuffer dst = ByteBuffer.allocate(1024);
243 decoder.read(dst);
244 }
245
246 @Test(expected=TruncatedChunkException.class)
247 public void testMalformedChunkTruncatedChunk() throws Exception {
248 final String s = "3\r\n12";
249 final ReadableByteChannel channel = new ReadableByteChannelMock(
250 new String[] {s}, Consts.ASCII);
251
252 final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
253 final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
254 final ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
255
256 final ByteBuffer dst = ByteBuffer.allocate(1024);
257 Assert.assertEquals(2, decoder.read(dst));
258 decoder.read(dst);
259 }
260
261 @Test
262 public void testFoldedFooters() throws Exception {
263 final String s = "10;key=\"value\"\r\n1234567890123456\r\n" +
264 "5\r\n12345\r\n5\r\n12345\r\n0\r\nFooter1: abcde\r\n \r\n fghij\r\n\r\n";
265 final ReadableByteChannel channel = new ReadableByteChannelMock(
266 new String[] {s}, Consts.ASCII);
267
268 final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
269 final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
270 final ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
271
272 final ByteBuffer dst = ByteBuffer.allocate(1024);
273
274 final int bytesRead = decoder.read(dst);
275 Assert.assertEquals(26, bytesRead);
276 Assert.assertEquals("12345678901234561234512345", CodecTestUtils.convert(dst));
277
278 final Header[] footers = decoder.getFooters();
279 Assert.assertEquals(1, footers.length);
280 Assert.assertEquals("Footer1", footers[0].getName());
281 Assert.assertEquals("abcde fghij", footers[0].getValue());
282 }
283
284 @Test(expected=IOException.class)
285 public void testMalformedFooters() throws Exception {
286 final String s = "10;key=\"value\"\r\n1234567890123456\r\n" +
287 "5\r\n12345\r\n5\r\n12345\r\n0\r\nFooter1 abcde\r\n\r\n";
288 final ReadableByteChannel channel = new ReadableByteChannelMock(
289 new String[] {s}, Consts.ASCII);
290
291 final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
292 final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
293 final ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
294
295 final ByteBuffer dst = ByteBuffer.allocate(1024);
296 decoder.read(dst);
297 }
298
299 @Test(expected=MalformedChunkCodingException.class)
300 public void testMissingLastCRLF() throws Exception {
301 final String s = "10\r\n1234567890123456\r\n" +
302 "5\r\n12345\r\n5\r\n12345";
303 final ReadableByteChannel channel = new ReadableByteChannelMock(
304 new String[] {s}, Consts.ASCII);
305
306 final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
307 final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
308 final ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
309
310 final ByteBuffer dst = ByteBuffer.allocate(1024);
311
312 while (dst.hasRemaining() && !decoder.isCompleted()) {
313 decoder.read(dst);
314 }
315 }
316
317 @Test(expected=ConnectionClosedException.class)
318 public void testMissingClosingChunk() throws Exception {
319 final String s = "10\r\n1234567890123456\r\n" +
320 "5\r\n12345\r\n5\r\n12345\r\n";
321 final ReadableByteChannel channel = new ReadableByteChannelMock(
322 new String[] {s}, Consts.ASCII);
323
324 final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
325 final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
326 final ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
327
328 final ByteBuffer dst = ByteBuffer.allocate(1024);
329
330 long bytesRead = 0;
331 try {
332 while (dst.hasRemaining() && !decoder.isCompleted()) {
333 final int i = decoder.read(dst);
334 if (i > 0) {
335 bytesRead += i;
336 }
337 }
338 } catch (final MalformedChunkCodingException ex) {
339 Assert.assertEquals(26L, bytesRead);
340 Assert.assertEquals("12345678901234561234512345", CodecTestUtils.convert(dst));
341 Assert.assertTrue(decoder.isCompleted());
342 throw ex;
343 }
344 }
345
346 @Test
347 public void testReadingWitSmallBuffer() throws Exception {
348 final String s = "10\r\n1234567890123456\r\n" +
349 "40\r\n12345678901234561234567890123456" +
350 "12345678901234561234567890123456\r\n0\r\n";
351 final ReadableByteChannel channel = new ReadableByteChannelMock(
352 new String[] {s}, Consts.ASCII);
353
354 final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
355 final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
356 final ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
357
358 final ByteBuffer dst = ByteBuffer.allocate(1024);
359 final ByteBuffer tmp = ByteBuffer.allocate(10);
360
361 int bytesRead = 0;
362 while (dst.hasRemaining() && !decoder.isCompleted()) {
363 final int i = decoder.read(tmp);
364 if (i > 0) {
365 bytesRead += i;
366 tmp.flip();
367 dst.put(tmp);
368 tmp.compact();
369 }
370 }
371
372 Assert.assertEquals(80, bytesRead);
373 Assert.assertEquals("12345678901234561234567890123456" +
374 "12345678901234561234567890123456" +
375 "1234567890123456", CodecTestUtils.convert(dst));
376 Assert.assertTrue(decoder.isCompleted());
377 }
378
379 @Test
380 public void testEndOfStreamConditionReadingFooters() throws Exception {
381 final String s = "10\r\n1234567890123456\r\n" +
382 "5\r\n12345\r\n5\r\n12345\r\n0\r\n";
383 final ReadableByteChannel channel = new ReadableByteChannelMock(
384 new String[] {s}, Consts.ASCII);
385
386 final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
387 final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
388 final ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
389
390 final ByteBuffer dst = ByteBuffer.allocate(1024);
391
392 int bytesRead = 0;
393 while (dst.hasRemaining() && !decoder.isCompleted()) {
394 final int i = decoder.read(dst);
395 if (i > 0) {
396 bytesRead += i;
397 }
398 }
399
400 Assert.assertEquals(26, bytesRead);
401 Assert.assertEquals("12345678901234561234512345", CodecTestUtils.convert(dst));
402 Assert.assertTrue(decoder.isCompleted());
403 }
404
405 @Test
406 public void testTooLongChunkHeader() throws Exception {
407 final String s = "5; and some very looooong comment\r\n12345\r\n0\r\n";
408 final ReadableByteChannel channel1 = new ReadableByteChannelMock(
409 new String[] {s}, Consts.ASCII);
410
411 final SessionInputBuffer inbuf1 = new SessionInputBufferImpl(1024, 256,
412 MessageConstraints.DEFAULT, null, null);
413 final HttpTransportMetricsImpl metrics1 = new HttpTransportMetricsImpl();
414 final ChunkDecoder decoder1 = new ChunkDecoder(channel1, inbuf1, metrics1);
415
416 final ByteBuffer dst = ByteBuffer.allocate(1024);
417
418 while (dst.hasRemaining() && !decoder1.isCompleted()) {
419 decoder1.read(dst);
420 }
421 Assert.assertEquals("12345", CodecTestUtils.convert(dst));
422 Assert.assertTrue(decoder1.isCompleted());
423
424 final ReadableByteChannel channel2 = new ReadableByteChannelMock(
425 new String[] {s}, Consts.ASCII);
426
427 final SessionInputBuffer inbuf2 = new SessionInputBufferImpl(1024, 256,
428 MessageConstraints.lineLen(10), null, null);
429 final HttpTransportMetricsImpl metrics2 = new HttpTransportMetricsImpl();
430 final ChunkDecoder decoder2 = new ChunkDecoder(channel2, inbuf2, metrics2);
431
432 dst.clear();
433 try {
434 decoder2.read(dst);
435 Assert.fail("MessageConstraintException expected");
436 } catch (final MessageConstraintException ex) {
437 }
438 }
439
440 @Test
441 public void testTooLongFooter() throws Exception {
442 final String s = "10\r\n1234567890123456\r\n" +
443 "0\r\nFooter1: looooooooooooooooooooooooooooooooooooooooooooooooooooooog\r\n\r\n";
444
445
446 final ReadableByteChannel channel1 = new ReadableByteChannelMock(
447 new String[] {s}, Consts.ASCII);
448 final SessionInputBuffer inbuf1 = new SessionInputBufferImpl(1024, 256,
449 MessageConstraints.DEFAULT, Consts.ASCII);
450 final HttpTransportMetricsImpl metrics1 = new HttpTransportMetricsImpl();
451 final ChunkDecoder decoder1 = new ChunkDecoder(channel1, inbuf1, metrics1);
452
453 final ByteBuffer dst = ByteBuffer.allocate(1024);
454
455 final int bytesRead = decoder1.read(dst);
456 Assert.assertEquals(16, bytesRead);
457 Assert.assertEquals("1234567890123456", CodecTestUtils.convert(dst));
458 final Header[] footers = decoder1.getFooters();
459 Assert.assertNotNull(footers);
460 Assert.assertEquals(1, footers.length);
461
462 final ReadableByteChannel channel2 = new ReadableByteChannelMock(
463 new String[] {s}, Consts.ASCII);
464 final SessionInputBuffer inbuf2 = new SessionInputBufferImpl(1024, 256,
465 MessageConstraints.lineLen(25), Consts.ASCII);
466 final HttpTransportMetricsImpl metrics2 = new HttpTransportMetricsImpl();
467 final ChunkDecoder decoder2 = new ChunkDecoder(channel2, inbuf2, metrics2);
468
469 dst.clear();
470 try {
471 decoder2.read(dst);
472 Assert.fail("MessageConstraintException expected");
473 } catch (final MessageConstraintException ex) {
474 }
475 }
476
477 @Test
478 public void testTooLongFoldedFooter() throws Exception {
479 final String s = "10\r\n1234567890123456\r\n" +
480 "0\r\nFooter1: blah\r\n blah\r\n blah\r\n blah\r\n blah\r\n blah\r\n blah\r\n blah\r\n\r\n";
481 final ReadableByteChannel channel1 = new ReadableByteChannelMock(
482 new String[] {s}, Consts.ASCII);
483 final SessionInputBuffer inbuf1 = new SessionInputBufferImpl(1024, 256,
484 MessageConstraints.DEFAULT, Consts.ASCII);
485 final HttpTransportMetricsImpl metrics1 = new HttpTransportMetricsImpl();
486 final ChunkDecoder decoder1 = new ChunkDecoder(channel1, inbuf1, metrics1);
487
488 final ByteBuffer dst = ByteBuffer.allocate(1024);
489
490 final int bytesRead = decoder1.read(dst);
491 Assert.assertEquals(16, bytesRead);
492 Assert.assertEquals("1234567890123456", CodecTestUtils.convert(dst));
493 final Header[] footers = decoder1.getFooters();
494 Assert.assertNotNull(footers);
495 Assert.assertEquals(1, footers.length);
496
497 final MessageConstraints constraints = MessageConstraints.lineLen(25);
498 final ReadableByteChannel channel2 = new ReadableByteChannelMock(
499 new String[] {s}, Consts.ASCII);
500 final SessionInputBuffer inbuf2 = new SessionInputBufferImpl(1024, 256,
501 constraints, Consts.ASCII);
502 final HttpTransportMetricsImpl metrics2 = new HttpTransportMetricsImpl();
503 final ChunkDecoder decoder2 = new ChunkDecoder(channel2, inbuf2, constraints, metrics2);
504
505 dst.clear();
506 try {
507 decoder2.read(dst);
508 Assert.fail("MessageConstraintException expected");
509 } catch (final MessageConstraintException ex) {
510 }
511 }
512
513 @Test
514 public void testTooManyFooters() throws Exception {
515 final String s = "10\r\n1234567890123456\r\n" +
516 "0\r\nFooter1: blah\r\nFooter2: blah\r\nFooter3: blah\r\nFooter4: blah\r\n\r\n";
517 final ReadableByteChannel channel1 = new ReadableByteChannelMock(
518 new String[] {s}, Consts.ASCII);
519 final SessionInputBuffer inbuf1 = new SessionInputBufferImpl(1024, 256,
520 MessageConstraints.DEFAULT, Consts.ASCII);
521 final HttpTransportMetricsImpl metrics1 = new HttpTransportMetricsImpl();
522 final ChunkDecoder decoder1 = new ChunkDecoder(channel1, inbuf1, metrics1);
523
524 final ByteBuffer dst = ByteBuffer.allocate(1024);
525
526 final int bytesRead = decoder1.read(dst);
527 Assert.assertEquals(16, bytesRead);
528 Assert.assertEquals("1234567890123456", CodecTestUtils.convert(dst));
529 final Header[] footers = decoder1.getFooters();
530 Assert.assertNotNull(footers);
531 Assert.assertEquals(4, footers.length);
532
533 final MessageConstraints constraints = MessageConstraints.custom()
534 .setMaxHeaderCount(3).build();
535 final ReadableByteChannel channel2 = new ReadableByteChannelMock(
536 new String[] {s}, Consts.ASCII);
537 final SessionInputBuffer inbuf2 = new SessionInputBufferImpl(1024, 256,
538 constraints, Consts.ASCII);
539 final HttpTransportMetricsImpl metrics2 = new HttpTransportMetricsImpl();
540 final ChunkDecoder decoder2 = new ChunkDecoder(channel2, inbuf2, constraints, metrics2);
541
542 dst.clear();
543 try {
544 decoder2.read(dst);
545 Assert.fail("MessageConstraintException expected");
546 } catch (final MessageConstraintException ex) {
547 }
548 }
549
550 @Test
551 public void testInvalidConstructor() {
552 final ReadableByteChannel channel = new ReadableByteChannelMock(
553 new String[] {"stuff;", "more stuff"}, Consts.ASCII);
554
555 final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
556 try {
557 new ChunkDecoder(null, null, null);
558 Assert.fail("IllegalArgumentException should have been thrown");
559 } catch (final IllegalArgumentException ex) {
560
561 }
562 try {
563 new ChunkDecoder(channel, null, null);
564 Assert.fail("IllegalArgumentException should have been thrown");
565 } catch (final IllegalArgumentException ex) {
566
567 }
568 try {
569 new ChunkDecoder(channel, inbuf, null);
570 Assert.fail("IllegalArgumentException should have been thrown");
571 } catch (final IllegalArgumentException ex) {
572
573 }
574 }
575
576 @Test(expected=IllegalArgumentException.class)
577 public void testInvalidInput() throws Exception {
578 final String s = "10;key=\"value\"\r\n1234567890123456\r\n" +
579 "5\r\n12345\r\n5\r\n12345\r\n0\r\nFooter1 abcde\r\n\r\n";
580 final ReadableByteChannel channel = new ReadableByteChannelMock(
581 new String[] {s}, Consts.ASCII);
582
583 final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
584 final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
585 final ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
586 decoder.read(null);
587 }
588
589 @Test
590 public void testHugeChunk() throws Exception {
591 final String s = "1234567890abcdef\r\n0123456789abcdef";
592 final ReadableByteChannel channel = new ReadableByteChannelMock(
593 new String[] {s}, Consts.ASCII);
594 final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
595 final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
596 final ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
597
598 final ByteBuffer dst = ByteBuffer.allocate(4);
599
600 int bytesRead = decoder.read(dst);
601 Assert.assertEquals(4, bytesRead);
602 Assert.assertEquals("0123", CodecTestUtils.convert(dst));
603 dst.clear();
604 bytesRead = decoder.read(dst);
605 Assert.assertEquals(4, bytesRead);
606 Assert.assertEquals("4567", CodecTestUtils.convert(dst));
607 }
608
609 }