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>
|
<version>7.5.1</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>software.amazon.awssdk</groupId>
|
||||||
|
<artifactId>s3</artifactId>
|
||||||
|
<version>2.30.33</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>javax.annotation</groupId>
|
<groupId>javax.annotation</groupId>
|
||||||
<artifactId>javax.annotation-api</artifactId>
|
<artifactId>javax.annotation-api</artifactId>
|
||||||
|
|
|
@ -38,6 +38,7 @@ final class AwsHttpHeaders {
|
||||||
static final String REQUEST_ID = "x-amz-request-id";
|
static final String REQUEST_ID = "x-amz-request-id";
|
||||||
static final String SDK_CHECKSUM_ALGORITHM = "x-amz-sdk-checksum-algorithm";
|
static final String SDK_CHECKSUM_ALGORITHM = "x-amz-sdk-checksum-algorithm";
|
||||||
static final String STORAGE_CLASS = "x-amz-storage-class";
|
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 TRANSFER_ENCODING = "x-amz-te";
|
||||||
static final String USER_AGENT = "x-amz-user-agent";
|
static final String USER_AGENT = "x-amz-user-agent";
|
||||||
|
|
||||||
|
|
|
@ -281,6 +281,8 @@ final class AwsSignature {
|
||||||
} else if ("STREAMING-AWS4-HMAC-SHA256-PAYLOAD".equals(
|
} else if ("STREAMING-AWS4-HMAC-SHA256-PAYLOAD".equals(
|
||||||
xAmzContentSha256)) {
|
xAmzContentSha256)) {
|
||||||
digest = "STREAMING-AWS4-HMAC-SHA256-PAYLOAD";
|
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)) {
|
} else if ("UNSIGNED-PAYLOAD".equals(xAmzContentSha256)) {
|
||||||
digest = "UNSIGNED-PAYLOAD";
|
digest = "UNSIGNED-PAYLOAD";
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -49,8 +49,14 @@ final class ChunkedInputStream extends FilterInputStream {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
String[] parts = line.split(";", 2);
|
String[] parts = line.split(";", 2);
|
||||||
|
if (parts[0].startsWith("x-amz-checksum-crc32:")) {
|
||||||
|
currentLength = 0;
|
||||||
|
} else {
|
||||||
currentLength = Integer.parseInt(parts[0], 16);
|
currentLength = Integer.parseInt(parts[0], 16);
|
||||||
|
}
|
||||||
|
if (parts.length > 1) {
|
||||||
currentSignature = parts[1];
|
currentSignature = parts[1];
|
||||||
|
}
|
||||||
chunk = new byte[currentLength];
|
chunk = new byte[currentLength];
|
||||||
currentIndex = 0;
|
currentIndex = 0;
|
||||||
ByteStreams.readFully(in, chunk);
|
ByteStreams.readFully(in, chunk);
|
||||||
|
|
|
@ -177,6 +177,7 @@ public class S3ProxyHandler {
|
||||||
AwsHttpHeaders.METADATA_DIRECTIVE,
|
AwsHttpHeaders.METADATA_DIRECTIVE,
|
||||||
AwsHttpHeaders.SDK_CHECKSUM_ALGORITHM, // TODO: ignoring header
|
AwsHttpHeaders.SDK_CHECKSUM_ALGORITHM, // TODO: ignoring header
|
||||||
AwsHttpHeaders.STORAGE_CLASS,
|
AwsHttpHeaders.STORAGE_CLASS,
|
||||||
|
AwsHttpHeaders.TRAILER, // TODO: ignoring header
|
||||||
AwsHttpHeaders.TRANSFER_ENCODING, // TODO: ignoring header
|
AwsHttpHeaders.TRANSFER_ENCODING, // TODO: ignoring header
|
||||||
AwsHttpHeaders.USER_AGENT
|
AwsHttpHeaders.USER_AGENT
|
||||||
);
|
);
|
||||||
|
@ -514,6 +515,8 @@ public class S3ProxyHandler {
|
||||||
AwsHttpHeaders.CONTENT_SHA256);
|
AwsHttpHeaders.CONTENT_SHA256);
|
||||||
if ("STREAMING-AWS4-HMAC-SHA256-PAYLOAD".equals(contentSha256)) {
|
if ("STREAMING-AWS4-HMAC-SHA256-PAYLOAD".equals(contentSha256)) {
|
||||||
is = new ChunkedInputStream(is);
|
is = new ChunkedInputStream(is);
|
||||||
|
} else if ("STREAMING-UNSIGNED-PAYLOAD-TRAILER".equals(contentSha256)) {
|
||||||
|
is = new ChunkedInputStream(is);
|
||||||
}
|
}
|
||||||
} else if (requestIdentity == null) {
|
} else if (requestIdentity == null) {
|
||||||
throw new S3Exception(S3ErrorCode.ACCESS_DENIED);
|
throw new S3Exception(S3ErrorCode.ACCESS_DENIED);
|
||||||
|
@ -603,6 +606,9 @@ public class S3ProxyHandler {
|
||||||
contentSha256)) {
|
contentSha256)) {
|
||||||
payload = new byte[0];
|
payload = new byte[0];
|
||||||
is = new ChunkedInputStream(is);
|
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)) {
|
} else if ("UNSIGNED-PAYLOAD".equals(contentSha256)) {
|
||||||
payload = new byte[0];
|
payload = new byte[0];
|
||||||
} else {
|
} 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);
|
return "s3proxy-" + new Random().nextInt(Integer.MAX_VALUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Ładowanie…
Reference in New Issue