diff --git a/aws/s3/core/src/main/java/org/jclouds/aws/s3/commands/CopyObject.java b/aws/s3/core/src/main/java/org/jclouds/aws/s3/commands/CopyObject.java index 358ec3b89b..d3356d6bd2 100644 --- a/aws/s3/core/src/main/java/org/jclouds/aws/s3/commands/CopyObject.java +++ b/aws/s3/core/src/main/java/org/jclouds/aws/s3/commands/CopyObject.java @@ -29,6 +29,7 @@ import org.jclouds.aws.s3.commands.options.CopyObjectOptions; import org.jclouds.aws.s3.domain.S3Object; import org.jclouds.aws.s3.xml.CopyObjectHandler; import org.jclouds.http.commands.callables.xml.ParseSax; +import org.jclouds.util.Utils; import com.google.inject.Inject; 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) * specify a new ACL} when generating a copy request. * - * @see + * @see * @see CopyObjectOptions * @see org.jclouds.aws.s3.domain.acl.CannedAccessPolicy * @author Adrian Cole @@ -53,24 +55,24 @@ import com.google.inject.name.Named; */ public class CopyObject extends S3FutureCommand { - @Inject - public CopyObject(@Named("jclouds.http.address") String amazonHost, - ParseSax callable, - @Assisted("sourceBucket") String sourceBucket, - @Assisted("sourceObject") String sourceObject, - @Assisted("destinationBucket") String destinationBucket, - @Assisted("destinationObject") String destinationObject, - @Assisted CopyObjectOptions options) { - super("PUT", - "/" + checkNotNull(destinationObject, "destinationObject"), - callable, amazonHost, destinationBucket); - CopyObjectHandler handler = (CopyObjectHandler) callable.getHandler(); - handler.setKey(destinationObject); - getRequest().getHeaders().put( - "x-amz-copy-source", - String.format("/%1$s/%2$s", checkNotNull(sourceBucket, - "sourceBucket"), checkNotNull(sourceObject, - "sourceObject"))); - getRequest().getHeaders().putAll(options.buildRequestHeaders()); - } + @Inject + public CopyObject(@Named("jclouds.http.address") String amazonHost, + ParseSax callable, @Assisted("sourceBucket") String sourceBucket, + @Assisted("sourceObject") String sourceObject, + @Assisted("destinationBucket") String destinationBucket, + @Assisted("destinationObject") String destinationObject, + @Assisted CopyObjectOptions options) + { + super("PUT", + "/" + checkNotNull(destinationObject, "destinationObject"), + callable, amazonHost, destinationBucket); + CopyObjectHandler handler = (CopyObjectHandler) callable.getHandler(); + handler.setKey(destinationObject); + getRequest().getHeaders().put( + "x-amz-copy-source", + String.format("/%1$s/%2$s", + checkNotNull(sourceBucket, "sourceBucket"), + Utils.encodeUriPath(checkNotNull(sourceObject, "sourceObject")))); + getRequest().getHeaders().putAll(options.buildRequestHeaders()); + } } \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/http/HttpRequest.java b/core/src/main/java/org/jclouds/http/HttpRequest.java index 58cd71fa08..21d4c7d49b 100644 --- a/core/src/main/java/org/jclouds/http/HttpRequest.java +++ b/core/src/main/java/org/jclouds/http/HttpRequest.java @@ -26,12 +26,11 @@ package org.jclouds.http; import static com.google.common.base.Preconditions.checkNotNull; import java.io.InputStream; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; import javax.annotation.Resource; import org.jclouds.logging.Logger; +import org.jclouds.util.Utils; /** * Represents a request that can be executed within @@ -50,7 +49,7 @@ public class HttpRequest extends HttpMessage { public HttpRequest(String method, String uri) { this.method = checkNotNull(method, "method"); - this.uri = encodeUri(checkNotNull(uri, "uri")); + this.uri = Utils.encodeUriPath(checkNotNull(uri, "uri")); } @Override @@ -90,33 +89,4 @@ public class HttpRequest extends HttpMessage { 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; - } - } diff --git a/core/src/main/java/org/jclouds/util/Utils.java b/core/src/main/java/org/jclouds/util/Utils.java index 945c3f1e52..583052bdbb 100644 --- a/core/src/main/java/org/jclouds/util/Utils.java +++ b/core/src/main/java/org/jclouds/util/Utils.java @@ -26,6 +26,7 @@ package org.jclouds.util; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; import java.util.concurrent.ExecutionException; import javax.annotation.Resource; @@ -144,5 +145,35 @@ public class Utils { public static String decodeString(byte[] bytes) { 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; + } + }