Repository: jclouds Updated Branches: refs/heads/master f6d95d0fd -> cbb76523c
JCLOUDS-1391: Sort headers correctly for signing Project: http://git-wip-us.apache.org/repos/asf/jclouds/repo Commit: http://git-wip-us.apache.org/repos/asf/jclouds/commit/cbb76523 Tree: http://git-wip-us.apache.org/repos/asf/jclouds/tree/cbb76523 Diff: http://git-wip-us.apache.org/repos/asf/jclouds/diff/cbb76523 Branch: refs/heads/master Commit: cbb76523cc4a8f306329ed5cc97f96af759a9967 Parents: f6d95d0 Author: Alin Dreghiciu <[email protected]> Authored: Wed Mar 7 20:49:51 2018 +0200 Committer: Andrew Gaul <[email protected]> Committed: Wed Mar 7 22:13:43 2018 -0800 ---------------------------------------------------------------------- .../filters/SharedKeyLiteAuthentication.java | 35 +++++++++++----- .../AzureBlobIntegrationLiveTest.java | 44 ++++++++++++++++++++ 2 files changed, 68 insertions(+), 11 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/jclouds/blob/cbb76523/providers/azureblob/src/main/java/org/jclouds/azure/storage/filters/SharedKeyLiteAuthentication.java ---------------------------------------------------------------------- diff --git a/providers/azureblob/src/main/java/org/jclouds/azure/storage/filters/SharedKeyLiteAuthentication.java b/providers/azureblob/src/main/java/org/jclouds/azure/storage/filters/SharedKeyLiteAuthentication.java index aebcf95..700c610 100644 --- a/providers/azureblob/src/main/java/org/jclouds/azure/storage/filters/SharedKeyLiteAuthentication.java +++ b/providers/azureblob/src/main/java/org/jclouds/azure/storage/filters/SharedKeyLiteAuthentication.java @@ -23,7 +23,8 @@ import static org.jclouds.util.Patterns.NEWLINE_PATTERN; import static org.jclouds.util.Strings2.toInputStream; import java.util.Collection; -import java.util.Set; +import java.util.Map; +import java.util.Map.Entry; import javax.annotation.Resource; import javax.inject.Inject; @@ -31,6 +32,11 @@ import javax.inject.Named; import javax.inject.Provider; import javax.inject.Singleton; +import com.google.common.base.Function; +import com.google.common.base.Joiner; +import com.google.common.collect.Iterables; +import com.google.common.collect.Maps; +import com.google.common.collect.Multimap; import org.jclouds.Constants; import org.jclouds.crypto.Crypto; import org.jclouds.date.TimeStamp; @@ -50,7 +56,6 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap.Builder; import com.google.common.collect.Multimaps; -import com.google.common.collect.Sets; import com.google.common.io.ByteProcessor; import com.google.common.net.HttpHeaders; @@ -150,18 +155,26 @@ public class SharedKeyLiteAuthentication implements HttpRequestFilter { } private void appendCanonicalizedHeaders(HttpRequest request, StringBuilder toSign) { - // TreeSet == Sort the headers alphabetically. - Set<String> headers = Sets.newTreeSet(request.getHeaders().keySet()); - for (String header : headers) { + // TreeMap == Sort the headers alphabetically. + Map<String, String> headers = Maps.newTreeMap(); + Multimap<String, String> requestHeaders = request.getHeaders(); + for (String header : requestHeaders.keySet()) { if (header.startsWith("x-ms-")) { - toSign.append(header.toLowerCase()).append(":"); - for (String value : request.getHeaders().get(header)) { - toSign.append(NEWLINE_PATTERN.matcher(value).replaceAll("")).append(","); - } - toSign.deleteCharAt(toSign.lastIndexOf(",")); - toSign.append("\n"); + String value = Joiner.on(",").join(Iterables.transform(requestHeaders.get(header), + new Function<String, Object>() + { + @Override + public Object apply(final String value) { + return NEWLINE_PATTERN.matcher(value).replaceAll(""); + } + }) + ); + headers.put(header.toLowerCase(), value); } } + for (Entry<String, String> entry : headers.entrySet()) { + toSign.append(entry.getKey()).append(":").append(entry.getValue()).append("\n"); + } } private void appendHttpHeaders(HttpRequest request, StringBuilder toSign) { http://git-wip-us.apache.org/repos/asf/jclouds/blob/cbb76523/providers/azureblob/src/test/java/org/jclouds/azureblob/blobstore/integration/AzureBlobIntegrationLiveTest.java ---------------------------------------------------------------------- diff --git a/providers/azureblob/src/test/java/org/jclouds/azureblob/blobstore/integration/AzureBlobIntegrationLiveTest.java b/providers/azureblob/src/test/java/org/jclouds/azureblob/blobstore/integration/AzureBlobIntegrationLiveTest.java index 67223fc..69ef7f6 100644 --- a/providers/azureblob/src/test/java/org/jclouds/azureblob/blobstore/integration/AzureBlobIntegrationLiveTest.java +++ b/providers/azureblob/src/test/java/org/jclouds/azureblob/blobstore/integration/AzureBlobIntegrationLiveTest.java @@ -19,10 +19,21 @@ package org.jclouds.azureblob.blobstore.integration; import java.io.IOException; import java.util.concurrent.ExecutionException; +import javax.ws.rs.core.MediaType; + +import com.google.common.base.Charsets; +import com.google.common.collect.ImmutableMap; +import org.jclouds.blobstore.domain.Blob; import org.jclouds.blobstore.integration.internal.BaseBlobIntegrationTest; +import org.jclouds.blobstore.options.CopyOptions; import org.testng.SkipException; import org.testng.annotations.Test; +import static com.google.common.hash.Hashing.md5; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertNull; + @Test(groups = "live") public class AzureBlobIntegrationLiveTest extends BaseBlobIntegrationTest { @Override @@ -64,4 +75,37 @@ public class AzureBlobIntegrationLiveTest extends BaseBlobIntegrationTest { public void testPutBlobAccessMultipart() throws Exception { super.testPutBlobAccessMultipart(); } + + @Test(groups = { "integration", "live" }) + public void testSigningOfUppercaseMetadata() throws InterruptedException { + String containerName = getContainerName(); + String blobName = "testSigningOfUppercaseMetadata"; + + Blob blob = view.getBlobStore().blobBuilder(blobName) + .userMetadata(ImmutableMap.of("B", "b", "a", "a")) + .payload(TEST_STRING).contentType(MediaType.TEXT_PLAIN) + .contentMD5(md5().hashString(TEST_STRING, Charsets.UTF_8)) + .build(); + + try { + assertNull(view.getBlobStore().blobMetadata(containerName, blobName)); + + addBlobToContainer(containerName, blob); + assertConsistencyAwareContainerSize(containerName, 1); + + view.getBlobStore().copyBlob( + containerName, blobName, containerName, blobName, + CopyOptions.builder().userMetadata(ImmutableMap.of("B", "b", "a", "a")).build() + ); + + Blob newObject = view.getBlobStore().getBlob(containerName, blobName); + + assertNotNull(newObject); + assertEquals(newObject.getMetadata().getUserMetadata().get("b"), "b"); + assertEquals(newObject.getMetadata().getUserMetadata().get("a"), "a"); + + } finally { + returnContainer(containerName); + } + } }
