Skip to content

Commit

Permalink
Only cap the input if content length header is given
Browse files Browse the repository at this point in the history
Currently RqLengthAware uses the InputStream#available to cap the input
if no Content-Length header is given, but the return value does not say
anything about the real content length, only how many bytes can be read
without blocking (what might be 0).

This now only returns a CapInputStream when a Content-Length is given in
the request and adds a testcase for the given case.
  • Loading branch information
Christoph Läubrich committed Aug 2, 2024
1 parent 20467cf commit 046de5f
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 6 deletions.
23 changes: 17 additions & 6 deletions src/main/java/org/takes/rq/RqLengthAware.java
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -68,14 +72,21 @@ public RqLengthAware(final Request req) {
*/
private static InputStream cap(final Request req) throws IOException {
final Iterator<String> 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;
}

}
28 changes: 28 additions & 0 deletions src/test/java/org/takes/rq/RqLengthAwareTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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";
Expand Down

0 comments on commit 046de5f

Please sign in to comment.