diff --git a/src/main/java/org/takes/rq/RqLengthAware.java b/src/main/java/org/takes/rq/RqLengthAware.java index 0436b0d74..b204da547 100644 --- a/src/main/java/org/takes/rq/RqLengthAware.java +++ b/src/main/java/org/takes/rq/RqLengthAware.java @@ -52,7 +52,9 @@ @EqualsAndHashCode(callSuper = true) public final class RqLengthAware extends RqWrap { - /** + private static final String CONTENT_LENGTH = "Content-Length"; + + /** * Ctor. * @param req Original request */ @@ -68,14 +70,16 @@ 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(); - if (hdr.hasNext()) { - length = Long.parseLong(hdr.next()); - } - body = new CapInputStream(body, length); - return body; + .header(CONTENT_LENGTH).iterator(); + if(hdr.hasNext()) { + String value = hdr.next(); + try { + return new CapInputStream(req.body(), Long.parseLong(value)); + } catch(NumberFormatException e) { + throw new IOException(String.format("Invalid %s header: %s", CONTENT_LENGTH, value)); + } + } + return req.body(); } } diff --git a/src/test/java/org/takes/rq/RqLengthAwareTest.java b/src/test/java/org/takes/rq/RqLengthAwareTest.java index 4fe943c8f..34c600ce3 100644 --- a/src/test/java/org/takes/rq/RqLengthAwareTest.java +++ b/src/test/java/org/takes/rq/RqLengthAwareTest.java @@ -23,9 +23,12 @@ */ package org.takes.rq; +import java.io.ByteArrayInputStream; +import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Arrays; + import org.hamcrest.MatcherAssert; import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; @@ -95,6 +98,34 @@ void readsByte() throws IOException { Matchers.equalTo(data.length() - 1) ); } + + @Test + void noContentLength() throws IOException { + byte[] bytes = "test".getBytes(); + final InputStream data = new FilterInputStream(new ByteArrayInputStream(bytes)) { + @Override + public int available() throws IOException { + //This simulates a stream where only one byte is available at once + return 1; + } + }; + final InputStream stream = new RqLengthAware( + new RqFake( + Arrays.asList( + "GET /test1", + "Host: b.example.com" + //We have no content length header so RqLengthAware should simply do nothing + ), + data + ) + ).body(); + for(int i = 0; i < bytes.length; i++) { + MatcherAssert.assertThat( + stream.read(), + Matchers.equalTo(bytes[i] & 0xFF) + ); + } + } @Test void readsByteArray() throws IOException {