画像の検証に使用できますgetimagesize()
が、問題は、いたずら好きなユーザーが10 GBのランダムファイルへのリンクを設定すると、本番サーバーの帯域幅が破壊されることです。取得するファイルサイズを制限するにはどうすればよいgetimagesize()
ですか?(例:最大画像サイズ5MB)
PS:私は尋ねる前に調査をしました。
画像の検証に使用できますgetimagesize()
が、問題は、いたずら好きなユーザーが10 GBのランダムファイルへのリンクを設定すると、本番サーバーの帯域幅が破壊されることです。取得するファイルサイズを制限するにはどうすればよいgetimagesize()
ですか?(例:最大画像サイズ5MB)
PS:私は尋ねる前に調査をしました。
ダウンロードしたい最大サイズを課して、ファイルを個別にダウンロードできます。
function mygetimagesize($url, $max_size = -1)
{
// create temporary file to store data from $url
if (false === ($tmpfname = tempnam(sys_get_temp_dir(), uniqid('mgis')))) {
return false;
}
// open input and output
if (false === ($in = fopen($url, 'rb')) || false === ($out = fopen($tmpfname, 'wb'))) {
unlink($tmpfname);
return false;
}
// copy at most $max_size bytes
stream_copy_to_stream($in, $out, $max_size);
// close input and output file
fclose($in); fclose($out);
// retrieve image information
$info = getimagesize($tmpfname);
// get rid of temporary file
unlink($tmpfname);
return $info;
}
getimagesize('http://example.com')
一度画像をダウンロードして、サイズを確認してから、ダウンロードした画像データを破棄することになるので、そもそもやりたくないですよね。それは帯域幅の本当の無駄です。
そのため、ダウンロードプロセスと画像サイズのチェックを分けてください。たとえばfopen
、画像の URL を開き、少しずつ読み取って一時ファイルに書き込み、読み取った量をカウントするために使用します。5MB を超えても読み取りが完了していない場合は、画像を停止して拒否します。
実際のダウンロードを開始する前にHTTP Content-Size ヘッダーを読み取って、明らかに大きなファイルを取り除くことができますが、スプーフィングまたは省略される可能性があるため、信頼することはできません。
例を次に示します。要件に合わせて変更を加える必要があります。
function getimagesize_limit($url, $limit)
{
global $phpbb_root_path;
$tmpfilename = tempnam($phpbb_root_path . 'store/', unique_id() . '-');
$fp = fopen($url, 'r');
if (!$fp) return false;
$tmpfile = fopen($tmpfilename, 'w');
$size = 0;
while (!feof($fp) && $size<$limit)
{
$content = fread($fp, 8192);
$size += 8192; fwrite($tmpfile, $content);
}
fclose($fp);
fclose($tmpfile);
$is = getimagesize($tmpfilename);
unlink($tmpfilename);
return $is;
}