How to get the file from Amazon AWS S3 bucket from URL? - amazon-web-services

I've created an Amazon S3 bucket and I've uploaded the files/images from mobile phone app. I've to show the posts with a lot of images and the images are automatically bind for image URLs. But I don't know how to get the URL because images should not be public to show directly. How can I show them in my app?
$cmd = $client->getCommand('GetObject',[
'Bucket' => 'myinstaclassbucket',
'Key' => 'e12e682c-936d-4a97-a049-6f104dd7c904.jpg',
]);
$request = $client->createPresignedRequest($cmd,$timetoexpire);
$presignedurl = (string) $request->getUri();
echo $presignedurl;

First of all you need to use AWS PHP SDK. Also make sure you have valid Access key and Secret key.
Than everything is straight forward.
$bucket = 'some-bucket';
$key = 'mainFolder/subFolder/file.xx';
// Init client
$client = new S3Client([
'key' => '*YOUR ACCESS KEY*',
'secret' => '*YOUR SECRET KEY*',
]);
if ($client->doesObjectExists($bucket, $key)) {
// If passing `expire` time you will get signed URL
$url = $client->getObjectUrl($bucket, $key, time() + (60 * 60 * 2));
} else {
$url = null;
}

Related

Aws sdk for .NET custom region endpoint configuration

I am trying to configure aws sdk for .net for using cloud service provider which provides aws compatible api. The code below for uploading using aws sdk for php works, but how to configure it properly for aws sdk .net, especially regions part:
This code works in php:
$bucketName = 'big_bucket';
$filePath = './img33.png';
$keyName = basename($filePath);
$IAM_KEY = 'top_secret_key';
$IAM_SECRET = 'top_secret_secret';
use Aws\S3\S3Client;
use Aws\S3\Exception\S3Exception;
// Set Amazon S3 Credentials
$s3 = S3Client::factory(
array(
'endpoint' => 'https://s3-kna1.citycloud.com:8080',
'credentials' => array(
'key' => $IAM_KEY,
'secret' => $IAM_SECRET
),
'version' => 'latest',
'region' => 's3-kna1',
'use_path_style_endpoint' => true
)
);
$s3->putObject(
array(
'Bucket'=>$bucketName,
'Key' => $keyName,
'SourceFile' => $keyName,
'StorageClass' => 'REDUCED_REDUNDANCY',
'ACL' => 'public-read'
)
);
The code below for .net does not work yet:
using Amazon.S3;
using Amazon.S3.Model;
using Amazon.S3.Transfer;
public class CityCloudFileHandler
{
private string _accessKey;
private string _secretKey;
private string _mediaBucket;
private string _serviceUrl;
private S3CannedACL _s3CannedAcl;
private AmazonS3Config _s3Config;
public CityCloudFileHandler(string accessKey, string secretKey, string mediaBucket, string serviceUrl,
S3CannedACL s3CannedAcl = null)
{
_accessKey = accessKey;
_secretKey = secretKey;
_mediaBucket = mediaBucket;
_serviceUrl = serviceUrl;
_s3CannedAcl = s3CannedAcl;
_s3Config = new AmazonS3Config
{
ServiceURL = "https://s3-kna1.citycloud.com:8080",
ForcePathStyle = true
};
}
private IAmazonS3 MediaS3()
{
return new AmazonS3Client(_accessKey, _secretKey, _s3Config);
}
}
A lot of the constructors for the AmazonS3Client accept a RegionEndpoint example. The value looks like this:
RegionEndpoint.USWest2 or RegionEndpoint.USEast1
Here is a link to the AmazonS3Client API documentation: AmazonS3Client
In addition, if you have setup a default user using the AWS CLI by creating two files (stored in: C:\Users\USER_NAME.aws\ on Windows)
The file credentials should contain the following information:
[default]
aws_access_key_id = your_access_key_id
aws_secret_access_key = your_secret_access_key
and a second file named config will contain (at least) the following lines:
[default]
region = us-east-2
Once that user has been setup, you can call the client constructor without parameters as long as the bucket is in the same region as the default user.
There is an example for uploading objects to an S3 bucket here: UploadObjectExample

Unable to move files completely to S3 bucket using AWS SDK for PHP

