10

I'm trying to use the AWS SDK for PHP to programatically upload a file to a bucket that's set to be a static website in the S3 Console.

The bucket is named foo.ourdomain.com and is hosted in eu-west. I'm using the following code to try and test if I can upload a file:

  $client = \Aws\S3\S3Client::factory(array('key' => bla, 'secret' => bla));
  $client->upload('foo.ourdomain.com', 'test.txt', 'hello world', 'public-read');

This is pretty much like it is in the examples, however, I received the following exception:

PHP Fatal error: Uncaught Aws\S3\Exception\PermanentRedirectException: AWS Error Code: PermanentRedirect, Status Code: 301, AWS Request ID: -, AWS Error Type: client, AWS Error Message: The bucket you are attempting to access must be addressed using the specified endpoint. Please send all future requests to this endpoint: "foo.ourdomain.com.s3.amazonaws.com"., User-Agent: aws-sdk-php2/2.4.8 Guzzle/3.7.4 curl/7.22.0 PHP/5.3.10-1ubuntu3.8

At this point I was surprised as there's no mention of this in the manual for the S3 SDK. But okay, I found a method setEndpoint and adjusted the code to:

   $client = \Aws\S3\S3Client::factory(array('key' => bla, 'secret' => bla));
   $client->setEndpoint('foo.ourdomain.com.s3.amazonaws.com');
   $client->upload('foo.ourdomain.com', 'test.txt', 'hello world', 'public-read');

I assumed that'd work, but I'm getting the exact same error. I've doublechecked and the endpoint mentioned in the exception byte-for-byte matches the one I'm setting in the second line.

I've also tried using foo.ourdomain.com.s3-website-eu-west-1.amazonaws.com as the endpoint (this is the host our CNAME points to as per the S3 consoles instructions). Didn't work either.

I must be missing something, but I can't find it anywhere. Perhaps buckets set to 'static website' behave differently in a way which is not currently supported by the SDK? If so, I can't find mention of it in the docs nor in the management console.

4

2 回答 2

19

知道了。解决方案是将客户端的初始化更改为:

$client = \Aws\S3\S3Client::factory(array(
  'key' => bla, 
  'secret' => bla, 
  'region' => 'eu-west-1'
));

即,我不需要指定一个端点,而是在选项数组中显式设置区域。我猜示例代码恰好使用了默认区域。

于 2013-11-04T13:16:27.023 回答
5

If you don't want to initialize the client to a specific region and/or you'll need to work with different regions, I have been successful in using the getBucketLocation/setRegion set of calls as follows:

// Bucket location is fetched
$m_bucketLocation = $I_s3->getBucketLocation(array(
        'Bucket' => $s_backupBucket,
));
// Bucket location is specified before operation is made
$I_s3->setRegion($m_bucketLocation['Location']);

I have one extra call, but solved my issue without the need to intervene on the factory.

于 2014-02-11T14:05:53.593 回答