diff --git a/src/main/java/org/takes/rq/RqLengthAware.java b/src/main/java/org/takes/rq/RqLengthAware.java index 0436b0d74..71177d259 100644 --- a/src/main/java/org/takes/rq/RqLengthAware.java +++ b/src/main/java/org/takes/rq/RqLengthAware.java @@ -51,6 +51,10 @@ */ @EqualsAndHashCode(callSuper = true) public final class RqLengthAware extends RqWrap { + /** + * Constant for the Content-Length header. + */ + private static final String CONTENT_LENGTH = "Content-Length"; /** * Ctor. @@ -68,14 +72,21 @@ public RqLengthAware(final Request req) { */ private static InputStream cap(final Request req) throws IOException { final Iterator hdr = new RqHeaders.Base(req) - .header("Content-Length").iterator(); - InputStream body = req.body(); - long length = (long) body.available(); + .header(RqLengthAware.CONTENT_LENGTH).iterator(); + final InputStream result; if (hdr.hasNext()) { - length = Long.parseLong(hdr.next()); + final String value = hdr.next(); + try { + result = new CapInputStream(req.body(), Long.parseLong(value)); + } catch (final NumberFormatException ex) { + final String msg = "Invalid %s header: %s"; + final String formated = String.format(msg, RqLengthAware.CONTENT_LENGTH, value); + throw new IOException(formated, ex); + } + } else { + result = req.body(); } - body = new CapInputStream(body, length); - return body; + return result; } } diff --git a/src/test/java/org/takes/rq/RqLengthAwareTest.java b/src/test/java/org/takes/rq/RqLengthAwareTest.java index 4fe943c8f..aa9222be3 100644 --- a/src/test/java/org/takes/rq/RqLengthAwareTest.java +++ b/src/test/java/org/takes/rq/RqLengthAwareTest.java @@ -23,6 +23,8 @@ */ package org.takes.rq; +import java.io.ByteArrayInputStream; +import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Arrays; @@ -96,6 +98,32 @@ void readsByte() throws IOException { ); } + @Test + void noContentLength() throws IOException { + final byte[] bytes = "test".getBytes(); + final InputStream data = new FilterInputStream(new ByteArrayInputStream(bytes)) { + @Override + public int available() throws IOException { + return 1; + } + }; + final InputStream stream = new RqLengthAware( + new RqFake( + Arrays.asList( + "GET /test1", + "Host: b.example.com" + ), + data + ) + ).body(); + for (final byte element : bytes) { + MatcherAssert.assertThat( + stream.read(), + Matchers.equalTo(element & 0xFF) + ); + } + } + @Test void readsByteArray() throws IOException { final String data = "array";