Thanks to visit codestin.com
Credit goes to github.com

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
Original file line number Diff line number Diff line change
@@ -1,16 +1,39 @@
package com.robothy.s3.test;

import static org.junit.jupiter.api.Assertions.*;
import static software.amazon.awssdk.http.SdkHttpConfigurationOption.TRUST_ALL_CERTIFICATES;
import com.robothy.s3.jupiter.LocalS3;
import com.robothy.s3.jupiter.LocalS3Endpoint;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.apache.commons.codec.digest.DigestUtils;
import org.junit.jupiter.api.Test;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.auth.signer.Aws4UnsignedPayloadSigner;
import software.amazon.awssdk.auth.signer.AwsS3V4Signer;
import software.amazon.awssdk.auth.signer.S3SignerExecutionAttribute;
import software.amazon.awssdk.core.ResponseBytes;
import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;
import software.amazon.awssdk.core.client.config.SdkAdvancedClientOption;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.http.apache.ApacheHttpClient;
import software.amazon.awssdk.http.auth.aws.crt.internal.signer.AwsChunkedV4aPayloadSigner;
import software.amazon.awssdk.http.auth.aws.crt.internal.signer.V4aPayloadSigner;
import software.amazon.awssdk.http.auth.aws.signer.AwsV4HttpSigner;
import software.amazon.awssdk.http.auth.aws.signer.AwsV4aHttpSigner;
import software.amazon.awssdk.http.auth.spi.signer.SignedRequest;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.S3Configuration;
import software.amazon.awssdk.services.s3.internal.handlers.EnableChunkedEncodingInterceptor;
import software.amazon.awssdk.services.s3.model.*;

import java.io.IOException;
import java.util.Map;
import software.amazon.awssdk.utils.AttributeMap;

public class PutObjectIntegrationTest {

Expand Down Expand Up @@ -90,4 +113,100 @@ void testPutObjectWithS3Client(S3Client client) throws Exception {
assertEquals(content, gotObjectAsBytes.asUtf8String());
}


@Test
@LocalS3
void test_STREAMING_AWS4_HMAC_SHA256_PAYLOAD_TRAILER(LocalS3Endpoint endpoint) throws Exception {

try (S3Client s3Client = S3Client.builder()
.region(Region.of(endpoint.region()))
.overrideConfiguration(ClientOverrideConfiguration.builder()
.putAdvancedOption(SdkAdvancedClientOption.DISABLE_HOST_PREFIX_INJECTION, true)
.build())
.credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create("foo", "bar")))
.serviceConfiguration(S3Configuration.builder().pathStyleAccessEnabled(true).build())
.endpointOverride(URI.create(endpoint.endpoint()))
.httpClient(ApacheHttpClient.builder().buildWithDefaults(AttributeMap.builder()
.put(TRUST_ALL_CERTIFICATES, Boolean.TRUE)
.build()))
.build()) {

String bucketName = "my-bucket";
String key = "hello.txt";
byte[] content = new byte[1024 * 1024 * 6];
s3Client.createBucket(b -> b.bucket(bucketName));
s3Client.putObject(b -> b.bucket(bucketName).key(key)
.contentLength((long) content.length)
.contentType("text/plain"),
RequestBody.fromBytes(content));

ResponseBytes<GetObjectResponse> object = s3Client.getObjectAsBytes(b -> b.bucket(bucketName).key(key));
assertArrayEquals(content, object.asByteArray());
}

}


@Test
@LocalS3
void test_STREAMING_AWS4_HMAC_SHA256_PAYLOAD(S3Client s3Client) throws Exception {
String bucketName = "my-bucket";
String key = "hello.txt";
byte[] content = new byte[1024 * 1024 * 6];
s3Client.createBucket(b -> b.bucket(bucketName));
s3Client.putObject(b -> b.bucket(bucketName).key(key)
.overrideConfiguration(c -> {
c.signer(AwsS3V4Signer.create());
c.executionAttributes()
.putAttribute(S3SignerExecutionAttribute.ENABLE_PAYLOAD_SIGNING, true)
.putAttribute(S3SignerExecutionAttribute.ENABLE_CHUNKED_ENCODING, true)
;
c.credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create("foo", "bar")));
})
.contentLength((long) content.length)
.contentType("text/plain"),
RequestBody.fromBytes(content));

ResponseBytes<GetObjectResponse> object = s3Client.getObjectAsBytes(b -> b.bucket(bucketName).key(key));
assertArrayEquals(content, object.asByteArray());
}


@Test
@LocalS3
void test_UNSIGNED_PAYLOAD(S3Client s3Client) throws Exception {
String bucketName = "my-bucket";
String key = "hello.txt";
byte[] content = new byte[1024 * 1024 * 6];
s3Client.createBucket(b -> b.bucket(bucketName));
s3Client.putObject(b -> b.bucket(bucketName).key(key)
.overrideConfiguration(c -> {
c.signer(Aws4UnsignedPayloadSigner.create());
c.executionAttributes()
.putAttribute(S3SignerExecutionAttribute.ENABLE_PAYLOAD_SIGNING, true)
.putAttribute(S3SignerExecutionAttribute.ENABLE_CHUNKED_ENCODING, true)
;
c.credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create("foo", "bar")));
})
.contentLength((long) content.length)
.contentType("text/plain"),
RequestBody.fromBytes(content));

