ZF-11669: Zend_Service_Amazon_S3::copyObject is not working

Description

After debugging I found out that the problem is related with Zend_Http_Client:

 
if (($method == self::POST || $method == self::PUT || $method == self::DELETE) && $this->enctype === null) {
    $this->setEncType(self::ENC_URLENCODED);
}

As copyObject executes a PUT request, I realized that encType can't be URLENCODED.

Comments

Related with ZF-11030 see r24269

This issue started after 1.11.10, as long as I know, the ZF 11030 path was applied in this version, consequently, it broke other services.

I just found this ticket after running into this bug myself. I'm using 1.11.10 and copyObject isn't working because the signatures aren't matching. This seems to be because of a urlencoding issue.

I can confirm it is related with ZF 11030. After this path, the content-type header is always set if not explicity defined. The problem is that for copy operation, if content-type was specified, Amazon S3 expects that it were included in auth header signature.

I propose the follow path:

--- S3.php (revision 24083)
+++ S3.php (working copy)
@@ -524,10 +524,12 @@
     {
         $sourceObject = $this->_fixupObjectName($sourceObject);
         $destObject   = $this->_fixupObjectName($destObject);
+        $sourceInfo = $this->getInfo($sourceObject);
 
         $headers = (is_array($meta)) ? $meta : array();
         $headers['x-amz-copy-source'] = $sourceObject;
         $headers['x-amz-metadata-directive'] = $meta === null ? 'COPY' : 'REPLACE';
+        $headers['Content-type'] = $sourceInfo['type'];
 
         $response = $this->_makeRequest('PUT', $destObject, null, $headers);

This way, content-type header is explicity defined as the same of original object. In my tests, this issue doesn't affect other operations.

I confirm that Thiago's patch works for me.

Thiago's patch would force the Content-type header to the Content-type of the source object and make it impossible to change the Content-type during the copy operation by passing the $meta array.

I suggest to only add the header if it is not already specified in the $meta array.

Came up against this tonight while using 1.11.10. Upgraded to 1.11.11 and still had the problem. Rolled back to an old 1.11.4 just cuz it was there, and the S3 moveObject + copyObject calls started to work again... Point being: Appears to be a problem in .10 + 1.11.11

I encountered this problem today in the latest build from Zend. This can be coded around though, rather than using a patch.

 
$s = $s3->getInfo($source);
$meta['Content-type'] = $s['type'];
return $this->getS3()->copyObject($source, $destination, $meta); 

Hope this helps.