Okay, this one took me hours to figure out, so I figured I would put my results here for others to find. Hopefully it will spare others the hours of frustration I went through!
If you do not know what Amazon AWS S3 is, you should read up on it. Basically, it's super-cheap online file storage for your web site or even personal use. You can even make it so that files are private, and can only be downloaded with a self-expiring URL (which might only be valid for, say, 1 hour).
Here is how, in PHP, to do just that. Please note, these code snippits were pieced together from various sources online until I finally got everything working the way it is supposed to.
First things first, you will need these functions:
function gs_getStringToSign($request_type, $expires, $uri) {
return "$request_type\n\n\n$expires\n$uri";
}
function gs_encodeSignature($s, $key) {
$s = utf8_encode($s);
$s = hash_hmac('sha1', $s, $key, true);
$s = base64_encode($s);
return urlencode($s);
}
function gs_prepareS3URL($file, $bucket) {
$awsKeyId = "PUT ACCESS ID HERE"; // this is the non-secret key ID.
$awsSecretKey = "PUT SECRET KEY HERE"; // this is the SECRET access key!
$file = rawurlencode($file);
$file = str_replace('%2F', '/', $file);
$path = $bucket .'/'. $file;
$expires = strtotime('+1 hour');
$stringToSign = gs_getStringToSign('GET', $expires, "/$path");
$signature = gs_encodeSignature($stringToSign, $awsSecretKey);
$url = "http://$bucket.s3.amazonaws.com/$file";
$url .= '?AWSAccessKeyId='.$awsKeyId
.'&Expires='.$expires
.'&Signature='.$signature;
return $url;
}
Next, all you have to do is call the gs_prepareS3URL function like so:
$file = "WordHunt.jar"; $bucket = "bytebyte.net"; $secure_link = gs_prepareS3URL($file, $bucket);
Isn't that easy? Just make sure you have set the ACL's on the file in question to not be readable by anyone but you (otherwise you wouldn't need these functions at all, and you could just download the file directly).
Fine print: This code is considered "open source," and is released under the GNU Public License version 3 or any later version (http://www.gnu.org/copyleft/gpl.html). In a nut shell, you can change this code however you want, and redistribute it, but ONLY if it is ALSO under the GNU Public License version 3 or later. If you do use this software, I would appreciate credit and a link back to this site, though this is not required.
Trouble with .flv
I'm trying to apply this to media files (.flv) I have on my S3 bucket. It works, however the link does not provide a download, instead showing a text file. Any idea on why that is? Any help would be greatly appreciated!
It shows a text file? What
It shows a text file? What does it say?
Works like a charm. Many
Works like a charm. Many thanks from France.
Anyone have more code?
I know enough about PHP to be dangerous in editing scripts, but now very fluent in PHP yet.
I assume if I use the large code as whatever.PHP in the same directory as the .HTML file and use a PHP call at the top of the HTML - should it work? Is that the setup needed?
(Or, does anyone have anymore code?)
Thanks,
Dave
Well, it depends on how your
<?php
include_once("aws_functions.php");
?>
<html>
<body>
Hey everyone! Download my file:
<?php
$file = "myfile.zip";
$bucket = "my-bucket";
$secure_link = gs_prepareS3URL($file, $bucket);
// Output the link to the page:
print '<a href="' . $secure_link . '">Click here!</a>';
?>
</body>
</html>
Thank you so much for sharing
Thank you so much for sharing this. I find the AWS documentation quite convoluted, and I simply could not make sense of what needed to be done.
I'm going to wrap your functions in a class and share back with you when I'm done :)
Awesome-- I'm glad this post
Awesome-- I'm glad this post helped you!
Richard
Great post, really appreciate
Great post, really appreciate it. The Amazon AWS docs are so confusing sometimes.
Great Post
I've been wrestling with the Amazon S3 SDK for hours. It was adding an extra character at the end of the string which was causing the signature to fail. Your solution resolved the issue. Thank you very much.
Glad I could help!
Glad I could help!