Skip to content

Commit 9fec27c

Browse files
authored
Do not add chunk data for empty ByteBuffer (#5320)
* Do not add chunk data for empty ByteBuffer * Do not add chunk data for empty ByteBuffer * Add unit test * Add changelog * Remove integ test
1 parent 5066958 commit 9fec27c

File tree

3 files changed

+51
-2
lines changed

3 files changed

+51
-2
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"category": "Amazon S3",
3+
"contributor": "",
4+
"type": "bugfix",
5+
"description": "Fixes bug where empty non-final chunk is wrapped with headers and trailers during PutObject when using flexible checksums with S3AsyncClient"
6+
}

core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/async/ChecksumCalculatingAsyncRequestBody.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,9 +197,11 @@ public void onNext(ByteBuffer byteBuffer) {
197197
checksumBytes = checksum.getChecksumBytes();
198198
ByteBuffer allocatedBuffer = getFinalChecksumAppendedChunk(byteBuffer);
199199
wrapped.onNext(allocatedBuffer);
200-
} else {
200+
} else if (byteBuffer.hasRemaining()) {
201201
ByteBuffer allocatedBuffer = createChunk(byteBuffer, false);
202202
wrapped.onNext(allocatedBuffer);
203+
} else {
204+
wrapped.onNext(byteBuffer);
203205
}
204206
} catch (SdkException sdkException) {
205207
this.subscription.cancel();

core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/async/ChecksumCalculatingAsyncRequestBodyTest.java

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.nio.file.Files;
2323
import java.nio.file.Path;
2424
import java.util.List;
25+
import java.util.Optional;
2526
import java.util.concurrent.CountDownLatch;
2627
import java.util.concurrent.TimeUnit;
2728
import java.util.stream.Collectors;
@@ -37,6 +38,7 @@
3738
import org.junit.jupiter.params.provider.MethodSource;
3839
import org.reactivestreams.Publisher;
3940
import org.reactivestreams.Subscriber;
41+
import org.reactivestreams.Subscription;
4042
import software.amazon.awssdk.core.async.AsyncRequestBody;
4143
import software.amazon.awssdk.core.checksums.Algorithm;
4244
import software.amazon.awssdk.core.internal.util.Mimetype;
@@ -97,7 +99,10 @@ private static Stream<Arguments> publishers() {
9799
expectedEmptyString),
98100
Arguments.of("RequestBody from string, random pos, empty string",
99101
checksumPublisher(AsyncRequestBody.fromRemainingByteBufferUnsafe(nonPosZeroByteBuffer(emptyString))),
100-
expectedEmptyString));
102+
expectedEmptyString),
103+
Arguments.of("EmptyBufferPublisher, test string",
104+
checksumPublisher(new EmptyBufferPublisher(testString)),
105+
expectedTestString));
101106
}
102107

103108
private static ChecksumCalculatingAsyncRequestBody checksumPublisher(AsyncRequestBody sourcePublisher) {
@@ -274,4 +279,40 @@ public void fromBytes_byteArrayNotNullChecksumSupplied() {
274279
ByteBuffer publishedBb = Flowable.fromPublisher(body).toList().blockingGet().get(0);
275280
assertThat(BinaryUtils.copyAllBytesFrom(publishedBb)).isEqualTo(expected);
276281
}
282+
283+
static class EmptyBufferPublisher implements AsyncRequestBody {
284+
285+
private final ByteBuffer[] buffers = new ByteBuffer[2];
286+
private final String payload;
287+
288+
EmptyBufferPublisher(String payload) {
289+
buffers[0] = ByteBuffer.wrap(new byte[0]);
290+
buffers[1] = ByteBuffer.wrap(payload.getBytes(StandardCharsets.UTF_8));
291+
this.payload = payload;
292+
}
293+
294+
@Override
295+
public void subscribe(Subscriber<? super ByteBuffer> subscriber) {
296+
subscriber.onSubscribe(new Subscription() {
297+
private int count = 0;
298+
299+
@Override
300+
public void request(long n) {
301+
if (count < 2) {
302+
subscriber.onNext(buffers[count++]);
303+
} else {
304+
subscriber.onComplete();
305+
}
306+
}
307+
308+
@Override
309+
public void cancel() {}
310+
});
311+
}
312+
313+
@Override
314+
public Optional<Long> contentLength() {
315+
return Optional.of((long) payload.length());
316+
}
317+
}
277318
}

0 commit comments

Comments
 (0)