I'm not familiar with how S3 works, so I don't know if this solution is possible. But couldn't you simply redirect the user's browser to the file? If I understand correctly, S3 allows you to create web URLs for any of the files in your bucket. So if, say, these are paid downloads, then you could have S3 generate a temporary URL for that download and then remove that once the user has downloaded it.
If that is not an option, you can try these PHP Classes:
- HTTP protocol client - A class that implements requests to HTTP resources (used by the below stream wrapper). Allows requests to be streamed.
- gHttp - An HTTP stream wrapper that lets you treat remote HTTP resources as files, using functions like
fopen()
, fread()
, etc.
- Amazon S3 Stream Wrapper - An Amazon S3 stream wrapper by the same developer as gHttp. Also allows remote resources to be accessed like ordinary files via
fopen('s3://...')
.
Edit:
This page has the info on how to "pre-authenticate" a request by encoding the authentication key in the URL. It's under the section titled: Query String Request Authentication Alternative.
// I'm only implementing the parts required for GET requests.
// POST uploads will require additional components.
function getStringToSign($req, $expires, $uri) {
return "$req\n\n\n$expires\n$uri";
}
function encodeSignature($sig, $key) {
$sig = utf8_encode($sig);
$sig = hash_hmac('sha1', $sig, $key);
$sig = base64_encode($sig);
return urlencode($sig);
}
$expires = strtotime('+1 hour');
$stringToSign = getStringToSign('GET', $expires, $uri);
$signature = encodeSignature($stringToSign, $awsKey);
$url .= '?AWSAccessKeyId='.$awsKeyId
.'&Expires='.$expires
.'&Signature='.$signature;
Then just redirect the user to $url
, and they should be able to download the file. The signature is encoded by a one-way encryption scheme (sha1), so there's no risk of your AWS Secret Access Key being uncovered.