【问题标题】:getimagesize() limiting file size for remote URLgetimagesize() 限制远程 URL 的文件大小
【发布时间】:2012-09-03 14:46:35
【问题描述】:

我可以使用getimagesize() 来验证图像,但问题是如果淘气的用户将链接指向10GB random file,那么它会破坏我的生产服务器的带宽。如何限制getimagesize() 获取的文件大小? (例如,最大图像大小为 5MB)

PS:问之前我已经research了。

【问题讨论】:

标签: php validation getimagesize


【解决方案1】:

您可以单独下载文件,设置您希望下载的最大大小:

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;
}

【讨论】:

  • 嗨,如果我有大约 100 个用户同时上传,stream_copy_to_stream 不会有内存问题吗?
  • @Severus 你会怎么想?我相信它在内部使用 8K 缓冲区来执行复制。
  • @Severus 你能更具体一点吗? :)
  • 那么当达到限制时我将如何抛出异常?
  • @Severus stream_copy_to_stream() 返回复制的字节,以便您检查数字是否等于 $max_size
【解决方案2】:

您不想一开始就执行getimagesize('http://example.com') 之类的操作,因为这将下载图像一次,检查大小,然后丢弃下载的图像数据。 那是真正的带宽浪费。

因此,将下载过程与检查图像大小分开。例如,使用fopen打开图片URL,一点一点地读取,写入一个临时文件,记录你读了多少。一旦超过 5MB 仍未完成阅读,您将停止并拒绝该图像。

可以在开始实际下载之前尝试读取 HTTP Content-Size 标头以清除明显较大的文件,但您不能依赖它,因为它可以被欺骗或省略。

【讨论】:

    【解决方案3】:

    这是example,您需要进行一些更改以满足您的要求。

    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;
    }
    

    【讨论】:

    • 请问为什么要加8192
    • @Severus 就是读8kb的意思,没有特别的意思。
    • 实现了phpbb的哪个文件?
    猜你喜欢
    • 2011-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-09
    • 1970-01-01
    • 2023-03-28
    相关资源
    最近更新 更多