Change base URL of generated S3 link using AWS SDK (PHP) - amazon-web-services

I want to create presigned S3 URL as mentioned here:
https://docs.aws.amazon.com/aws-sdk-php/v3/guide/service/s3-presigned-url.html
My code is quite similar to the example mentioned in the url:
$sdk = new Aws\Sdk( [
'region' => 'eu-west-2',
'version' => 'latest',
] );
$s3Client = $sdk->createS3();
$cmd = $s3Client->getCommand('GetObject', [
'Bucket' => 'books.com',
'Key' => 'testKey'
]);
$request = $s3Client->createPresignedRequest($cmd, '+20 minutes');
// Get the actual presigned-url
$presignedUrl = (string) $request->getUri();
The above generates urls like so:
https://s3.eu-west-2.amazonaws.com/books.com/testKey?X-Amz-Content-Sha256=....
This is as expected. However my S3 bucket has Static Website Hosting and I use a CNAME record allowing me to use a different base url.
Therefore I want the following URL instead:
http://books.com/my-bucket/testKey?X-Amz-Content-Sha256=....
How can I do this?

You can set the endpoint to your bucket domain name:
$sdk = new Aws\Sdk( [
'region' => 'eu-west-2',
'version' => 'latest',
'endpoint' => 'http://books.com',
'bucket_endpoint' => true
] );
This will generate a signed URL that looks like this:
http://books.com/testKey?X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAI2V4Lxxxxxxxxxxx%2F20171116%2Feu-west-2%2Fs3%2Faws4_request&X-Amz-Date=20171116T191003Z&X-Amz-SignedHeaders=host&X-Amz-Expires=1200&X-Amz-Signature=0b735cb661b1d2e25c7f5b477d4c657f160a85aa53bee3ea91244340f6d37dee

Related

Setting Cache-Control header, AWS S3 presigned URL image upload from browser

I'm trying to work with AWS PHP SDK using PostObjectV4 to upload image from clients browser.
$client = new S3Client([
'version' => 'latest',
'region' => 'us-east-2',
'credentials' => [
'key' => S3_KEY,
'secret' => S3_SECRET,
]
]);
$bucket = 'bucketsomewhere.coim';
$formInputs = ['acl' => 'public-read'];
$options = [
['acl' => 'public-read'],
['bucket' => $bucket],
['starts-with', '$key', 'Users/'],
['starts-with', '$Content-Type', 'image/'],
['starts-with', '$Cache-Control', 'max-age='],
];
$expires = '+40 minutes';
$postObject = new \Aws\S3\PostObjectV4(
$client,
$bucket,
$formInputs,
$options,
$expires
);
After sending POST request from JS. It gives me following error:
Invalid according to Policy: Policy Condition failed: ["starts-with", "$Cache-Control", "max-age=31536000"]
I read it about from their docs, but no success. Help is needed :) .

Send attachment from s3 bucket using Mailgun

Trying to send an email with inline images embed. Only the file is not located on the server it is in an S3 bucket. How can this be done? The standard API doesn't seem to be reading the images into the email.
require 'vendor/autoload.php';
use Mailgun\Mailgun;
# Instantiate the client.
$mgClient = Mailgun::create('PRIVATE_API_KEY', 'https://API_HOSTNAME');
$domain = "YOUR_DOMAIN_NAME";
$params = array(
'from' => 'Excited User <YOU#YOUR_DOMAIN_NAME>',
'to' => 'bob#example.com',
'subject' => 'Hello',
'text' => 'Testing some Mailgun awesomness!',
'html' => '<html>Inline image: <img src="cid:test.jpg"></html>',
'inline' => array(
array('filePath' => '/path/to/image.jpg'))
);
# Make the call to the client.
$result = $mgClient->messages()->send($domain, $params);
By using inline param you can send the images with the correct path.

Save AWS Polly mp3 file to S3

