在php中,我想将s3文件下载到浏览器而不将其存储在我的服务器上

Cor*_*rey 5 php fopen download amazon-s3 buffering

我在亚马逊的S3上有文件.它们以唯一ID命名,因此没有重复项.我正在使用授权的URL访问它们.我需要能够将它们传递给浏览器,但我需要重命名它们.现在我正在使用fopen,但它在将文件提供给浏览器之前将文件下载到我的服务器.如何让文件"通过"我的服务器传递到浏览器?或者我如何缓冲下载 - 将一小块下载到我的服务器并在下载下一个块时将其传递给浏览器?

此外 - 我真的想使用CloudFront,但他们不提供经过身份验证的URL.我相信我可以使用CURL发送请求的凭据 - 我可以使用CURL执行此类"传递"文件服务吗?

谢谢!

Cal*_*vin 5

我不熟悉S3的工作原理,所以我不知道这个解决方案是否可行.但是,您不能简单地将用户的浏览器重定向到该文件吗?如果我理解正确,S3允许您为存储桶中的任何文件创建Web URL.因此,如果这些是付费下载,那么您可以让S3为该下载生成临时URL,然后在用户下载后删除它.

如果这不是一个选项,您可以尝试这些PHP类:

  • HTTP协议客户端 - 实现对HTTP资源的请求的类(由下面的流包装器使用).允许流式传输请求.
  • gHttp -一个HTTP流的包装,让你能够将远程HTTP资源文件,使用类似的功能fopen(),fread()等等.
  • Amazon S3 Stream Wrapper - 由与gHttp相同的开发人员创建的Amazon S3流包装器.还允许通过普通文件访问远程资源fopen('s3://...').

编辑:

此页面包含有关如何通过对URL中的身份验证密钥进行编码来"预先验证"请求的信息.它位于标题为" 查询字符串请求身份验证替代 "的部分下.

// 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;
Run Code Online (Sandbox Code Playgroud)

然后只需将用户重定向到$url,他们应该能够下载该文件.签名由单向加密方案(sha1)编码,因此不存在发现AWS Secret Access Key的风险.