Skip to content

Commit

Permalink
Fix#1035 Use request header to determine if checksum validation shoul…
Browse files Browse the repository at this point in the history
…d be enabled in SyncChecksumValidation also
  • Loading branch information
ChaithanyaGK authored and zoewangg committed Dec 17, 2019
1 parent e36b63c commit 778f350
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public Optional<InputStream> modifyHttpResponseContent(Context.ModifyHttpRespons

@Override
public void afterUnmarshalling(Context.AfterUnmarshalling context, ExecutionAttributes executionAttributes) {
if (putObjectChecksumEnabled(context.request(), SYNC, executionAttributes, context.httpResponse())) {
if (putObjectChecksumEnabled(context.request(), SYNC, executionAttributes, context.httpRequest())) {
validatePutObjectChecksum((PutObjectResponse) context.response(), executionAttributes);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,22 @@


import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Java6Assertions.assertThatThrownBy;
import static software.amazon.awssdk.core.ClientType.SYNC;
import static software.amazon.awssdk.core.interceptor.SdkExecutionAttribute.CLIENT_TYPE;
import static software.amazon.awssdk.core.interceptor.SdkExecutionAttribute.SERVICE_CONFIG;
import static software.amazon.awssdk.services.s3.checksums.ChecksumConstant.CHECKSUM_ENABLED_RESPONSE_HEADER;
import static software.amazon.awssdk.services.s3.checksums.ChecksumConstant.CONTENT_LENGTH_HEADER;
import static software.amazon.awssdk.services.s3.checksums.ChecksumConstant.ENABLE_MD5_CHECKSUM_HEADER_VALUE;
import static software.amazon.awssdk.services.s3.checksums.ChecksumConstant.SERVER_SIDE_ENCRYPTION_HEADER;
import static software.amazon.awssdk.services.s3.checksums.ChecksumsEnabledValidator.CHECKSUM;
import static software.amazon.awssdk.services.s3.model.ServerSideEncryption.AWS_KMS;

import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
Expand All @@ -38,19 +43,28 @@
import software.amazon.awssdk.core.interceptor.ExecutionAttributes;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.http.ContentStreamProvider;
import software.amazon.awssdk.http.SdkHttpFullRequest;
import software.amazon.awssdk.http.SdkHttpMethod;
import software.amazon.awssdk.http.SdkHttpRequest;
import software.amazon.awssdk.http.SdkHttpResponse;
import software.amazon.awssdk.services.s3.S3Configuration;
import software.amazon.awssdk.services.s3.checksums.ChecksumCalculatingInputStream;
import software.amazon.awssdk.services.s3.checksums.ChecksumValidatingInputStream;
import software.amazon.awssdk.services.s3.internal.handlers.SyncChecksumValidationInterceptor.ChecksumCalculatingStreamProvider;
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.services.s3.model.PutObjectResponse;
import software.amazon.awssdk.services.s3.utils.InterceptorTestUtils;
import software.amazon.awssdk.utils.IoUtils;
import software.amazon.awssdk.utils.StringInputStream;
import software.amazon.awssdk.utils.internal.Base16Lower;

public class SyncChecksumValidationInterceptorTest {

private static final byte[] CONTENT_BYTES = "CONTENT".getBytes(Charset.forName("UTF-8"));
private static final String VALID_CHECKSUM = Base16Lower.encodeAsString(checkSumFor(CONTENT_BYTES).getChecksumBytes());
private static final String INVALID_CHECKSUM = "3902ee7e149eb8313a34757e89e21af6";

private SyncChecksumValidationInterceptor interceptor = new SyncChecksumValidationInterceptor();

@Test
Expand Down Expand Up @@ -149,6 +163,73 @@ public void checksumCalculatingStreamProvider_shouldReturnNewStreamResetChecksum
newStream.close();
}

@Test
public void afterUnmarshalling_putObjectRequest_shouldValidateChecksum() {
SdkHttpResponse sdkHttpResponse = getSdkHttpResponseWithChecksumHeader();

PutObjectResponse response = PutObjectResponse.builder()
.eTag(VALID_CHECKSUM)
.build();

PutObjectRequest putObjectRequest = PutObjectRequest.builder()
.build();

SdkHttpRequest sdkHttpRequest = SdkHttpFullRequest.builder()
.uri(URI.create("http://localhost:8080"))
.method(SdkHttpMethod.PUT)
.build();

Context.AfterUnmarshalling afterUnmarshallingContext =
InterceptorTestUtils.afterUnmarshallingContext(putObjectRequest, sdkHttpRequest, response, sdkHttpResponse);

interceptor.afterUnmarshalling(afterUnmarshallingContext, getExecutionAttributesWithChecksum());
}

@Test
public void afterUnmarshalling_putObjectRequest_shouldValidateChecksum_throwExceptionIfInvalid() {
SdkHttpResponse sdkHttpResponse = getSdkHttpResponseWithChecksumHeader();

PutObjectResponse response = PutObjectResponse.builder()
.eTag(INVALID_CHECKSUM)
.build();

PutObjectRequest putObjectRequest = PutObjectRequest.builder().build();

SdkHttpRequest sdkHttpRequest = SdkHttpFullRequest.builder()
.uri(URI.create("http://localhost:8080"))
.method(SdkHttpMethod.PUT)
.build();

Context.AfterUnmarshalling afterUnmarshallingContext =
InterceptorTestUtils.afterUnmarshallingContext(putObjectRequest, sdkHttpRequest, response, sdkHttpResponse);

assertThatThrownBy(() -> interceptor.afterUnmarshalling(afterUnmarshallingContext, getExecutionAttributesWithChecksum()))
.hasMessage("Data read has a different checksum than expected.");
}

@Test
public void afterUnmarshalling_putObjectRequest_with_SSE_shouldNotValidateChecksum() {
SdkHttpResponse sdkHttpResponse = getSdkHttpResponseWithChecksumHeader();

PutObjectResponse response = PutObjectResponse.builder()
.eTag(INVALID_CHECKSUM)
.build();

PutObjectRequest putObjectRequest = PutObjectRequest.builder().build();

SdkHttpRequest sdkHttpRequest = SdkHttpFullRequest.builder()
.putHeader(SERVER_SIDE_ENCRYPTION_HEADER, AWS_KMS.toString())
.putHeader("x-amz-server-side-encryption-aws-kms-key-id", ENABLE_MD5_CHECKSUM_HEADER_VALUE)
.uri(URI.create("http://localhost:8080"))
.method(SdkHttpMethod.PUT)
.build();

Context.AfterUnmarshalling afterUnmarshallingContext =
InterceptorTestUtils.afterUnmarshallingContext(putObjectRequest, sdkHttpRequest, response, sdkHttpResponse);

interceptor.afterUnmarshalling(afterUnmarshallingContext, getExecutionAttributesWithChecksum());
}

private static final class CloseAwareStream extends InputStream {
private StringInputStream inputStream;
private boolean isClosed;
Expand Down Expand Up @@ -192,4 +273,15 @@ private ExecutionAttributes getExecutionAttributesWithChecksumDisabled() {
executionAttributes.putAttribute(SERVICE_CONFIG, S3Configuration.builder().checksumValidationEnabled(false).build());
return executionAttributes;
}

private ExecutionAttributes getExecutionAttributesWithChecksum() {
SdkChecksum checksum = checkSumFor(CONTENT_BYTES);
return getExecutionAttributes().putAttribute(CHECKSUM, checksum);
}

private static SdkChecksum checkSumFor(byte[] bytes) {
SdkChecksum checksum = new Md5Checksum();
checksum.update(bytes, 0, bytes.length);
return checksum;
}
}

0 comments on commit 778f350

Please sign in to comment.