使用ZF 1.11我使用$ s3-> copyObject()没有问题。我需要升级到ZF 1.12.20,但是当尝试复制对象时我得到了这个错误:
Zend_Http_Response::__set_state(array(
'version' => '1.1',
'code' => 403,
'message' => 'Forbidden',
'headers' =>
array (
'X-amz-request-id' => '07295DAF1500709B',
'X-amz-id-2' => '6zkAaIx0FHCZvgetRaMfCp6h6SfbHVbJoCrHqNdKN6AcfywOrrBCcSD13RcKvfiDBOJjiEm+ldM=',
'Content-type' => 'application/xml',
'Transfer-encoding' => 'chunked',
'Date' => 'Fri, 30 Sep 2016 12:30:03 GMT',
'Server' => 'AmazonS3',
'Connection' => 'close',
),
'body' => '610
SignatureDoesNotMatchThe request signature we calculated does not match the signature you provided. Check your key and signing method.AKIAJK6QI4DTZQ2X2SFAPUT
application/x-www-form-urlencoded
Fri, 30 Sep 2016 12:30:03 +0000
x-amz-copy-source:imgdeverasmusu/259/not-quite-reaching-potential-5f601d2088d7afc4fe69e1800bedc1cf.jpg
x-amz-metadata-directive:COPY
/imgdeverasmusu/259/eq-db37b6972b19800eaf310011ae00ffc2.jpg
如果我将类Zend_Http_Client 1.12.20更改为1.11,则副本可以使用,但不能使用1.12.20。
答案 0 :(得分:0)
<?php
//导致错误的更改是这样的: if((($ method == self :: POST || $ method == self :: PUT || $ method == self :: DELETE)&& $ this-> enctype === null){ $ this-> setEncType(self :: ENC_URLENCODED); }
//在ZF 1.11.1上是: //如果(($ method == self :: POST && $ this-> enctype === null){ // $ this-> setEncType(self :: ENC_URLENCODED); //}
//因此,解决方法是将编码设置为false(值!== null) //我创建了一个扩展Zend_Service_Amazon_S3的新类,在其中添加了以下行: $ client-> setEncType(false);
MyApp_Service_Amazon_S3类扩展了Zend_Service_Amazon_S3 {
public function _makeRequest($method, $path='', $params=null, $headers=array(), $data=null)
{
$retry_count = 0;
if (!is_array($headers)) {
$headers = array($headers);
}
$headers['Date'] = gmdate(DATE_RFC1123, time());
if (is_resource($data) && $method != 'PUT') {
/**
* @see Zend_Service_Amazon_S3_Exception
*/
require_once 'Zend/Service/Amazon/S3/Exception.php';
throw new Zend_Service_Amazon_S3_Exception("Only PUT request supports stream data");
}
// build the end point out
$parts = explode('/', $path, 2);
$endpoint = clone($this->_endpoint);
if ($parts[0]) {
// prepend bucket name to the hostname
$endpoint->setHost($parts[0] . '.' . $endpoint->getHost());
}
if (!empty($parts[1])) {
// ZF-10218, ZF-10122
$pathparts = explode('?', $parts[1]);
$endpath = $pathparts[0];
$endpoint->setPath('/' . $endpath);
} else {
$endpoint->setPath('/');
if ($parts[0]) {
$path = $parts[0] . '/';
}
}
self::addSignature($method, $path, $headers);
$client = self::getHttpClient();
$client->resetParameters(true);
$client->setUri($endpoint);
$client->setAuth(false);
// Work around buglet in HTTP client - it doesn't clean headers
// Remove when ZHC is fixed
/*
$client->setHeaders(array('Content-MD5' => null,
'Content-Encoding' => null,
'Expect' => null,
'Range' => null,
'x-amz-acl' => null,
'x-amz-copy-source' => null,
'x-amz-metadata-directive' => null));
*/
$client->setHeaders($headers);
// Workaround to fix enctype bug
$client->setEncType(false);
if (is_array($params)) {
foreach ($params as $name => $value) {
$client->setParameterGet($name, $value);
}
}
if (($method == 'PUT') && ($data !== null)) {
if (!isset($headers['Content-type'])) {
$headers['Content-type'] = self::getMimeType($path);
}
$client->setRawData($data, $headers['Content-type']);
}
do {
$retry = false;
$response = $client->request($method);
$response_code = $response->getStatus();
// Some 5xx errors are expected, so retry automatically
if ($response_code >= 500 && $response_code < 600 && $retry_count <= 5) {
$retry = true;
$retry_count++;
sleep($retry_count / 4 * $retry_count);
} else if ($response_code == 307) {
// Need to redirect, new S3 endpoint given
// This should never happen as Zend_Http_Client will redirect automatically
} else if ($response_code == 100) {
// echo 'OK to Continue';
}
} while ($retry);
return $response;
}
}