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.

Marlies
  • 919
  • 1
  • 5
  • 17

2 Answers2

19

Got it. The solution was to change the initialisation of the client to:

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

I.e. rather than specify an endpoint I needed to explicitly set the region in the options array. I guess the example code happens to use whatever the default region is.

ericteubert
  • 4,391
  • 3
  • 29
  • 35
Marlies
  • 919
  • 1
  • 5
  • 17
  • Right, the SDK defaults to the global region/endpoint. If you created the bucket in a specific region, you need to sent the S3Client to use that region. – Jeremy Lindblom Nov 05 '13 at 07:36
  • 2
    strange though that the remark in the error is quite specific as to how to fix it, but also quite wrong :) – Nanne Nov 05 '13 at 10:42
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.

maraspin
  • 2,295
  • 19
  • 15