I'm trying to get past a road block situation related to S3.
Background: From my mobile app users can pick upto 10 images and post it to server. This is received and moved to concerned folders in AWS instance - Let's call it instance "A" for the purpose of our discussion. As and when the file is moved to instance "A" we are calling "moveFileToS3" . The code looks something like this.
foreach($_FILES as $file)
{
$file_info = $file['name'];
$extension = pathinfo($file['name'],PATHINFO_EXTENSION);
$destination_file_name = $imagesMoved . '-'. $sku . '.'. $extension;
$file_path = $images_directory . $destination_file_name;
if (move_uploaded_file($file['tmp_name'], $file_path))
{
$imagesMoved++;
//Move the file to S3
moveFileToS3($destination_file_name, $images_directory, $parent_folder . '/' . $images_folder . '/');
}
if (intval($imagesMoved) == intval($totalFileCount))
{
$image_moved = true;
//Begin to update the DB
}
}
When this call (moveFileToS3) is NOT made.. all the files selected by the user make it to instance "A".
But when this call(moveFileToS3) is made... not all the files selected by the user make it to instance "A" and only a few files from instance "A" get moved to S3 location. Neither set of instructions after $image_moved = true get executed.
Any assistance to get past this situation would be very much appreciated. I have attached the file that has the method "moveFileToS3" for your quick reference.
<?php
require '../api/vendor/autoload.php';
use Aws\Common\Exception\MultipartUploadException;
use Aws\S3\MultipartUploader;
use Aws\S3\S3Client;
function moveFileToS3($fileName, $fileLocation, $targetLocation)
{
date_default_timezone_set('Asia/Kolkata');
$region = 'xxxxx';
$version = 'xxxxx';
$bucket = 'xx-xxxxxx-xxxxx';
$endpoint = 'xxxxxxxx.s3-accelerate.amazonaws.com';
$key = 'xxxxxx';
$secret = 'xxxxxxxxx';
$fileFullPathLocal = $fileLocation.$fileName;
$s3 = new S3Client([
'version' => $version,
'region' => $region,
'debug' => true,
'credentials' => [
'key' => $key,
'secret' => $secret,
]
]);
// Prepare the upload parameters.
$uploader = new MultipartUploader($s3, $fileFullPathLocal, [
'bucket' => $bucket,
'key' => $targetLocation.$fileName
]);
// Perform the upload.
try
{
$responseLogFile = fopen("../log/S3UploadLog_".date("Y-m-d").".log", "a+");
fwrite($responseLogFile, '['.date("Y-m-d H:i:s").']: Upload Started : '.$fileName. PHP_EOL. PHP_EOL);
fclose($responseLogFile);
$result = $uploader->upload();
$responseLogFile = fopen("../log/S3UploadLog_".date("Y-m-d").".log", "a+");
fwrite($responseLogFile, '['.date("Y-m-d H:i:s").']: Upload Finished : '.$fileName. PHP_EOL. PHP_EOL);
// fwrite($responseLogFile, '['.date("Y-m-d H:i:s").']: Upload Result : '.$result. PHP_EOL. PHP_EOL);
fwrite($responseLogFile, '['.date("Y-m-d H:i:s").']: Object Url : '.$result['ObjectURL']. PHP_EOL. PHP_EOL);
fclose($responseLogFile);
// echo "Upload complete: {$result['ObjectURL']}" . PHP_EOL;
unlink($fileFullPathLocal);
}
catch (MultipartUploadException $e)
{
$responseLogFile = fopen("../log/S3UploadLog_".date("Y-m-d").".log", "a+");
fwrite($responseLogFile, '['.date("Y-m-d H:i:s").']: Upload Failed : '.$fileName. PHP_EOL. PHP_EOL);
fclose($responseLogFile);
echo $e->getMessage() . PHP_EOL;
}
}
?>
Seems to issue when you move file from your local dev sever to a bucket.. But when moved to AWS environment.. works without any issues

How to get the AWS S3 bucket location via PHP api call?

I am searching on the internet on how can I get the AWS s3 bucket region with an API call or directly in PHP using their library but have not luck finding the info.
I have the following info available:
Account credentials, bucket name, access key + secret. That is for multiple buckets, that I have access to, and I need to get the region programatically, so logging in to aws console and checking out is not an option.
Assuming you have an instance of the AWS PHP Client in $client, you should be able to find the location with $client->getBucketLocation().
Here is some example code:
<?php
$result = $client->getBucketLocation([
'Bucket' => 'yourBucket',
]);
The result will look like this
[
'LocationConstraint' => 'the-region-of-your-bucket',
]
When you create a S3 client, you can use any of the available regions in AWS, even if it's not one that you use.
$s3Client = new Aws\S3\S3MultiRegionClient([
'version' => 'latest',
'region' => 'us-east-1',
'credentials' => [
'key' => $accessKey,
'secret' => $secretKey,
],
]);
$region = $s3Client->determineBucketRegion($bucketname);

AWS S3 put object (video) with pre-signed URL, Not working?

