Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changes/next-release/bugfix-AWSSDKforJavav2-08c895c.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"type": "bugfix",
"category": "AWS SDK for Java v2",
"contributor": "",
"description": "Preserve the initial content-length when calling mark in SdkLengthAwareInputStream."
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,15 @@
@SdkInternalApi
public class SdkLengthAwareInputStream extends FilterInputStream {
private static final Logger LOG = Logger.loggerFor(SdkLengthAwareInputStream.class);
private long length;
private final long length;
private long remaining;
private long markedRemaining;
Comment thread
alextwoods marked this conversation as resolved.

public SdkLengthAwareInputStream(InputStream in, long length) {
super(in);
this.length = Validate.isNotNegative(length, "length");
this.remaining = this.length;
this.markedRemaining = this.remaining;
}

@Override
Expand Down Expand Up @@ -104,15 +106,14 @@ public int available() throws IOException {
@Override
public void mark(int readlimit) {
super.mark(readlimit);
// mark() causes reset() to change the stream's position back to the current position. Therefore, when reset() is called,
// the new length of the stream will be equal to the current value of 'remaining'.
length = remaining;
// Store the current remaining bytes to restore on reset()
markedRemaining = remaining;
}

@Override
public void reset() throws IOException {
super.reset();
remaining = length;
remaining = markedRemaining;
}

public long remaining() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,27 @@ void readByte_readExactLength_doesNotThrow() throws IOException {
assertThat(total).isEqualTo(delegateLength);
}

@Test
void readBytePartialThenMark_doesNotResetContentLength() throws IOException {
int delegateLength = 16;
int expectedContentLength = delegateLength + 1;
ByteArrayInputStream delegate = new ByteArrayInputStream(new byte[delegateLength]);

SdkLengthAwareInputStream is = new SdkLengthAwareInputStream(delegate, expectedContentLength);
is.read(); // read one byte
is.mark(1024);
// read another byte and reset, the length should not be reset based on the byte that was already read
is.read();
is.reset();
assertThatThrownBy(() -> {
int read;
while ((read = is.read()) != -1) {
}
})
.isInstanceOf(IllegalStateException.class)
.hasMessageContaining("The request content has fewer bytes than the specified content-length: " + expectedContentLength);
}

@Test
void readByte_delegateLongerThanRequired_truncated() throws IOException {
int delegateLength = 32;
Expand Down
Loading