×

Welcome to TagMyCode

Please login or create account to add a snippet.
1
0
 
0
Language: PHP
Posted by: Massimo Zappino
Added: Oct 27, 2011 8:53 AM
Modified: Oct 27, 2011 8:58 AM
Views: 185
Since ZF 1.11.10 I've got a problem during copy object on S3. After a long search into the sources i found the problem.
The problem was on Zend_Http_Client class in the setMethod() function.
  1. <?php
  2.  
  3.  
  4. // The change that caused the error is this:
  5.         if (($method == self::POST || $method == self::PUT || $method == self::DELETE) && $this->enctype === null) {
  6.             $this->setEncType(self::ENC_URLENCODED);
  7.         }
  8.  
  9. // On ZF 1.11.1 it was:
  10. //        if ($method == self::POST && $this->enctype === null) {
  11. //            $this->setEncType(self::ENC_URLENCODED);
  12. //        }
  13.  
  14. // So the workaround is to set the encoding to false (a value !== null)
  15. // I created a new class that extends Zend_Service_Amazon_S3 where i added this line:
  16. $client->setEncType(false);
  17.  
  18.  
  19. class MyApp_Service_Amazon_S3 extends Zend_Service_Amazon_S3
  20. {
  21.  
  22.     public function _makeRequest($method, $path='', $params=null, $headers=array(), $data=null)
  23.     {
  24.         $retry_count = 0;
  25.  
  26.         if (!is_array($headers)) {
  27.             $headers = array($headers);
  28.         }
  29.  
  30.         $headers['Date'] = gmdate(DATE_RFC1123, time());
  31.  
  32.         if (is_resource($data) && $method != 'PUT') {
  33.             /**
  34.              * @see Zend_Service_Amazon_S3_Exception
  35.              */
  36.             require_once 'Zend/Service/Amazon/S3/Exception.php';
  37.             throw new Zend_Service_Amazon_S3_Exception("Only PUT request supports stream data");
  38.         }
  39.  
  40.         // build the end point out
  41.         $parts = explode('/', $path, 2);
  42.         $endpoint = clone($this->_endpoint);
  43.         if ($parts[0]) {
  44.             // prepend bucket name to the hostname
  45.             $endpoint->setHost($parts[0] . '.' . $endpoint->getHost());
  46.         }
  47.         if (!empty($parts[1])) {
  48.             // ZF-10218, ZF-10122
  49.             $pathparts = explode('?', $parts[1]);
  50.             $endpath = $pathparts[0];
  51.             $endpoint->setPath('/' . $endpath);
  52.         } else {
  53.             $endpoint->setPath('/');
  54.             if ($parts[0]) {
  55.                 $path = $parts[0] . '/';
  56.             }
  57.         }
  58.         self::addSignature($method, $path, $headers);
  59.  
  60.         $client = self::getHttpClient();
  61.  
  62.         $client->resetParameters(true);
  63.         $client->setUri($endpoint);
  64.         $client->setAuth(false);
  65.         // Work around buglet in HTTP client - it doesn't clean headers
  66.         // Remove when ZHC is fixed
  67.         /*
  68.           $client->setHeaders(array('Content-MD5'              => null,
  69.           'Content-Encoding'         => null,
  70.           'Expect'                   => null,
  71.           'Range'                    => null,
  72.           'x-amz-acl'                => null,
  73.           'x-amz-copy-source'        => null,
  74.           'x-amz-metadata-directive' => null));
  75.          */
  76.         $client->setHeaders($headers);
  77.  
  78.         // Workaround to fix enctype bug
  79.         $client->setEncType(false);
  80.  
  81.         if (is_array($params)) {
  82.             foreach ($params as $name => $value) {
  83.                 $client->setParameterGet($name, $value);
  84.             }
  85.         }
  86.  
  87.         if (($method == 'PUT') && ($data !== null)) {
  88.             if (!isset($headers['Content-type'])) {
  89.                 $headers['Content-type'] = self::getMimeType($path);
  90.             }
  91.             $client->setRawData($data, $headers['Content-type']);
  92.         }
  93.         do {
  94.             $retry = false;
  95.  
  96.             $response = $client->request($method);
  97.             $response_code = $response->getStatus();
  98.  
  99.             // Some 5xx errors are expected, so retry automatically
  100.             if ($response_code >= 500 && $response_code < 600 && $retry_count <= 5) {
  101.                 $retry = true;
  102.                 $retry_count++;
  103.                 sleep($retry_count / 4 * $retry_count);
  104.             } else if ($response_code == 307) {
  105.                 // Need to redirect, new S3 endpoint given
  106.                 // This should never happen as Zend_Http_Client will redirect automatically
  107.             } else if ($response_code == 100) {
  108.                 // echo 'OK to Continue';
  109.             }
  110.         } while ($retry);
  111.  
  112.         return $response;
  113.     }
  114.  
  115. }
  116.  
  117.  
  118.  

4 comments

Maksym Karazieiev 2 years ago
Thanks. that saved my day
Massimo Zappino 2 years ago
Happy for you
Maksym Karazieiev 2 years ago
Have a question, how did you forced Zend_Cloud_StorageService_Adapter_S3 use your service instead of hardcoded Zend_Service_Amazon_S3? If you remember ofcourse :)
Massimo Zappino 2 years ago
I used MyApp_Service_Amazon_S3 directly

$s3 = new MyApp_Service_Amazon_S3($my_aws_key, $my_aws_secret_key);

Write a comment