views:

136

answers:

3

I created a simple file browser in PHP that links to the files through generation expiring query URLs. So for each access to a directory, a link to each file is generated that is valid for say 900 seconds.

I now have the problem that the generated signatures seem to fail sometimes. Which is strange, since I intentionally used external S3 libraries for generating the URLs and signatures.

In fact, I tried the following libraries to generate the signatures:

The libraries internally use hash_hmac('sha256', ... or hash_hmac('sha1', ... - I also don't understand why differnet hash algorithms are used.

Since the problem is the same with all libraries, it could as well be in my URL generation code, which is straightforward though:

$bucket = "myBucket";
$filename = $object->Key;
$linksValidForSeconds = 900;
$url = $s3->get_object_url($bucket, $filename, $linksValidForSeconds);

Sp $bucket and $linksValidForSeconds are constant, $filename is e.g. "Media/Pictures/My Picture.png". But event for same variables, it sometimes works, soemtimes doesn't.

Any ideas?

Edit: Typo/Wrong constant variable name fixed (thanks)

A: 

The code the asker is using above is from the CloudFusion AWS PHP SDK. Here's the documentation for get_object_url(): get_object_url ( $bucket, $filename, [ $preauth = 0 ], [ $opt = null ] )

The problem in your code above is your $linksValidForSeconds variable.

Where: $preauth - integer | string (Optional) Specifies that a presigned URL for this request should be returned. May be passed as a number of seconds since UNIX Epoch, or any string compatible with strtotime().

In other words, you are setting an expires time for 900 seconds after UNIX Epoch. I am honestly not sure how any links have worked using that library with your client code. If you are using the CloudFusion SDK, what you want to do is take the current UNIX time and add 900 seconds to that when passing in the parameter.

You seem to be confusing this with the Amazon S3 Class' getAuthenticatedURL method which takes the parameter integer $lifetime in seconds as you've used in your client code.

Be careful when using multiple libraries and swapping between them freely. Things tend to break that way.

Josh Smith
Apparently, CloudFusion released a new version only two days ago. The previous signature was: function get_object_url($bucket, $filename, $qsa = 0, $torrent = false). So $qsa is in fact a number of seconds in the library I am using. I will migrate to the new SDK and check if the problem consists..
Tarnschaf
Sounds good. And thanks for updating and letting us know what happened. But man, did I work hard for that bounty. ;)
Josh Smith
Yeah, thank you very much. I'm afraid I posted too few code samples for you to be able to solve it..
Tarnschaf
@Tarnschaf True enough, though your bounty expires no matter what. Might as well award it to someone who took the time to answer.
Josh Smith
Ok, sorry I didn't know. You've deserved it :)
Tarnschaf
I figured, which is why I mentioned. And thanks! I appreciate it. Keeps people motivated to keep on giving.
Josh Smith
+1  A: 

I found the problem and it had nothing to do with the code I mentioned. The generated URL is urlencode()'d and sent to another PHP script. There I use the URL to display an image from S3. I used urldecode() there to undo the changes but apparently this is not neccesary.

So each time the signature contains certain chars, the urldecode() would change them and corrupt it.

Sorry for omitting the actual problem code.

Tarnschaf
A: 

The current version of CloudFusion is the AWS SDK for PHP, plus some other stuff. Amazon forked CloudFusion as the basis for their PHP SDK, then when the official SDK went live, CloudFusion backported the changes.

It's kind of a KHTML/WebKit thing. http://en.wikipedia.org/wiki/WebKit#History

Ryan Parman