kopia lustrzana https://github.com/gaul/s3proxy
Add configurable limit for single-part object size
rodzic
c66e29cd0a
commit
7e74e859e5
|
@ -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" +
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
Ładowanie…
Reference in New Issue