諸般の事情により下記のとおり古いバージョンで試しています。最新版だとどうなるかはわかりません。
- PHP 5.3.3
- AWS SDK for PHP 2.8.27
AWS SDK for PHP で S3 の操作をしようとしたところ、バケット名にドットが無ければ成功するのに、ドットを含むと下記のようなエラーで失敗しました。
The bucket you are attempting to access must be addressed using the specified endpoint.
Please send all future requests to this endpoint: "oreore.s3.example.com.s3.amazonaws.com".
つまり、oreore-s3
なら大丈夫で、oreore.s3.example.com
みたいなのならダメ、ということです。
原因
S3 はバケット名をバーチャルホストスタイルとパススタイルのどちらかで指定できます。
- バーチャルホストスタイル
https://BUCKET.s3.amazonaws.com/KEY
- パススタイル
https://s3-ap-northeast-1.amazonaws.com/BUCKET/KEY
バーチャルホストスタイルではリージョンを意識する必要がありませんが、パススタイルだとリージョンによってエンドポイントが異なります。
バーチャルホストスタイルでは、バケット名にドットを含んでいなければ https が可能です。次のようなワイルドカード証明書があるからです。
*.s3.amazonaws.com
一方、ドットを含む場合は https 不可です。次のようなワイルドカード証明書は不可能だからです。
**.s3.amazonaws.com
AWS SDK で次の条件でバーチャルホストスタイルとパススタイルが使い分けられています。
-
https://github.com/aws/aws-sdk-php/blob/2.8.27/src/Aws/S3/BucketStyleListener.php#L63
- DNS のパートとして有効
- HTTPS ではない または ドットを含まない
- 以上の条件に合致するならバーチャルホストスタイルを使用する
バーチャルホストスタイルが使用される場合、前述の通りリージョンを意識する必要がないので、コード上でもリージョンを指定する必要はありませんが、パススタイルが使用される場合はリージョンを指定する必要があります。
パススタイルが使用されるにも関わらず(=バケット名にドットを含む)、リージョンを指定しなかった場合は、前述のようなエラーになります。
解決方法
次のようにリージョンを指定します。
$s3 = S3Client::factory(array(
ClientOptions::REGION =>Region::AP_NORTHEAST_1,
));
もしくは、http を使います。
$s3 = S3Client::factory(array(
ClientOptions::SCHEME => 'http',
));