PHPで、s3ファイルをサーバーに保存せずにブラウザにダウンロードしたいです
質問
Amazon の S3 にファイルがあります。これらには一意の ID が付けられているため、重複はありません。許可された URL を使用してアクセスしています。それらをブラウザに渡すことができる必要がありますが、名前を変更する必要があります。現在、fopen を使用していますが、ファイルをブラウザーに提供する前にサーバーにファイルをダウンロードしています。ファイルをサーバー経由でブラウザに「パススルー」するにはどうすればよいですか?または、ダウンロードをバッファリングするにはどうすればよいですか?小さなチャンクをサーバーにダウンロードし、次のチャンクをダウンロードするときにそれをブラウザーに渡しますか?
また、CloudFront を使用したいのですが、認証された URL が提供されていません。CURL を使用してリクエストの資格情報を送信できると思いますが、CURL を使用してこの種の「パススルー」ファイルを提供することはできますか?
ありがとう!
解決
S3 の仕組みに詳しくないので、この解決策が可能かどうかはわかりません。しかし、単純にユーザーのブラウザをファイルにリダイレクトすることはできないでしょうか?私の理解が正しければ、S3 ではバケット内の任意のファイルの Web URL を作成できます。したがって、たとえば、これらが有料ダウンロードである場合、次のようにすることができます。 S3 にそのダウンロード用の一時 URL を生成させる ユーザーがダウンロードしたら削除します。
それができない場合は、次の PHP クラスを試してみてください。
- HTTPプロトコルクライアント - HTTP リソースへのリクエストを実装するクラス (以下のストリーム ラッパーによって使用されます)。リクエストのストリーミングを許可します。
- HTTP - HTTP ストリーム ラッパー。次のような関数を使用して、リモート HTTP リソースをファイルとして扱うことができます。
fopen()
,fread()
, 、など。 - Amazon S3 ストリーム ラッパー - 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;
次に、ユーザーを次のようにリダイレクトします。 $url
, 、ファイルをダウンロードできるはずです。署名は一方向暗号化スキーム (sha1) でエンコードされるため、AWS シークレット アクセス キーが漏洩するリスクはありません。
他のヒント
あなたはhttpauthとhttpauthtypeを指定するrequest_optionsで、HTTP_GETを使用してみましたか?この方法がうまくバイナリのために動作しない可能性があります文字列の有効なタイプを、前提としていた場合、私は覚えていませんが。
それが成功した場合、あなたは正しいMIMEタイプを提供し、ブラウザに書き出すことができる必要があります。
あなただけ( " HTTPのReadFileを使用してBUを試してみました。 EXT の ")?
それはちょうどバイパスし、コンテンツタイプが懸念される場合は、しかし、あなたはその最初を確認する必要があり、出力バッファに直接書き込みます。
また、ReadFile関数の引数としてURLエン使用すると、PHPはurlwrapper-サポート付きでコンパイルされている必要があります。