5

I've got files on Amazon's S3. They are named with a unique ID so there are no duplicates. I am accessing them using an authorized URL. I need to be able to pass them through to the browser, but I need to rename them. Right now I'm using fopen, but it is downloading the file to my server before serving the file to the browser. How can I have the files 'pass through' my server to the browser? Or how do I buffer the download - downloading a small chunk to my server and pass that to the browser while downloading the next chunk?

Also - I would really like to use CloudFront but they don't offer authenticated URLs. I believe I can use CURL to send credentials for the request - can I do this sort of 'pass through' file serving with CURL?

Thanks!

4

3 回答 3

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 中编码身份验证密钥来“预身份验证”请求的信息。它位于标题为: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;

然后只需将用户重定向到$url,他们应该能够下载文件。签名由单向加密方案 (sha1) 编码,因此您的 AWS 秘密访问密钥不存在被泄露的风险。

于 2009-04-21T14:07:58.627 回答
1

您是否尝试过使用 http_get 和 request_options 来指定 httpauth 和 httpauthtype?尽管我不记得此方法是否假定字符串有效类型,但这可能不适用于二进制文件。

如果成功,那么您应该能够提供正确的 MIME 类型并写入浏览器。

于 2009-04-21T13:24:27.793 回答
0

您是否尝试过仅使用 readfile(" http://username:password@host/filename.ext ") ?

这只会绕过并直接写入输出缓冲区,但是如果您需要关注内容类型,则需要先验证这一点。

使用 en URL 作为 readfile 的参数还需要使用 urlwrapper-support 编译 PHP。

于 2009-04-22T16:28:58.730 回答