I am uploading a video on S3 bucket via PHP S3 API with pre-signed URL.
The mp4 video is uploaded successfully to S3, but it's not streaming
and not giving any kind of error.
Here are the details.
My PHP file to create pre-singed url for S3 putObject method.
require 'aws/aws-autoloader.php';
use Aws\S3\S3Client;
use Aws\Exception\AwsException;
$s3Client = new Aws\S3\S3Client([
'version' => 'latest',
'region' => 'ap-south-1',
'credentials' => [
'key' => 'XXXXXXX',
'secret' => 'XXXXXXX'
]
]);
/*echo '<pre>';
print_r($_FILES);die;*/
if(!$_FILES['file']['tmp_name'] || $_FILES['file']['tmp_name']==''){
echo json_encode(array('status'=>'false','message'=>'file path is required!'));die;
}else{
$SourceFile =$_FILES['file']['tmp_name'];
$key=$_FILES['file']['name'];
$size=$_FILES['file']['size'];
}
try {
$cmd = $s3Client->getCommand('putObject', [
'Bucket' => 's3-signed-test',
'Key' => $key,
'SourceFile' => $SourceFile,
'debug' => false,
'ACL' => 'public-read-write',
'ContentType' => 'video/mp4',
'CacheControl'=>'no-cache',
'ContentLength'=>$size
]);
$request = $s3Client->createPresignedRequest($cmd, '+120 minutes');
// Get the actual presigned-url
$presignedUrl = (string) $request->getUri();
} catch (S3Exception $e) {
echo $e->getMessage() . "\n";die;
}
echo json_encode(array('status'=>'true','signedUrl'=>$presignedUrl));die;
This code is working fine and uploading video mp4 on s3 bucket.
But after upload when I am going to access that video, it's not working
I have tried also with getObject pre-singed url but it's not working.
Here are the S3 object URLs-
(1) getObject pre-singed URL
https://s3-signed-test.s3.ap-south-1.amazonaws.com/file.mp4?X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIVUO7AT4W4MCPDIA%2F20180402%2Fap-south-1%2Fs3%2Faws4_request&X-Amz-Date=20180402T112848Z&X-Amz-SignedHeaders=host&X-Amz-Expires=7200&X-Amz-Signature=d6b877f9bba5dd2221381f10017c8659fe42342d81f7af940d8693478679a8fc
(2) S3 Direct object URL-
https://s3.ap-south-1.amazonaws.com/s3-signed-test/file.mp4
My Problem is I am unable to access video which I have uploaded with pre-singed URL on the s3 bucket, bucket permission is public, and accessible for all origins.
Please let me know, someone who have solution for this.

Get s3 metadata without getting object

Is it possible to get just the objects custom metadata from S3 without having to get the whole object? I've looked through the AWS SDK PHP 2 and searched google and SO with no clear answer, or maybe just not the answer I'm hoping for.
Thanks.
Maybe this would help for PHP 2? It uses the Guzzle framework which I'm not familiar with.
Executes a HeadObject command: The HEAD operation retrieves metadata from an object without returning the object itself. This operation is useful if you're only interested in an object's metadata. To use HEAD, you must have READ access to the object.
Final attempt using Guzzle framework (untested code):
use Guzzle\Service\Resource\Model
use Aws\Common\Enum\Region;
use Aws\S3\S3Client;
$client = S3Client::factory(array(
"key" => "YOUR ACCESS KEY ID",
"secret" => "YOUR SECRET ACCESS KEY",
"region" => Region::US_EAST_1,
"scheme" => "http",
));
// HEAD object
$headers = $client->headObject(array(
"Bucket" => "your-bucket",
"Key" => "your-key"
));
print_r($headers->toArray());
PHP 1.6.2 Solution
// Instantiate the class
$s3 = new AmazonS3();
$bucket = 'my-bucket' . strtolower($s3->key);
$response = $s3->get_object_metadata($bucket, 'üpløåd/î\'vé nøw béén üpløådéd.txt');
// Success?
var_dump($response['ContentType']);
var_dump($response['Headers']['content-language']);
var_dump($response['Headers']['x-amz-meta-ice-ice-baby']);
Credit to: http://docs.aws.amazon.com/AWSSDKforPHP/latest/#m=AmazonS3/get_object_metadata
Hope that helps!
AWS HEAD Object http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectHEAD.html
use Aws\S3\S3Client;
use Guzzle\Common\Collection;
$client = S3Client::factory(array(
'key' => 'YOUR-AWS-KEY',
'secret' => 'YOUR-SECRET-KEY'
));
// Use Guzzle's toArray() method.
$result = $client->headObject(['Bucket' => 'YOUR-BUCKET-NAME', 'Key' => 'YOUR-FILE-NAME'])->toArray();
print_r($result['Metadata']);