CopyObject command now works with non-ASCII object names

git-svn-id: http://jclouds.googlecode.com/svn/trunk@881 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
jamurty 2009-05-30 06:57:55 +00:00
parent 58e5b51c59
commit 3d41d6b107
3 changed files with 57 additions and 54 deletions

View File

@ -29,6 +29,7 @@ import org.jclouds.aws.s3.commands.options.CopyObjectOptions;
import org.jclouds.aws.s3.domain.S3Object; import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.aws.s3.xml.CopyObjectHandler; import org.jclouds.aws.s3.xml.CopyObjectHandler;
import org.jclouds.http.commands.callables.xml.ParseSax; import org.jclouds.http.commands.callables.xml.ParseSax;
import org.jclouds.util.Utils;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted; import com.google.inject.assistedinject.Assisted;
@ -45,7 +46,8 @@ import com.google.inject.name.Named;
* {@link CopyObjectOptions#overrideAcl(org.jclouds.aws.s3.domain.acl.CannedAccessPolicy) * {@link CopyObjectOptions#overrideAcl(org.jclouds.aws.s3.domain.acl.CannedAccessPolicy)
* specify a new ACL} when generating a copy request. * specify a new ACL} when generating a copy request.
* *
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTObjectCOPY.html" /> * @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTObjectCOPY.html"
* />
* @see CopyObjectOptions * @see CopyObjectOptions
* @see org.jclouds.aws.s3.domain.acl.CannedAccessPolicy * @see org.jclouds.aws.s3.domain.acl.CannedAccessPolicy
* @author Adrian Cole * @author Adrian Cole
@ -55,12 +57,12 @@ public class CopyObject extends S3FutureCommand<S3Object.Metadata> {
@Inject @Inject
public CopyObject(@Named("jclouds.http.address") String amazonHost, public CopyObject(@Named("jclouds.http.address") String amazonHost,
ParseSax<S3Object.Metadata> callable, ParseSax<S3Object.Metadata> callable, @Assisted("sourceBucket") String sourceBucket,
@Assisted("sourceBucket") String sourceBucket,
@Assisted("sourceObject") String sourceObject, @Assisted("sourceObject") String sourceObject,
@Assisted("destinationBucket") String destinationBucket, @Assisted("destinationBucket") String destinationBucket,
@Assisted("destinationObject") String destinationObject, @Assisted("destinationObject") String destinationObject,
@Assisted CopyObjectOptions options) { @Assisted CopyObjectOptions options)
{
super("PUT", super("PUT",
"/" + checkNotNull(destinationObject, "destinationObject"), "/" + checkNotNull(destinationObject, "destinationObject"),
callable, amazonHost, destinationBucket); callable, amazonHost, destinationBucket);
@ -68,9 +70,9 @@ public class CopyObject extends S3FutureCommand<S3Object.Metadata> {
handler.setKey(destinationObject); handler.setKey(destinationObject);
getRequest().getHeaders().put( getRequest().getHeaders().put(
"x-amz-copy-source", "x-amz-copy-source",
String.format("/%1$s/%2$s", checkNotNull(sourceBucket, String.format("/%1$s/%2$s",
"sourceBucket"), checkNotNull(sourceObject, checkNotNull(sourceBucket, "sourceBucket"),
"sourceObject"))); Utils.encodeUriPath(checkNotNull(sourceObject, "sourceObject"))));
getRequest().getHeaders().putAll(options.buildRequestHeaders()); getRequest().getHeaders().putAll(options.buildRequestHeaders());
} }
} }

View File

@ -26,12 +26,11 @@ package org.jclouds.http;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import java.io.InputStream; import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import javax.annotation.Resource; import javax.annotation.Resource;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import org.jclouds.util.Utils;
/** /**
* Represents a request that can be executed within * Represents a request that can be executed within
@ -50,7 +49,7 @@ public class HttpRequest extends HttpMessage {
public HttpRequest(String method, String uri) { public HttpRequest(String method, String uri) {
this.method = checkNotNull(method, "method"); this.method = checkNotNull(method, "method");
this.uri = encodeUri(checkNotNull(uri, "uri")); this.uri = Utils.encodeUriPath(checkNotNull(uri, "uri"));
} }
@Override @Override
@ -90,33 +89,4 @@ public class HttpRequest extends HttpMessage {
this.payload = content; this.payload = content;
} }
/**
* Encode a path portion of a URI using the UTF-8 encoding, but leave slash '/'
* characters and any parameters (anything after the first '?') unencoded.
* If encoding with UTF-8 fails, the method falls back to using the
* system's default encoding.
*
* @param uri
* @return
*/
protected String encodeUri(String uri) {
String path, params = "";
int offset;
if ((offset = uri.indexOf('?')) >= 0) {
path = uri.substring(0, offset);
params = uri.substring(offset);
} else {
path = uri;
}
String encodedUri;
try {
encodedUri = URLEncoder.encode(path, "UTF-8");
} catch (UnsupportedEncodingException e) {
encodedUri = URLEncoder.encode(path);
}
return encodedUri.replace("%2F", "/") + params;
}
} }

View File

@ -26,6 +26,7 @@ package org.jclouds.util;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import javax.annotation.Resource; import javax.annotation.Resource;
@ -145,4 +146,34 @@ public class Utils {
return decodeString(bytes, UTF8_ENCODING); return decodeString(bytes, UTF8_ENCODING);
} }
/**
* Encode a path portion of a URI using the UTF-8 encoding, but leave slash '/'
* characters and any parameters (anything after the first '?') un-encoded.
* If encoding with UTF-8 fails, the method falls back to using the
* system's default encoding.
*
* @param uri
* @return
*/
@SuppressWarnings("deprecation")
public static String encodeUriPath(String uri) {
String path, params = "";
int offset;
if ((offset = uri.indexOf('?')) >= 0) {
path = uri.substring(0, offset);
params = uri.substring(offset);
} else {
path = uri;
}
String encodedUri;
try {
encodedUri = URLEncoder.encode(path, "UTF-8");
} catch (UnsupportedEncodingException e) {
encodedUri = URLEncoder.encode(path);
}
return encodedUri.replace("%2F", "/") + params;
}
} }