JCLOUDS-1391: Sort headers correctly for signing

This commit is contained in:
Alin Dreghiciu 2018-03-07 20:49:51 +02:00 committed by Andrew Gaul
parent f6d95d0fda
commit cbb76523cc
2 changed files with 68 additions and 11 deletions

View File

@ -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) {

View File

@ -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);
}
}
}