protected InputStream createContentInputStream( final long len, final SessionInputBuffer buffer, final InputStream inputStream) { if (len > 0) { return new ContentLengthInputStream(buffer, inputStream, len); } else if (len == 0) { return EmptyInputStream.INSTANCE; } else if (len == ContentLengthStrategy.CHUNKED) { return new ChunkedInputStream(buffer, inputStream, this.h1Config); } else { return new IdentityInputStream(buffer, inputStream); } }
protected InputStream createContentInputStream( final long len, final SessionInputBuffer buffer, final InputStream inputStream) { if (len > 0) { return new ContentLengthInputStream(buffer, inputStream, len); } else if (len == 0) { return EmptyInputStream.INSTANCE; } else if (len == ContentLengthStrategy.CHUNKED) { return new ChunkedInputStream(buffer, inputStream, this.h1Config); } else { return new IdentityInputStream(buffer, inputStream); } }
@Test public void testHugeChunk() throws IOException { final SessionInputBuffer inBuffer = new SessionInputBufferImpl(16); final ByteArrayInputStream inputStream = new ByteArrayInputStream("1234567890abcdef\r\n01234567".getBytes( StandardCharsets.ISO_8859_1)); final ChunkedInputStream in = new ChunkedInputStream(inBuffer, inputStream); final ByteArrayOutputStream out = new ByteArrayOutputStream(); for (int i = 0; i < 8; ++i) { out.write(in.read()); } final String result = new String(out.toByteArray(), StandardCharsets.ISO_8859_1); Assert.assertEquals("01234567", result); }
@Test(expected=MalformedChunkCodingException.class) public void testCorruptChunkedInputStreamMissingCRLF() throws IOException { final String s = "5\r\n012345\r\n56789\r\n0\r\n"; final SessionInputBuffer inBuffer = new SessionInputBufferImpl(16); final ByteArrayInputStream inputStream = new ByteArrayInputStream(s.getBytes(StandardCharsets.ISO_8859_1)); final ChunkedInputStream in = new ChunkedInputStream(inBuffer, inputStream); final byte[] buffer = new byte[300]; final ByteArrayOutputStream out = new ByteArrayOutputStream(); int len; while ((len = in.read(buffer)) > 0) { out.write(buffer, 0, len); } in.close(); }
@Test(expected = MalformedChunkCodingException.class) public void testCorruptChunkedInputStreamNegativeSize() throws IOException { final String s = "-5\r\n01234\r\n5\r\n56789\r\n0\r\n"; final SessionInputBuffer inBuffer = new SessionInputBufferImpl(16); final ByteArrayInputStream inputStream = new ByteArrayInputStream(s.getBytes(StandardCharsets.ISO_8859_1)); final ChunkedInputStream in = new ChunkedInputStream(inBuffer, inputStream); in.read(); in.close(); }
@Test public void testEmptyChunkedInputStream() throws IOException { final String s = "0\r\n"; final SessionInputBuffer inBuffer = new SessionInputBufferImpl(16); final ByteArrayInputStream inputStream = new ByteArrayInputStream(s.getBytes(StandardCharsets.ISO_8859_1)); final ChunkedInputStream in = new ChunkedInputStream(inBuffer, inputStream); final byte[] buffer = new byte[300]; final ByteArrayOutputStream out = new ByteArrayOutputStream(); int len; while ((len = in.read(buffer)) > 0) { out.write(buffer, 0, len); } Assert.assertEquals(0, out.size()); in.close(); }
@Test(expected=MalformedChunkCodingException.class) public void testCorruptChunkedInputStreamMissingLF() throws IOException { final String s = "5\r01234\r\n5\r\n56789\r\n0\r\n"; final SessionInputBuffer inBuffer = new SessionInputBufferImpl(16); final ByteArrayInputStream inputStream = new ByteArrayInputStream(s.getBytes(StandardCharsets.ISO_8859_1)); final ChunkedInputStream in = new ChunkedInputStream(inBuffer, inputStream); in.read(); in.close(); }
@Test(expected = MalformedChunkCodingException.class) public void testCorruptChunkedInputStreamInvalidSize() throws IOException { final String s = "whatever\r\n01234\r\n5\r\n56789\r\n0\r\n"; final SessionInputBuffer inBuffer = new SessionInputBufferImpl(16); final ByteArrayInputStream inputStream = new ByteArrayInputStream(s.getBytes(StandardCharsets.ISO_8859_1)); final ChunkedInputStream in = new ChunkedInputStream(inBuffer, inputStream); in.read(); in.close(); }
@Test(expected = MalformedChunkCodingException.class) public void testCorruptChunkedInputStreamInvalidFooter() throws IOException { final String s = "1\r\n0\r\n0\r\nstuff\r\n"; final SessionInputBuffer inBuffer = new SessionInputBufferImpl(16); final ByteArrayInputStream inputStream = new ByteArrayInputStream(s.getBytes(StandardCharsets.ISO_8859_1)); final ChunkedInputStream in = new ChunkedInputStream(inBuffer, inputStream); in.read(); in.read(); in.close(); }
@Test public void testCorruptChunkedInputStreamClose() throws IOException { final String s = "whatever\r\n01234\r\n5\r\n56789\r\n0\r\n"; final SessionInputBuffer inBuffer = new SessionInputBufferImpl(16); final ByteArrayInputStream inputStream = new ByteArrayInputStream(s.getBytes(StandardCharsets.ISO_8859_1)); final ChunkedInputStream in = new ChunkedInputStream(inBuffer, inputStream); try { in.read(); Assert.fail("MalformedChunkCodingException expected"); } catch (final MalformedChunkCodingException ex) { } in.close(); }
@Test(expected=ConnectionClosedException.class) public void testChunkedInputStreamNoClosingChunk() throws IOException { final String s = "5\r\n01234\r\n"; final SessionInputBuffer inBuffer = new SessionInputBufferImpl(16); final ByteArrayInputStream inputStream = new ByteArrayInputStream(s.getBytes(StandardCharsets.ISO_8859_1)); final ChunkedInputStream in = new ChunkedInputStream(inBuffer, inputStream); final byte[] tmp = new byte[5]; Assert.assertEquals(5, in.read(tmp)); in.read(); in.close(); }
@Test(expected=MalformedChunkCodingException.class) public void testCorruptChunkedInputStreamTruncatedCRLF() throws IOException { final String s = "5\r\n01234"; final SessionInputBuffer inBuffer = new SessionInputBufferImpl(16); final ByteArrayInputStream inputStream = new ByteArrayInputStream(s.getBytes(StandardCharsets.ISO_8859_1)); final ChunkedInputStream in = new ChunkedInputStream(inBuffer, inputStream); final byte[] tmp = new byte[5]; Assert.assertEquals(5, in.read(tmp)); in.read(); in.close(); }
@Test(expected = TruncatedChunkException.class) public void testCorruptChunkedInputStreamTruncatedChunk() throws IOException { final String s = "3\r\n12"; final SessionInputBuffer inBuffer = new SessionInputBufferImpl(16); final ByteArrayInputStream inputStream = new ByteArrayInputStream(s.getBytes(StandardCharsets.ISO_8859_1)); final ChunkedInputStream in = new ChunkedInputStream(inBuffer, inputStream); final byte[] buffer = new byte[300]; Assert.assertEquals(2, in.read(buffer)); in.read(buffer); in.close(); }
@Test public void testTooLongChunkHeader() throws IOException { final String s = "5; and some very looooong commend\r\n12345\r\n0\r\n"; final SessionInputBuffer inBuffer1 = new SessionInputBufferImpl(16); final ByteArrayInputStream inputStream1 = new ByteArrayInputStream(s.getBytes(StandardCharsets.ISO_8859_1)); final ChunkedInputStream in1 = new ChunkedInputStream(inBuffer1, inputStream1); final byte[] buffer = new byte[300]; Assert.assertEquals(5, in1.read(buffer)); in1.close(); final SessionInputBuffer inBuffer2 = new SessionInputBufferImpl(16, 10); final ByteArrayInputStream inputStream2 = new ByteArrayInputStream(s.getBytes(StandardCharsets.ISO_8859_1)); final ChunkedInputStream in2 = new ChunkedInputStream(inBuffer2, inputStream2); try { in2.read(buffer); Assert.fail("MessageConstraintException expected"); } catch (final MessageConstraintException ex) { } finally { try { in2.close(); } catch (final MessageConstraintException ex) { } } }
@Test public void testAvailable() throws IOException { final String s = "5\r\n12345\r\n0\r\n"; final SessionInputBuffer inBuffer = new SessionInputBufferImpl(16); final ByteArrayInputStream inputStream = new ByteArrayInputStream(s.getBytes(StandardCharsets.ISO_8859_1)); final ChunkedInputStream in = new ChunkedInputStream(inBuffer, inputStream); Assert.assertEquals(0, in.available()); in.read(); Assert.assertEquals(4, in.available()); in.close(); }
@Test public void testChunkedConsistence() throws IOException { final String input = "76126;27823abcd;:q38a-\nkjc\rk%1ad\tkh/asdui\r\njkh+?\\suweb"; final SessionOutputBuffer outbuffer = new SessionOutputBufferImpl(16); final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); final ChunkedOutputStream out = new ChunkedOutputStream(outbuffer, outputStream, 2048); out.write(input.getBytes(StandardCharsets.ISO_8859_1)); out.flush(); out.close(); out.close(); final SessionInputBuffer inBuffer = new SessionInputBufferImpl(16); final ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray()); final ChunkedInputStream in = new ChunkedInputStream(inBuffer, inputStream); final byte[] d = new byte[10]; final ByteArrayOutputStream result = new ByteArrayOutputStream(); int len = 0; while ((len = in.read(d)) > 0) { result.write(d, 0, len); } final String output = new String(result.toByteArray(), StandardCharsets.ISO_8859_1); Assert.assertEquals(input, output); in.close(); }
@Test public void testChunkedInputStreamOneByteRead() throws IOException { final String s = "5\r\n01234\r\n5\r\n56789\r\n0\r\n"; final SessionInputBuffer inBuffer = new SessionInputBufferImpl(16); final ByteArrayInputStream inputStream = new ByteArrayInputStream(s.getBytes(StandardCharsets.ISO_8859_1)); final ChunkedInputStream in = new ChunkedInputStream(inBuffer, inputStream); int ch; int i = '0'; while ((ch = in.read()) != -1) { Assert.assertEquals(i, ch); i++; } Assert.assertEquals(-1, in.read()); Assert.assertEquals(-1, in.read()); in.close(); }
@Test public void testResumeOnSocketTimeoutInData() throws IOException { final String s = "5\r\n01234\r\n5\r\n5\0006789\r\na\r\n0123\000456789\r\n0\r\n"; final SessionInputBuffer inBuffer = new SessionInputBufferImpl(16); final TimeoutByteArrayInputStream inputStream = new TimeoutByteArrayInputStream(s.getBytes(StandardCharsets.ISO_8859_1)); final ChunkedInputStream in = new ChunkedInputStream(inBuffer, inputStream); final byte[] tmp = new byte[3]; int bytesRead = 0; int timeouts = 0; int i = 0; while (i != -1) { try { i = in.read(tmp); if (i > 0) { bytesRead += i; } } catch (final InterruptedIOException ex) { timeouts++; } } Assert.assertEquals(20, bytesRead); Assert.assertEquals(2, timeouts); in.close(); }
@Test public void testResumeOnSocketTimeoutInChunk() throws IOException { final String s = "5\000\r\000\n\00001234\r\n\0005\r\n56789\r\na\r\n0123456789\r\n\0000\r\n"; final SessionInputBuffer inBuffer = new SessionInputBufferImpl(16); final TimeoutByteArrayInputStream inputStream = new TimeoutByteArrayInputStream(s.getBytes(StandardCharsets.ISO_8859_1)); final ChunkedInputStream in = new ChunkedInputStream(inBuffer, inputStream); final byte[] tmp = new byte[3]; int bytesRead = 0; int timeouts = 0; int i = 0; while (i != -1) { try { i = in.read(tmp); if (i > 0) { bytesRead += i; } } catch (final InterruptedIOException ex) { timeouts++; } } Assert.assertEquals(20, bytesRead); Assert.assertEquals(5, timeouts); in.close(); }
@Test public void testChunkedInputStreamSmallBuffer() throws IOException { final SessionInputBuffer inBuffer = new SessionInputBufferImpl(16); final ByteArrayInputStream inputStream = new ByteArrayInputStream(CHUNKED_INPUT.getBytes(StandardCharsets.ISO_8859_1)); final ChunkedInputStream in = new ChunkedInputStream(inBuffer, inputStream); final byte[] buffer = new byte[7]; final ByteArrayOutputStream out = new ByteArrayOutputStream(); int len; while ((len = in.read(buffer)) > 0) { out.write(buffer, 0, len); } Assert.assertEquals(-1, in.read(buffer)); Assert.assertEquals(-1, in.read(buffer)); in.close(); final Header[] footers = in.getFooters(); Assert.assertNotNull(footers); Assert.assertEquals(2, footers.length); Assert.assertEquals("Footer1", footers[0].getName()); Assert.assertEquals("abcde", footers[0].getValue()); Assert.assertEquals("Footer2", footers[1].getName()); Assert.assertEquals("fghij", footers[1].getValue()); }