mirror of https://github.com/apache/jclouds.git
JCLOUDS-1391: Sort headers correctly for signing
This commit is contained in:
parent
f6d95d0fda
commit
cbb76523cc
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue