PHP代理下载文件

问题描述 投票:2回答:4

我觉得这很简单。

我有一个简单的网站,有一个保留区域和一些可以从中下载的文件。

我用.htaccess禁用了直接文件下载,我通过这个简单的proxy.php文件管理文件下载:

// ....

if ($filename === null || !file_exists($proxiedDirectory.$filename)) {
    http_response_code(404);
    exit;
}

if (!$site->is_logged_in()) { 
    http_response_code(403);
    exit;
}

$fp = fopen($proxiedDirectory.$filename, 'rb');

header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.$filename.'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($filename));
fpassthru($fp);
exit;

这段代码完美无缺,但不幸的是我有一个用户可以下载的1.2Gb文件,这个脚本太慢了,不允许完整的文件下载。

任何帮助,将不胜感激,

提前致谢!

M.

php proxy download-manager source-code-protection
4个回答
1
投票

你可以使用header()set_time_limit()fgets()ob_flush()flush()的组合。这是我的例子,最好在OS 64bit上使用Php 64bit,因为filesize()在这个架构中没有限制。

    // Set force download headers
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename="' . $file . '"');
    header('Content-Transfer-Encoding: binary');
    header('Connection: Keep-Alive');
    header('Expires: 0');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');
    header('Content-Length: ' . sprintf("%u", filesize($downloads_folder . $file)));
    // Open and output file contents
    set_time_limit(0);
    $fh = fopen($downloads_folder . $file, "rb");
    while (!feof($fh)) {
      echo fgets($fh);
      ob_flush();
      flush();
    }
    fclose($fh);
    exit;

希望这可以帮助。


0
投票

使用chunked download,像这样:

$chunkSize = 1024 * 1024;
while (!feof($fp))
{
    $buffer = fread($fp, $chunkSize);
    echo $buffer;
    ob_flush();
    flush();
}

0
投票

使用nginx作为代理可能更合适。原因很简单:当你通过php下载时,在php-fpm请求时会有超时,因此文件更有可能无法下载完成。

location /proxy.lua {
    proxy_pass http://proxy.com/link/;
} 

如果你需要检查用户是否登录,你可以使用lua + nginx(OpenResty)

但有一种简单的方法可以检查:1。proxy.php将请求重定向到nginx位置proxy.lua,其中包含两个参数:ts和code。

ts is timestamp of server
code is md5sum(ts+"complexstring")
header("Location: /proxy.lua?ts=122&code=xxx&filename=xxxx", 302);
exit(0);

在卢阿时:

parse the parameter ts and code, validate the code and ts value
proxy the file

0
投票

ob_end_clean()之前使用fpassthru($fp)

EG

ob_end_clean();
fpassthru($fp);

这可能适用于大文件

© www.soinside.com 2019 - 2024. All rights reserved.