ResponseBytes<GetObjectResponse> object = s3Client.getObjectAsBytes(b -> b.bucket(bucketName).key(key));
assertArrayEquals(content, object.asByteArray());
}

//@Test
//@LocalS3
void test_STREAMING_AWS4_ECDSA_P256_SHA256_PAYLOAD(S3Client s3Client) throws Exception {
// TODO: implement this test
}

// @Test
// @LocalS3
void test_STREAMING_AWS4_ECDSA_P256_SHA256_PAYLOAD_TAILER(LocalS3Endpoint localS3Endpoint) throws Exception {
// TODO: implement this test
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,19 @@ public class AmzHeaderValues {
/**
* Value of {@linkplain AmzHeaderNames#X_AMZ_CONTENT_SHA256}. This value means
* the payload are encoded with signatures.
* <p>
* <a href="https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-auth-using-authorization-header.html">Streaming Signature Version 4</a>
*/
public static final String STREAMING_AWS4_HMAC_SHA_256_PAYLOAD = "STREAMING-AWS4-HMAC-SHA256-PAYLOAD";

public static final String STREAMING_AWS4_HMAC_SHA256_PAYLOAD_TRAILER = "STREAMING-AWS4-HMAC-SHA256-PAYLOAD-TRAILER";

public static final String STREAMING_UNSIGNED_PAYLOAD_TRAILER = "STREAMING-UNSIGNED-PAYLOAD-TRAILER";

public static final String STREAMING_UNSIGNED_PAYLOAD = "STREAMING-UNSIGNED-PAYLOAD";

public static final String STREAMING_AWS4_ECDSA_P256_SHA256_PAYLOAD = "STREAMING-AWS4-ECDSA-P256-SHA256-PAYLOAD";

public static final String STREAMING_AWS4_ECDSA_P256_SHA256_PAYLOAD_TRAILER = "STREAMING-AWS4-ECDSA-P256-SHA256-PAYLOAD-TRAILER";

}
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,23 @@
public static DecodedAmzRequestBody getBody(HttpRequest request) {
DecodedAmzRequestBody result = new DecodedAmzRequestBody();

String amzContentSha256 = request.header(AmzHeaderNames.X_AMZ_CONTENT_SHA256).orElse("");
String amzContentSha256 = request.header(AmzHeaderNames.X_AMZ_CONTENT_SHA256).orElse("").trim();
switch (amzContentSha256) {
case AmzHeaderValues.STREAMING_AWS4_HMAC_SHA_256_PAYLOAD:
case AmzHeaderValues.STREAMING_AWS4_HMAC_SHA256_PAYLOAD_TRAILER:
result.setDecodedBody(new AwsChunkedDecodingInputStream(new ByteBufInputStream(request.getBody())));
result.setDecodedContentLength(request.header(AmzHeaderNames.X_AMZ_DECODED_CONTENT_LENGTH).map(Long::parseLong)
.orElseThrow(() -> new IllegalArgumentException(AmzHeaderNames.X_AMZ_DECODED_CONTENT_LENGTH + "header not exist.")));
break;
case AmzHeaderValues.STREAMING_UNSIGNED_PAYLOAD_TRAILER:
case AmzHeaderValues.STREAMING_UNSIGNED_PAYLOAD:
result.setDecodedBody(new AwsUnsignedChunkedDecodingInputStream(new ByteBufInputStream(request.getBody())));
result.setDecodedContentLength(request.header(AmzHeaderNames.X_AMZ_DECODED_CONTENT_LENGTH).map(Long::parseLong)
.orElseThrow(() -> new IllegalArgumentException(AmzHeaderNames.X_AMZ_DECODED_CONTENT_LENGTH + "header not exist.")));
break;
case AmzHeaderValues.STREAMING_AWS4_ECDSA_P256_SHA256_PAYLOAD:
case AmzHeaderValues.STREAMING_AWS4_ECDSA_P256_SHA256_PAYLOAD_TRAILER:
throw new UnsupportedOperationException("Unsupported payload encoding: " + amzContentSha256);

Check warning on line 46 in local-s3-rest/src/main/java/com/robothy/s3/rest/utils/RequestUtils.java

View check run for this annotation

Codecov / codecov/patch

local-s3-rest/src/main/java/com/robothy/s3/rest/utils/RequestUtils.java#L46

Added line #L46 was not covered by tests
default:
result.setDecodedBody(new ByteBufInputStream(request.getBody()));
result.setDecodedContentLength(request.header(HttpHeaderNames.CONTENT_LENGTH.toString()).map(Long::parseLong)
Expand Down
Loading