Add configurable limit for single-part object size

pull/345/head
Andrew Gaul 2021-02-03 22:48:23 +09:00
rodzic c66e29cd0a
commit 7e74e859e5
5 zmienionych plików z 41 dodań i 10 usunięć

Wyświetl plik

@ -38,6 +38,8 @@ enum S3ErrorCode {
" succeeded and you already own it."),
BUCKET_NOT_EMPTY(HttpServletResponse.SC_CONFLICT,
"The bucket you tried to delete is not empty"),
ENTITY_TOO_LARGE(HttpServletResponse.SC_BAD_REQUEST,
"Your proposed upload exceeds the maximum allowed object size."),
ENTITY_TOO_SMALL(HttpServletResponse.SC_BAD_REQUEST,
"Your proposed upload is smaller than the minimum allowed object" +
" size. Each part must be at least 5 MB in size, except the last" +

Wyświetl plik

@ -117,6 +117,7 @@ public final class S3Proxy {
handler = new S3ProxyHandlerJetty(builder.blobStore,
builder.authenticationType, builder.identity,
builder.credential, builder.virtualHost,
builder.maxSinglePartObjectSize,
builder.v4MaxNonChunkedRequestSize,
builder.ignoreUnknownHeaders, builder.corsRules,
builder.servicePath, builder.maximumTimeSkew);
@ -135,6 +136,7 @@ public final class S3Proxy {
private String keyStorePath;
private String keyStorePassword;
private String virtualHost;
private long maxSinglePartObjectSize = 5L * 1024 * 1024 * 1024;
private long v4MaxNonChunkedRequestSize = 32 * 1024 * 1024;
private boolean ignoreUnknownHeaders;
private CrossOriginResourceSharing corsRules;
@ -229,6 +231,13 @@ public final class S3Proxy {
builder.virtualHost(virtualHost);
}
String maxSinglePartObjectSize = properties.getProperty(
S3ProxyConstants.PROPERTY_MAX_SINGLE_PART_OBJECT_SIZE);
if (maxSinglePartObjectSize != null) {
builder.maxSinglePartObjectSize(Long.parseLong(
maxSinglePartObjectSize));
}
String v4MaxNonChunkedRequestSize = properties.getProperty(
S3ProxyConstants.PROPERTY_V4_MAX_NON_CHUNKED_REQUEST_SIZE);
if (v4MaxNonChunkedRequestSize != null) {
@ -325,6 +334,16 @@ public final class S3Proxy {
return this;
}
public Builder maxSinglePartObjectSize(long maxSinglePartObjectSize) {
if (maxSinglePartObjectSize <= 0) {
throw new IllegalArgumentException(
"must be greater than zero, was: " +
maxSinglePartObjectSize);
}
this.maxSinglePartObjectSize = maxSinglePartObjectSize;
return this;
}
public Builder v4MaxNonChunkedRequestSize(
long v4MaxNonChunkedRequestSize) {
if (v4MaxNonChunkedRequestSize <= 0) {
@ -406,6 +425,8 @@ public final class S3Proxy {
that.keyStorePassword) &&
Objects.equals(this.virtualHost, that.virtualHost) &&
Objects.equals(this.servicePath, that.servicePath) &&
Objects.equals(this.maxSinglePartObjectSize,
that.maxSinglePartObjectSize) &&
Objects.equals(this.v4MaxNonChunkedRequestSize,
that.v4MaxNonChunkedRequestSize) &&
Objects.equals(this.ignoreUnknownHeaders,
@ -417,8 +438,8 @@ public final class S3Proxy {
public int hashCode() {
return Objects.hash(endpoint, secureEndpoint, keyStorePath,
keyStorePassword, virtualHost, servicePath,
v4MaxNonChunkedRequestSize, ignoreUnknownHeaders,
corsRules);
maxSinglePartObjectSize, v4MaxNonChunkedRequestSize,
ignoreUnknownHeaders, corsRules);
}
}

Wyświetl plik

@ -62,6 +62,8 @@ public final class S3ProxyConstants {
*/
public static final String PROPERTY_VIRTUAL_HOST =
"s3proxy.virtual-host";
public static final String PROPERTY_MAX_SINGLE_PART_OBJECT_SIZE =
"s3proxy.max-single-part-object-size";
public static final String PROPERTY_V4_MAX_NON_CHUNKED_REQUEST_SIZE =
"s3proxy.v4-max-non-chunked-request-size";
/** When true, model eventual consistency using two storage backends. */

Wyświetl plik

@ -191,6 +191,7 @@ public class S3ProxyHandler {
private final boolean anonymousIdentity;
private final AuthenticationType authenticationType;
private final Optional<String> virtualHost;
private final long maxSinglePartObjectSize;
private final long v4MaxNonChunkedRequestSize;
private final boolean ignoreUnknownHeaders;
private final CrossOriginResourceSharing corsRules;
@ -216,9 +217,9 @@ public class S3ProxyHandler {
public S3ProxyHandler(final BlobStore blobStore,
AuthenticationType authenticationType, final String identity,
final String credential, @Nullable String virtualHost,
long v4MaxNonChunkedRequestSize, boolean ignoreUnknownHeaders,
CrossOriginResourceSharing corsRules, final String servicePath,
int maximumTimeSkew) {
long maxSinglePartObjectSize, long v4MaxNonChunkedRequestSize,
boolean ignoreUnknownHeaders, CrossOriginResourceSharing corsRules,
final String servicePath, int maximumTimeSkew) {
if (authenticationType != AuthenticationType.NONE) {
anonymousIdentity = false;
blobStoreLocator = new BlobStoreLocator() {
@ -246,6 +247,7 @@ public class S3ProxyHandler {
}
this.authenticationType = authenticationType;
this.virtualHost = Optional.fromNullable(virtualHost);
this.maxSinglePartObjectSize = maxSinglePartObjectSize;
this.v4MaxNonChunkedRequestSize = v4MaxNonChunkedRequestSize;
this.ignoreUnknownHeaders = ignoreUnknownHeaders;
this.corsRules = corsRules;
@ -1906,6 +1908,9 @@ public class S3ProxyHandler {
if (contentLength < 0) {
throw new S3Exception(S3ErrorCode.INVALID_ARGUMENT);
}
if (contentLength > maxSinglePartObjectSize) {
throw new S3Exception(S3ErrorCode.ENTITY_TOO_LARGE);
}
BlobAccess access;
String cannedAcl = request.getHeader(AwsHttpHeaders.ACL);

Wyświetl plik

@ -48,12 +48,13 @@ final class S3ProxyHandlerJetty extends AbstractHandler {
S3ProxyHandlerJetty(final BlobStore blobStore,
AuthenticationType authenticationType, final String identity,
final String credential, @Nullable String virtualHost,
long v4MaxNonChunkedRequestSize, boolean ignoreUnknownHeaders,
CrossOriginResourceSharing corsRules, String servicePath,
int maximumTimeSkew) {
long maxSinglePartObjectSize, long v4MaxNonChunkedRequestSize,
boolean ignoreUnknownHeaders, CrossOriginResourceSharing corsRules,
String servicePath, int maximumTimeSkew) {
handler = new S3ProxyHandler(blobStore, authenticationType, identity,
credential, virtualHost, v4MaxNonChunkedRequestSize,
ignoreUnknownHeaders, corsRules, servicePath, maximumTimeSkew);
credential, virtualHost, maxSinglePartObjectSize,
v4MaxNonChunkedRequestSize, ignoreUnknownHeaders, corsRules,
servicePath, maximumTimeSkew);
}
private void sendS3Exception(HttpServletRequest request,