kopia lustrzana https://github.com/gaul/s3proxy
Parse but do not enforce CRC32
This suffices to allow AWS SDK for Java v2 to work without additional configuration. A more complete solution would allow for additional checksum algorithms and actually enforce the checksums. Fixes #830.pull/815/merge
rodzic
6e5fbf5a5f
commit
02fbdc149b
5
pom.xml
5
pom.xml
|
@ -554,6 +554,11 @@
|
|||
<version>7.5.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>software.amazon.awssdk</groupId>
|
||||
<artifactId>s3</artifactId>
|
||||
<version>2.30.33</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.annotation</groupId>
|
||||
<artifactId>javax.annotation-api</artifactId>
|
||||
|
|
|
@ -38,6 +38,7 @@ final class AwsHttpHeaders {
|
|||
static final String REQUEST_ID = "x-amz-request-id";
|
||||
static final String SDK_CHECKSUM_ALGORITHM = "x-amz-sdk-checksum-algorithm";
|
||||
static final String STORAGE_CLASS = "x-amz-storage-class";
|
||||
static final String TRAILER = "x-amz-trailer";
|
||||
static final String TRANSFER_ENCODING = "x-amz-te";
|
||||
static final String USER_AGENT = "x-amz-user-agent";
|
||||
|
||||
|
|
|
@ -281,6 +281,8 @@ final class AwsSignature {
|
|||
} else if ("STREAMING-AWS4-HMAC-SHA256-PAYLOAD".equals(
|
||||
xAmzContentSha256)) {
|
||||
digest = "STREAMING-AWS4-HMAC-SHA256-PAYLOAD";
|
||||
} else if ("STREAMING-UNSIGNED-PAYLOAD-TRAILER".equals(xAmzContentSha256)) {
|
||||
digest = "STREAMING-UNSIGNED-PAYLOAD-TRAILER";
|
||||
} else if ("UNSIGNED-PAYLOAD".equals(xAmzContentSha256)) {
|
||||
digest = "UNSIGNED-PAYLOAD";
|
||||
} else {
|
||||
|
|
|
@ -49,8 +49,14 @@ final class ChunkedInputStream extends FilterInputStream {
|
|||
return -1;
|
||||
}
|
||||
String[] parts = line.split(";", 2);
|
||||
if (parts[0].startsWith("x-amz-checksum-crc32:")) {
|
||||
currentLength = 0;
|
||||
} else {
|
||||
currentLength = Integer.parseInt(parts[0], 16);
|
||||
}
|
||||
if (parts.length > 1) {
|
||||
currentSignature = parts[1];
|
||||
}
|
||||
chunk = new byte[currentLength];
|
||||
currentIndex = 0;
|
||||
ByteStreams.readFully(in, chunk);
|
||||
|
|
|
@ -177,6 +177,7 @@ public class S3ProxyHandler {
|
|||
AwsHttpHeaders.METADATA_DIRECTIVE,
|
||||
AwsHttpHeaders.SDK_CHECKSUM_ALGORITHM, // TODO: ignoring header
|
||||
AwsHttpHeaders.STORAGE_CLASS,
|
||||
AwsHttpHeaders.TRAILER, // TODO: ignoring header
|
||||
AwsHttpHeaders.TRANSFER_ENCODING, // TODO: ignoring header
|
||||
AwsHttpHeaders.USER_AGENT
|
||||
);
|
||||
|
@ -514,6 +515,8 @@ public class S3ProxyHandler {
|
|||
AwsHttpHeaders.CONTENT_SHA256);
|
||||
if ("STREAMING-AWS4-HMAC-SHA256-PAYLOAD".equals(contentSha256)) {
|
||||
is = new ChunkedInputStream(is);
|
||||
} else if ("STREAMING-UNSIGNED-PAYLOAD-TRAILER".equals(contentSha256)) {
|
||||
is = new ChunkedInputStream(is);
|
||||
}
|
||||
} else if (requestIdentity == null) {
|
||||
throw new S3Exception(S3ErrorCode.ACCESS_DENIED);
|
||||
|
@ -603,6 +606,9 @@ public class S3ProxyHandler {
|
|||
contentSha256)) {
|
||||
payload = new byte[0];
|
||||
is = new ChunkedInputStream(is);
|
||||
} else if ("STREAMING-UNSIGNED-PAYLOAD-TRAILER".equals(contentSha256)) {
|
||||
payload = new byte[0];
|
||||
is = new ChunkedInputStream(is);
|
||||
} else if ("UNSIGNED-PAYLOAD".equals(contentSha256)) {
|
||||
payload = new byte[0];
|
||||
} else {
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Copyright 2014-2025 Andrew Gaul <andrew@gaul.org>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.gaul.s3proxy;
|
||||
|
||||
import org.jclouds.blobstore.BlobStoreContext;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
|
||||
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
|
||||
import software.amazon.awssdk.core.sync.RequestBody;
|
||||
import software.amazon.awssdk.http.SdkHttpConfigurationOption;
|
||||
import software.amazon.awssdk.http.apache.ApacheHttpClient;
|
||||
import software.amazon.awssdk.regions.Region;
|
||||
import software.amazon.awssdk.services.s3.S3Client;
|
||||
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
|
||||
import software.amazon.awssdk.utils.AttributeMap;
|
||||
|
||||
public final class AwsSdk2Test {
|
||||
private BlobStoreContext context;
|
||||
private S3Client s3Client;
|
||||
private String containerName;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
var info = TestUtils.startS3Proxy(System.getProperty("s3proxy.test.conf", "s3proxy.conf"));
|
||||
context = info.getBlobStore().getContext();
|
||||
|
||||
var attributeMap = AttributeMap.builder()
|
||||
.put(SdkHttpConfigurationOption.TRUST_ALL_CERTIFICATES, true)
|
||||
.build();
|
||||
s3Client = S3Client.builder()
|
||||
.credentialsProvider(
|
||||
StaticCredentialsProvider.create(
|
||||
AwsBasicCredentials.create(info.getS3Identity(), info.getS3Credential())))
|
||||
.region(Region.US_EAST_1)
|
||||
.endpointOverride(info.getSecureEndpoint())
|
||||
.httpClient(ApacheHttpClient.builder()
|
||||
.buildWithDefaults(attributeMap))
|
||||
.build();
|
||||
|
||||
containerName = AwsSdkTest.createRandomContainerName();
|
||||
info.getBlobStore().createContainerInLocation(null, containerName);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
if (s3Client != null) {
|
||||
s3Client.close();
|
||||
}
|
||||
if (context != null) {
|
||||
context.getBlobStore().deleteContainer(containerName);
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPutObject() throws Exception {
|
||||
var key = "testPutObject";
|
||||
var byteSource = TestUtils.randomByteSource().slice(0, 1024);
|
||||
|
||||
var putRequest = PutObjectRequest.builder()
|
||||
.bucket(containerName)
|
||||
.key(key)
|
||||
.build();
|
||||
|
||||
s3Client.putObject(putRequest, RequestBody.fromBytes(byteSource.read()));
|
||||
}
|
||||
}
|
|
@ -1828,7 +1828,7 @@ public final class AwsSdkTest {
|
|||
}
|
||||
}
|
||||
|
||||
private static String createRandomContainerName() {
|
||||
static String createRandomContainerName() {
|
||||
return "s3proxy-" + new Random().nextInt(Integer.MAX_VALUE);
|
||||
}
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue