JCLOUDS-766: Include Content-MD5 in v4 signature

Addresses AWSS3BlobIntegrationLiveTest.deleteMultipleObjects test
failures.
This commit is contained in:
Andrew Gaul 2016-03-18 16:19:12 -07:00
parent feae011c4d
commit 35c5d7ffc0
2 changed files with 26 additions and 2 deletions

View File

@ -21,6 +21,8 @@ import com.google.common.base.Strings;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSortedMap;
import com.google.common.hash.HashCode;
import com.google.common.io.BaseEncoding;
import com.google.common.net.HttpHeaders;
import com.google.inject.Inject;
import org.jclouds.aws.domain.SessionCredentials;
@ -69,6 +71,8 @@ public class Aws4SignerForAuthorizationHeader extends Aws4SignerBase {
checkNotNull(request, "request is not ready to sign");
checkNotNull(request.getEndpoint(), "request is not ready to sign, request.endpoint not present.");
Payload payload = request.getPayload();
// get host from request endpoint.
String host = request.getEndpoint().getHost();
@ -82,7 +86,6 @@ public class Aws4SignerForAuthorizationHeader extends Aws4SignerBase {
HttpRequest.Builder<?> requestBuilder = request.toBuilder() //
.removeHeader(AUTHORIZATION) // remove Authorization
.removeHeader(CONTENT_MD5) // aws s3 not allowed Content-MD5, use specs x-amz-content-sha256
.removeHeader(DATE); // remove date
ImmutableMap.Builder<String, String> signedHeadersBuilder = ImmutableSortedMap.<String, String>naturalOrder();
@ -102,6 +105,16 @@ public class Aws4SignerForAuthorizationHeader extends Aws4SignerBase {
signedHeadersBuilder.put(HttpHeaders.CONTENT_LENGTH.toLowerCase(), contentLength);
}
// Content MD5
if (payload != null) {
HashCode md5 = payload.getContentMetadata().getContentMD5AsHashCode();
if (md5 != null) {
String contentMD5 = BaseEncoding.base64().encode(md5.asBytes());
requestBuilder.replaceHeader(CONTENT_MD5, contentMD5);
signedHeadersBuilder.put(CONTENT_MD5.toLowerCase(), contentMD5);
}
}
// host
requestBuilder.replaceHeader(HttpHeaders.HOST, host);
signedHeadersBuilder.put(HttpHeaders.HOST.toLowerCase(), host);

View File

@ -59,6 +59,8 @@ import com.google.common.base.Strings;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSortedMap;
import com.google.common.hash.HashCode;
import com.google.common.io.BaseEncoding;
import com.google.common.io.ByteProcessor;
import com.google.common.net.HttpHeaders;
import com.google.inject.Inject;
@ -104,7 +106,6 @@ public class Aws4SignerForChunkedUpload extends Aws4SignerBase {
HttpRequest.Builder<?> requestBuilder = request.toBuilder() //
.removeHeader(AUTHORIZATION) // remove Authorization
.removeHeader(CONTENT_MD5) // aws s3 not allowed Content-MD5, use aws specs x-amz-content-sha256
.removeHeader(DATE) // remove Date
.removeHeader(CONTENT_LENGTH); // remove Content-Length
@ -125,6 +126,16 @@ public class Aws4SignerForChunkedUpload extends Aws4SignerBase {
requestBuilder.replaceHeader(CONTENT_LENGTH, Long.toString(totalLength));
signedHeadersBuilder.put(CONTENT_LENGTH.toLowerCase(), Long.toString(totalLength));
// Content MD5
if (payload != null) {
HashCode md5 = payload.getContentMetadata().getContentMD5AsHashCode();
if (md5 != null) {
String contentMD5 = BaseEncoding.base64().encode(md5.asBytes());
requestBuilder.replaceHeader(CONTENT_MD5, contentMD5);
signedHeadersBuilder.put(CONTENT_MD5.toLowerCase(), contentMD5);
}
}
// Content Type
// content-type is not a required signing param. However, examples use this, so we include it to ease testing.
String contentType = getContentType(request);