2009-04-21 46 views
5

我已經在亞馬遜的S3上有文件。它們以唯一的ID命名,因此沒有重複。我正在使用授權的URL訪問它們。我需要能夠將它們傳遞給瀏覽器,但我需要重命名它們。現在我正在使用fopen,但是它在將文件提供給瀏覽器之前將文件下載到我的服務器。我如何讓文件'通過'我的服務器到瀏覽器?或者如何緩衝下載 - 下載一個小塊到我的服務器並在下載下一個塊時將其傳遞給瀏覽器?在PHP中,我想下載一個s3文件到瀏覽器,而不將它存儲在我的服務器上

另外 - 我真的想使用CloudFront,但他們不提供經過身份驗證的URL。我相信我可以使用CURL爲請求發送證書 - 我可以使用CURL做這種「通過」文件服務嗎?

謝謝!

回答

5

我不熟悉S3的工作原理,所以我不知道這個解決方案是否可行。但是,你不能簡單地將用戶的瀏覽器重定向到文件嗎?如果我理解正確,S3允許您爲存儲桶中的任何文件創建網址。因此,如果這些付費下載,那麼你可以have S3 generate a temporary URL for that download,然後刪除,一旦用戶下載它。

如果這不是一個選項,你可以嘗試這些PHP類:

  • HTTP protocol client - 實現請求HTTP資源類(由下面流包裝使用)。允許請求流式傳輸。
  • gHttp - 一個HTTP流的包裝,讓你能夠將遠程HTTP資源文件,使用像fopen()fread()功能等
  • Amazon S3 Stream Wrapper - 由相同的顯影劑gHttp的亞馬遜S3流包裝。還允許通過fopen('s3://...')像普通文件一樣訪問遠程資源。

編輯:

This page對信息如何「預先驗證」通過編碼在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; 

然後,只需將用戶重定向到$url,他們應該能夠下載該文件。簽名由單向加密方案(sha1)編碼,因此您的AWS祕密訪問密鑰沒有被發現的風險。

+0

我擔心重定向的一個問題是您需要驗證您的安全性沒有被傳遞。如果重定向需要授權,則您將此授予客戶端。 – Joe 2009-04-21 14:16:09

1

您是否嘗試過使用http_get和request_options來指定httpauth和httpauthtype?雖然我不記得這種方法是否採用了字符串有效類型,這對於二進制文件可能無效。

如果這是成功的,那麼你應該能夠提供正確的MIME類型並寫出到瀏覽器。

+0

謝謝喬。我會研究它。 – Corey 2009-04-21 13:38:09

0

您是否嘗試過使用readfile(「http://username:[email protected]/filename.ext」)?

這將只是繞過並直接寫入outputbuffer,但是如果內容類型是值得關注的,則需要首先驗證。

使用en URL作爲readfile的參數也要求使用urlwrapper-support編譯PHP。

相關問題