Repository: jclouds
Updated Branches:
  refs/heads/2.1.x b46eb9914 -> fa88bcc0d


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/fa88bcc0
Tree: http://git-wip-us.apache.org/repos/asf/jclouds/tree/fa88bcc0
Diff: http://git-wip-us.apache.org/repos/asf/jclouds/diff/fa88bcc0

Branch: refs/heads/2.1.x
Commit: fa88bcc0dd456048ae703bf22384c551c8794563
Parents: b46eb99
Author: Alin Dreghiciu <adreghi...@gmail.com>
Authored: Wed Mar 7 20:49:51 2018 +0200
Committer: Andrew Gaul <g...@apache.org>
Committed: Wed Mar 7 22:23:33 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/fa88bcc0/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/fa88bcc0/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);
+      }
+   }
 }

Reply via email to