0

I am uploading files from php to aws s3. I have successfully uploaded the file.

The url it is returning is => https://BUCKETNAME.s3.ap-south-1.amazonaws.com/images1740/1550830121572.jpg

The actual url is => https://s3.ap-south-1.amazonaws.com/BUCKETNAME/images1740/1550830121572.jpg (bucket name is coming in starting instead at the end of url)

Because of this it is giving me error while loading images => "Specified Key not found"

$source = $source;
$bucket = 'xxxxxxxxxxxxxxxxx';
$keyname = 'images'.$usr_id."/".$name;

// for push

$s3 = S3Client::factory(
    array(
        'credentials' => array(
            'key'    => "xxxxxxxxxxxxxx",
            'secret' => "xxxxxxxxxxxxxxx"
        ),
        'version' => 'latest',
        'region'  => 'ap-south-1'
    )
);

try {
    // Upload data.
    $result = $s3->putObject(array(
        'Bucket' => $bucket,
        'Key'    => $keyname,
        'SourceFile' => $source,
        'ServerSideEncryption' => 'AES256',
    ));

    // Print the URL to the object.
    print_r($result);
    return $result['ObjectURL'] . PHP_EOL;
    // print_r($result);
} catch (S3Exception $e) {
    echo $e->getMessage() . PHP_EOL;
}
Praveen
  • 60
  • 1
  • 7
  • Is this a new bucket you just created ? If it is, it takes a couple of hours to get the alias https://BUCKETNAME.s3.ap-south-1.amazonaws.com working (the time required for the DNS update and propagation). It is better to use the pattern https://s3.ap-south-1.amazonaws.com/BUCKETNAME as it gives consistent results, even just after bucket creation – Sébastien Stormacq Feb 22 '19 at 11:03
  • Bucket is not new. I have created this bucket one month ago. – Praveen Feb 22 '19 at 11:14
  • OK. How are you accessing your object ? Is this HTTP or API call ? Would you mind to share also the code you're using to access the object. If you are using HTTP, can you post the output of a `curl -vvv with both URLs to check the difference – Sébastien Stormacq Feb 22 '19 at 11:21
  • I am using "AWS SDK" for PHP and the to upload I have used "putObject()" method of s3 client – Praveen Feb 22 '19 at 11:28
  • 1
    @SébastienStormacq note that the DNS delay after bucket creation only applies if you try to access the bucket using the non-regional-specific "global" endpoint, `https://example-bucket.s3.amazonaws.com`. Using either path or virtual style with the correct *regional* endpoint will work immediately. – Michael - sqlbot Feb 22 '19 at 15:05

1 Answers1

7

Set use_path_style_endpoint to true when initializing the S3 client to have it use the S3 path style endpoint by default when building the object URL. 1

Implementation details has the object URL to be in the path style if the bucket name makes a valid domain name otherwise it fallback to the S3 path style.
You want to keep the later behavior all the time.

$s3 = S3Client::factory(
    array(
        'credentials' => array(
            'key'    => "xxxxxxxxxxxxxx",
            'secret' => "xxxxxxxxxxxxxxx"
        ),
        'use_path_style_endpoint' => true,
        'version' => 'latest',
        'region'  => 'ap-south-1'
    )
);

You can also do as below if you wanted to disable it one-time for the PutObject operation.

$result = $s3->putObject(array(
    'Bucket' => $bucket,
    'Key'    => $keyname,
    'SourceFile' => $source,
    'ServerSideEncryption' => 'AES256',
    '@use_path_style_endpoint' => true
));
Oluwafemi Sule
  • 36,144
  • 1
  • 56
  • 81
  • 2
    While this answer is technically accurate in its explanation of how to force use of the path style endpoint even when not necessary, one point to consider is that these endpoints are *completely interchangeable* except when the bucket itself has one or more dots `.` in its name. (This includes *"if the bucket name makes a valid domain name"* but should also be true if the bucket is not a valid domain name but still contains at least one dot.) Either endpoint will work, neither is more correct than the other, and using one instead of the other does not explain a "no such key" error. – Michael - sqlbot Feb 22 '19 at 15:23