Установите правильную конечную точку для клиента S3 в Amazon AWS PHP SDK

Я пытаюсь использовать AWS SDK для PHP, чтобы запрограммировать загрузку файла в ведро, установленное как статический веб-сайт в консоли S3.

Ведро называется foo.ourdomain.com и размещено на eu-west. Я использую следующий код, чтобы попробовать и проверить, могу ли я загрузить файл:

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

Это очень похоже на примеры, однако я получил следующее исключение:

PHP Неустранимая ошибка: Uncaught Aws\S3\Exception\PermanentRedirectException: AWS Код ошибки: PermanentRedirect, код состояния: 301, AWS Идентификатор запроса: -, AWS Тип ошибки: клиент, сообщение AWS Error: ведро, к которому вы пытаетесь получить доступ должны быть решены с использованием указанной конечной точки. Пожалуйста, отправьте все будущие запросы в эту конечную точку: "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

В этот момент я был удивлен, так как об этом не упоминалось в руководстве для S3 SDK. Но все в порядке, я нашел метод setEndpoint и скорректировал код:

   $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');

Я предположил, что это сработает, но я получаю ту же ошибку. Я дважды проверял, и конечная точка, указанная в байте за исключением, совпадает с тем, который я устанавливаю во второй строке.

Я также пробовал использовать foo.ourdomain.com.s3-website-eu-west-1.amazonaws.com в качестве конечной точки (это хост, на который указывает CNAME в соответствии с инструкциями консоли S3). Не работает.

Мне что-то не хватает, но я не могу найти его нигде. Возможно, ведра, установленные на "статический веб-сайт", ведут себя по-разному таким образом, который в настоящее время не поддерживается SDK? Если это так, я не могу найти упоминание об этом в документах и ​​на консоли управления.

Ответ 1

Получил это. Решение заключалось в том, чтобы изменить инициализацию клиента на:

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

т.е. вместо того, чтобы указывать конечную точку, мне нужно было явно указать область в массиве параметров. Я предполагаю, что код примера используется для использования независимо от области по умолчанию.

Ответ 2

Если вы не хотите инициализировать клиента в определенном регионе и/или вам нужно работать с разными регионами, мне удалось использовать набор вызовов getBucketLocation/setRegion следующим образом:

// 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']);

У меня есть один дополнительный вызов, но я решил проблему без необходимости вмешиваться в factory.