I am trying to send some text to AWS Polly to convert to speech and then save that mp3 file to S3. That part seems to work now.
// Send text to AWS Polly
$client_polly = new Aws\Polly\PollyClient([
'region' => 'us-west-2',
'version' => 'latest',
'credentials' => [
'key' => $aws_useKey,
'secret' => $aws_secret,
]
]);
$text = 'Test. Test. This is a sample text to be synthesized.';
$voice = 'Matthew';
$result_polly = $client_polly->startSpeechSynthesisTask([
'Text' => $text,
'TextType' => 'text',
'OutputFormat' => 'mp3',
'OutputS3BucketName' => $aws_bucket,
'OutputS3KeyPrefix' => 'files/audio/,
'VoiceId' => $voice,
'ACL' => 'public-read'
]);
echo $result_polly['ObjectURL'];
I'm also trying to accomplish couple other things:
Make mp3 file publicly accessible. Currently I have to go to AWS console to
click "Make Public" button. It seems that 'ACL' => 'public-read' doesn't work for me
I need to return full URL of the mp3 file. For some reason $result_polly['ObjectURL']; doesn't get any value.
What am I missing?
There is no ACL field in the StartSpeechSynthesisTask call:
$result = $client->startSpeechSynthesisTask([
'LanguageCode' => 'arb|cmn-CN|cy-GB|da-DK|de-DE|en-AU|en-GB|en-GB-WLS|en-IN|en-US|es-ES|es-MX|es-US|fr-CA|fr-FR|is-IS|it-IT|ja-JP|hi-IN|ko-KR|nb-NO|nl-NL|pl-PL|pt-BR|pt-PT|ro-RO|ru-RU|sv-SE|tr-TR',
'LexiconNames' => ['<string>', ...],
'OutputFormat' => 'json|mp3|ogg_vorbis|pcm', // REQUIRED
'OutputS3BucketName' => '<string>', // REQUIRED
'OutputS3KeyPrefix' => '<string>',
'SampleRate' => '<string>',
'SnsTopicArn' => '<string>',
'SpeechMarkTypes' => ['<string>', ...],
'Text' => '<string>', // REQUIRED
'TextType' => 'ssml|text',
'VoiceId' => 'Aditi|Amy|Astrid|Bianca|Brian|Carla|Carmen|Celine|Chantal|Conchita|Cristiano|Dora|Emma|Enrique|Ewa|Filiz|Geraint|Giorgio|Gwyneth|Hans|Ines|Ivy|Jacek|Jan|Joanna|Joey|Justin|Karl|Kendra|Kimberly|Lea|Liv|Lotte|Lucia|Mads|Maja|Marlene|Mathieu|Matthew|Maxim|Mia|Miguel|Mizuki|Naja|Nicole|Penelope|Raveena|Ricardo|Ruben|Russell|Salli|Seoyeon|Takumi|Tatyana|Vicki|Vitoria|Zeina|Zhiyu', // REQUIRED
]);
Therefore, you will either need to make another call to Amazon S3 to change the ACL of the object, or use an Amazon S3 Bucket Policy to make the bucket (or a path within the bucket) public.
The output location is given in the OutputUri field (NOT OutputUrl -- URI vs URL).

AWS Environment variable provider not accepting credentials

I'm connecting dynamoDb locally using the below code
$dotenv = new Dotenv\Dotenv(dirname(__DIR__, 2));
$dotenv->load();
$this->key = getenv('aws_access_key_id');
$this->secret = getenv('aws_secret_access_key');
$this->dynamodb = new DynamoDbClient([
'profile' => 'default',
'region' => 'us-east-1',
'version' => 'latest',
'credentials' => [
'key' => $this->key,
'secret' => $this->secret,
]
]);
My .env file
aws_access_key_id = ....
aws_secret_access_key = ....
I'm getting this error
Type: Aws\Exception\CredentialsException
Message: Cannot read credentials from /Users/user/.aws/credentials
File: /path/to/project/vendor/aws/aws-sdk-php/src/Credentials/CredentialProvider.php
Line: 394
Tried the basic hard-coding of access key & secret key as well but it doesn't seem to be working rather every time it's fetching from the default path ~/.aws/credentials
TIA
Try without specifying:
'profile' => 'default'
You want to use the default profile that is specified in the credentials file. It is possible the SDK looks at this line and try to open the credentials file and look for default profile. I don't have PHP SDK installed to verify this..
Try to print the environment variable to make sure your application is getting those environment variables.
It is not finding it from those variables. You need to export them before you run this script.
Hope it helps.
EDIT1:
use Aws\Common\Credentials\Credentials;
$credentials = new Credentials('YOUR_ACCESS_KEY', 'YOUR_SECRET_KEY');
//assign these credentials to Dynamodbclient
EDIT2: AWS SDK 3.x follows different way to initialize.
$sdk = new Aws\Sdk([
'credentials' => $credentials,
'region' => 'us-east-1',
'version' => 'latest',
'DynamoDb' => [
'region' => 'us-west-2',
],
]);
$dynamodb = $sdk->createDynamoDb(); // This is dynamodb client

Unable to get Directory listing of S3 bucket using PHP SDK, EC2

I am using PHP sdk to get list of files in folder form S3.
When I run the php form my localhost, I get the files listing. But when I run the same Php form EC2, it does not work, no error return.
<?php
header('Access-Control-Allow-Origin: *');
require './vendor/autoload.php';
use Aws\S3\S3Client;
use Aws\S3\Exception\S3Exception;
$folderId = $_REQUEST["folderid"];
//echo $folderId;
// Create an S3 client
$client = new \Aws\S3\S3Client([
'region' => 'ap-south-1',
'version' => '2006-03-01',
'credentials' => array(
'key' => 'zzzzzz',
'secret' => 'xxxxxxx',
),
]);
$folderPath = "thumb_images/{$folderId}/";
//echo "<br />".$folderPath."<br />";
$objects = $client->getIterator('ListObjects', array(
"Bucket" => 'bucket_name',
"Prefix" => $folderPath //must have the trailing forward slash "/"
));
foreach ($objects as $object) {
echo $object['Key'] . "<br>";
}
?>