mirror of https://github.com/apache/jclouds.git
Issue 119: fixed encoding in unit tests
git-svn-id: http://jclouds.googlecode.com/svn/trunk@2270 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
parent
ba60357f21
commit
633a38b502
|
@ -133,39 +133,39 @@ public class SignRequest implements HttpRequestFilter {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void appendCanonicalizedHeaders(HttpRequest request, StringBuilder toSign) {
|
private void appendCanonicalizedHeaders(HttpRequest request, StringBuilder toSign) {
|
||||||
// TreeSet == SortÊtheÊheadersÊalphabetically.
|
// TreeSet == Sort the headers alphabetically.
|
||||||
Set<String> headers = new TreeSet<String>(request.getHeaders().keySet());
|
Set<String> headers = new TreeSet<String>(request.getHeaders().keySet());
|
||||||
for (String header : headers) {
|
for (String header : headers) {
|
||||||
if (header.startsWith("x-emc-")) {
|
if (header.startsWith("x-emc-")) {
|
||||||
// ConvertÊallÊheaderÊnamesÊtoÊlowercase.
|
// Convert all header names to lowercase.
|
||||||
toSign.append(header.toLowerCase()).append(":");
|
toSign.append(header.toLowerCase()).append(":");
|
||||||
// ForÊheadersÊwithÊvaluesÊthatÊspanÊmultipleÊlines,ÊconvertÊthemÊintoÊoneÊlineÊbyÊreplacingÊanyÊ
|
// For headers with values that span multiple lines, convert them into one line by replacing any
|
||||||
// newlineÊcharactersÊandÊextraÊembeddedÊwhiteÊspacesÊinÊtheÊvalue.
|
// newline characters and extra embedded white spaces in the value.
|
||||||
for (String value : request.getHeaders().get(header))
|
for (String value : request.getHeaders().get(header))
|
||||||
toSign.append(value.replaceAll("\r?\n", "").replaceAll(" ", " ")).append(" ");
|
toSign.append(value.replaceAll("\r?\n", "").replaceAll(" ", " ")).append(" ");
|
||||||
toSign.deleteCharAt(toSign.lastIndexOf(" "));
|
toSign.deleteCharAt(toSign.lastIndexOf(" "));
|
||||||
// ConcatenateÊallÊheadersÊtogether,ÊusingÊnewlinesÊ(\n)ÊseparatingÊeachÊheaderÊfromÊtheÊnextÊone.Ê
|
// Concatenate all headers together, using newlines (\n) separating each header from the next one.
|
||||||
toSign.append("\n");
|
toSign.append("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ThereÊshouldÊbeÊnoÊterminatingÊnewlineÊcharacterÊatÊtheÊendÊofÊtheÊlastÊheader.
|
// There should be no terminating newline character at the end of the last header.
|
||||||
if (toSign.charAt(toSign.length() - 1) == '\n')
|
if (toSign.charAt(toSign.length() - 1) == '\n')
|
||||||
toSign.deleteCharAt(toSign.length() - 1);
|
toSign.deleteCharAt(toSign.length() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
void appendHttpHeaders(HttpRequest request, StringBuilder toSign) {
|
void appendHttpHeaders(HttpRequest request, StringBuilder toSign) {
|
||||||
// OnlyÊtheÊvalueÊisÊused,ÊnotÊtheÊheaderÊ
|
// Only the value is used, not the header
|
||||||
// name.ÊIfÊaÊrequestÊdoesÊnotÊincludeÊtheÊheader,ÊthisÊisÊanÊemptyÊstring.
|
// name. If a request does not include the header, this is an empty string.
|
||||||
for (String header : new String[] { HttpHeaders.CONTENT_TYPE, "Range" })
|
for (String header : new String[] { HttpHeaders.CONTENT_TYPE, "Range" })
|
||||||
toSign.append(valueOrEmpty(request.getHeaders().get(header)).toLowerCase()).append("\n");
|
toSign.append(valueOrEmpty(request.getHeaders().get(header)).toLowerCase()).append("\n");
|
||||||
// StandardÊHTTPÊheader,ÊinÊUTCÊformat.ÊOnlyÊtheÊdateÊvalueÊisÊused, notÊtheÊheaderÊname.
|
// Standard HTTP header, in UTC format. Only the date value is used, not the header name.
|
||||||
toSign.append(request.getHeaders().get(HttpHeaders.DATE).iterator().next()).append("\n");
|
toSign.append(request.getHeaders().get(HttpHeaders.DATE).iterator().next()).append("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
void appendCanonicalizedResource(HttpRequest request, StringBuilder toSign) {
|
void appendCanonicalizedResource(HttpRequest request, StringBuilder toSign) {
|
||||||
// PathÊportionÊofÊtheÊHTTPÊrequestÊURI,ÊinÊlowercase.
|
// Path portion of the HTTP request URI, in lowercase.
|
||||||
toSign.append(request.getEndpoint().getRawPath().toLowerCase()).append("\n");
|
toSign.append(request.getEndpoint().getRawPath().toLowerCase()).append("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ public class ListOptions extends BaseHttpRequestOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* theÊmaximumÊnumberÊofÊitemsÊ thatÊshouldÊbeÊreturned. IfÊthisÊisÊÊnotÊspecified,ÊthereÊisÊno
|
* the maximum number of items that should be returned. If this is not specified, there is no
|
||||||
* limit.
|
* limit.
|
||||||
*/
|
*/
|
||||||
public ListOptions limit(int maxresults) {
|
public ListOptions limit(int maxresults) {
|
||||||
|
|
|
@ -369,7 +369,7 @@ public class JCloudsS3ServiceLiveTest extends BaseBlobStoreIntegrationTest<S3Cli
|
||||||
assertEquals(jsResultObject.getContentType(), MediaType.APPLICATION_OCTET_STREAM);
|
assertEquals(jsResultObject.getContentType(), MediaType.APPLICATION_OCTET_STREAM);
|
||||||
|
|
||||||
// Upload unicode-named object
|
// Upload unicode-named object
|
||||||
requestObject = new S3Object("Ÿn’<EFBFBD>˜dŽ-object");
|
requestObject = new S3Object("₪n₪₪₪d₪-object");
|
||||||
jsResultObject = service.putObject(new S3Bucket(bucketName), requestObject);
|
jsResultObject = service.putObject(new S3Bucket(bucketName), requestObject);
|
||||||
jcObject = context.getApi().getObject(bucketName, requestObject.getKey()).get(10,
|
jcObject = context.getApi().getObject(bucketName, requestObject.getKey()).get(10,
|
||||||
TimeUnit.SECONDS);
|
TimeUnit.SECONDS);
|
||||||
|
@ -381,7 +381,7 @@ public class JCloudsS3ServiceLiveTest extends BaseBlobStoreIntegrationTest<S3Cli
|
||||||
assertEquals(jsResultObject.getContentType(), MediaType.APPLICATION_OCTET_STREAM);
|
assertEquals(jsResultObject.getContentType(), MediaType.APPLICATION_OCTET_STREAM);
|
||||||
|
|
||||||
// Upload string object
|
// Upload string object
|
||||||
String data = "This is my Ÿn’<EFBFBD>˜dŽ data";
|
String data = "This is my ₪n₪₪₪d₪ data";
|
||||||
requestObject = new S3Object(objectKey, data);
|
requestObject = new S3Object(objectKey, data);
|
||||||
jsResultObject = service.putObject(new S3Bucket(bucketName), requestObject);
|
jsResultObject = service.putObject(new S3Bucket(bucketName), requestObject);
|
||||||
jcObject = context.getApi().getObject(bucketName, objectKey).get(10, TimeUnit.SECONDS);
|
jcObject = context.getApi().getObject(bucketName, objectKey).get(10, TimeUnit.SECONDS);
|
||||||
|
@ -415,7 +415,7 @@ public class JCloudsS3ServiceLiveTest extends BaseBlobStoreIntegrationTest<S3Cli
|
||||||
|
|
||||||
// Upload object and check MD5
|
// Upload object and check MD5
|
||||||
requestObject = new S3Object(objectKey);
|
requestObject = new S3Object(objectKey);
|
||||||
data = "Here is some d‡tˆ for you";
|
data = "Here is some d₪t₪ for you";
|
||||||
requestObject.setDataInputStream(new ByteArrayInputStream(data.getBytes("UTF-8")));
|
requestObject.setDataInputStream(new ByteArrayInputStream(data.getBytes("UTF-8")));
|
||||||
jsResultObject = service.putObject(new S3Bucket(bucketName), requestObject);
|
jsResultObject = service.putObject(new S3Bucket(bucketName), requestObject);
|
||||||
jcObject = context.getApi().getObject(bucketName, objectKey).get(10, TimeUnit.SECONDS);
|
jcObject = context.getApi().getObject(bucketName, objectKey).get(10, TimeUnit.SECONDS);
|
||||||
|
@ -434,8 +434,8 @@ public class JCloudsS3ServiceLiveTest extends BaseBlobStoreIntegrationTest<S3Cli
|
||||||
String bucketName = getContainerName();
|
String bucketName = getContainerName();
|
||||||
try {
|
try {
|
||||||
String data = "This is my data";
|
String data = "This is my data";
|
||||||
String sourceObjectKey = "šriginalObject"; // Notice the use of non-ASCII
|
String sourceObjectKey = "₪riginalObject"; // Notice the use of non-ASCII
|
||||||
String destinationObjectKey = "dŽstinationObject"; // characters here.
|
String destinationObjectKey = "d₪stinationObject"; // characters here.
|
||||||
String metadataName = "metadata-name";
|
String metadataName = "metadata-name";
|
||||||
String sourceMetadataValue = "souce-metadata-value";
|
String sourceMetadataValue = "souce-metadata-value";
|
||||||
String destinationMetadataValue = "destination-metadata-value";
|
String destinationMetadataValue = "destination-metadata-value";
|
||||||
|
|
|
@ -44,7 +44,7 @@ import com.google.common.collect.ImmutableMultimap;
|
||||||
public class NioHttpUtilsTest {
|
public class NioHttpUtilsTest {
|
||||||
@DataProvider(name = "gets")
|
@DataProvider(name = "gets")
|
||||||
public Object[][] createData() {
|
public Object[][] createData() {
|
||||||
return new Object[][] { { "object" }, { "/path" }, { "sp%20ace" }, { "unic¿de" },
|
return new Object[][] { { "object" }, { "/path" }, { "sp%20ace" }, { "unic₪de" },
|
||||||
{ "qu?stion" } };
|
{ "qu?stion" } };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ import java.lang.annotation.Target;
|
||||||
import javax.inject.Qualifier;
|
import javax.inject.Qualifier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Related to a resource of type Contacts, which represents the userÕs contact list.
|
* Related to a resource of type Contacts, which represents the user's contact list.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
*
|
||||||
|
|
|
@ -31,7 +31,7 @@ import java.lang.annotation.Target;
|
||||||
import javax.inject.Qualifier;
|
import javax.inject.Qualifier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Related to a resource of type RecycleBin, which contains the userÕs deleted files.
|
* Related to a resource of type RecycleBin, which contains the user's deleted files.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
*
|
||||||
|
|
|
@ -31,7 +31,7 @@ import java.lang.annotation.Target;
|
||||||
import javax.inject.Qualifier;
|
import javax.inject.Qualifier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Related to a resource of type Container, which is the userÕs root Container
|
* Related to a resource of type Container, which is the user's root Container
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
*
|
||||||
|
|
|
@ -101,7 +101,7 @@ public interface CloudFilesClient {
|
||||||
* <p/>
|
* <p/>
|
||||||
* Determine the number of Containers within the account and the total bytes stored. Since the
|
* Determine the number of Containers within the account and the total bytes stored. Since the
|
||||||
* storage system is designed to store large amounts of data, care should be taken when
|
* storage system is designed to store large amounts of data, care should be taken when
|
||||||
* representing the total bytes response as an ÒintegerÓ; when possible, convert it to a 64-bit
|
* representing the total bytes response as an integer; when possible, convert it to a 64-bit
|
||||||
* unsigned integer if your platform supports that primitive type.
|
* unsigned integer if your platform supports that primitive type.
|
||||||
*/
|
*/
|
||||||
@HEAD
|
@HEAD
|
||||||
|
@ -117,21 +117,21 @@ public interface CloudFilesClient {
|
||||||
* are supported with this request.
|
* are supported with this request.
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>limit - For an integer value N, limits the number of results to at most N values.</li>
|
* <li>limit - For an integer value N, limits the number of results to at most N values.</li>
|
||||||
* <li>marker - Given a string value X, return Object names greater in value than the speciÞed
|
* <li>marker - Given a string value X, return Object names greater in value than the specied
|
||||||
* marker.</li>
|
* marker.</li>
|
||||||
* <li>format - Specify either json or xml to return the respective serialized response.</li>
|
* <li>format - Specify either json or xml to return the respective serialized response.</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
* <p/>
|
* <p/>
|
||||||
* At this time, a ÒpreÞxÓ query parameter is not supported at the Account level.
|
* At this time, a prex query parameter is not supported at the Account level.
|
||||||
*
|
*
|
||||||
*<h4>Large Container Lists</h4>
|
*<h4>Large Container Lists</h4>
|
||||||
* The system will return a maximum of 10,000 Container names per request. To retrieve subsequent
|
* The system will return a maximum of 10,000 Container names per request. To retrieve subsequent
|
||||||
* container names, another request must be made with a ÔmarkerÕ parameter. The marker indicates
|
* container names, another request must be made with a marker parameter. The marker indicates
|
||||||
* where the last list left off and the system will return container names greater than this
|
* where the last list left off and the system will return container names greater than this
|
||||||
* marker, up to 10,000 again. Note that the ÔmarkerÕ value should be URL encoded prior to
|
* marker, up to 10,000 again. Note that the marker value should be URL encoded prior to
|
||||||
* sending the HTTP request.
|
* sending the HTTP request.
|
||||||
* <p/>
|
* <p/>
|
||||||
* If 10,000 is larger than desired, a ÔlimitÕ parameter may be given.
|
* If 10,000 is larger than desired, a limit parameter may be given.
|
||||||
* <p/>
|
* <p/>
|
||||||
* If the number of container names returned equals the limit given (or 10,000 if no limit is
|
* If the number of container names returned equals the limit given (or 10,000 if no limit is
|
||||||
* given), it can be assumed there are more container names to be listed. If the container name
|
* given), it can be assumed there are more container names to be listed. If the container name
|
||||||
|
|
|
@ -83,13 +83,13 @@ public class ListContainerOptions extends BaseHttpRequestOptions {
|
||||||
* For a string value X, return the Object names nested in the pseudo path.
|
* For a string value X, return the Object names nested in the pseudo path.
|
||||||
* <p/>
|
* <p/>
|
||||||
* Users will be able to simulate a hierarchical structure in Cloud Files by following a few
|
* Users will be able to simulate a hierarchical structure in Cloud Files by following a few
|
||||||
* guidelines. Object names must contain the forward slash character Ô/Õ as a path element
|
* guidelines. Object names must contain the forward slash character / as a path element
|
||||||
* separator and also create Òdirectory markerÓ Objects, then they will be able to traverse this
|
* separator and also create directory marker Objects, then they will be able to traverse this
|
||||||
* nested structure with the new ÒpathÓ query parameter.
|
* nested structure with the new path query parameter.
|
||||||
* <p/>
|
* <p/>
|
||||||
* To take advantage of this feature, the directory marker Objects must also be created to
|
* To take advantage of this feature, the directory marker Objects must also be created to
|
||||||
* represent the appropriate directories. The following additional Objects need to be created. A
|
* represent the appropriate directories. The following additional Objects need to be created. A
|
||||||
* good convention would be to create these as zero or one byte Þles with a Content-Type of
|
* good convention would be to create these as zero or one byte files with a Content-Type of
|
||||||
* application/directory
|
* application/directory
|
||||||
*/
|
*/
|
||||||
public ListContainerOptions underPath(String path) {
|
public ListContainerOptions underPath(String path) {
|
||||||
|
|
|
@ -37,7 +37,7 @@ public interface CloudFilesConstants extends RackspaceConstants {
|
||||||
*/
|
*/
|
||||||
String LIMIT = "limit";
|
String LIMIT = "limit";
|
||||||
/**
|
/**
|
||||||
* Given a string value X, return Object names greater in value than the speciÞed marker.
|
* Given a string value X, return Object names greater in value than the specified marker.
|
||||||
*/
|
*/
|
||||||
String MARKER = "marker";
|
String MARKER = "marker";
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -28,7 +28,7 @@ import org.joda.time.DateTime;
|
||||||
/**
|
/**
|
||||||
* An image is a collection of files used to create or rebuild a server. Rackspace provides a number
|
* An image is a collection of files used to create or rebuild a server. Rackspace provides a number
|
||||||
* of pre-built OS images by default. You may also create custom images from cloud servers you have
|
* of pre-built OS images by default. You may also create custom images from cloud servers you have
|
||||||
* launched. These custom images are useful for backup purposes or for producing ÒgoldÓ server
|
* launched. These custom images are useful for backup purposes or for producing gold server
|
||||||
* images if you plan to deploy a particular server configuration frequently.
|
* images if you plan to deploy a particular server configuration frequently.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
|
|
|
@ -97,7 +97,7 @@ public interface VCloudClient {
|
||||||
Future<? extends Task> undeploy(@Endpoint URI vApp);
|
Future<? extends Task> undeploy(@Endpoint URI vApp);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This call powers on the vApp, as specified in the vAppÕs ovf:Startup element.
|
* This call powers on the vApp, as specified in the vApp's ovf:Startup element.
|
||||||
*/
|
*/
|
||||||
@POST
|
@POST
|
||||||
@Consumes(TASK_XML)
|
@Consumes(TASK_XML)
|
||||||
|
@ -106,7 +106,7 @@ public interface VCloudClient {
|
||||||
Future<? extends Task> powerOn(@Endpoint URI vApp);
|
Future<? extends Task> powerOn(@Endpoint URI vApp);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This call powers off the vApp, as specified in the vAppÕs ovf:Startup element.
|
* This call powers off the vApp, as specified in the vApp's ovf:Startup element.
|
||||||
*/
|
*/
|
||||||
@POST
|
@POST
|
||||||
@Consumes(TASK_XML)
|
@Consumes(TASK_XML)
|
||||||
|
|
Loading…
Reference in New Issue