我将私人文件存储在服务器上(Centos / Apache / PHP),授权用户可以使用webbrowser下载(确定用户是否被授权在其他地方,并且不是问题的一部分)。
我使用以下脚本下载文件。它适用于小文件,但是当文件很大(约80MB)时它不起作用。对于这些,下载的文件是零字节,Adobe表示它是非支持类型或由于未编码的电子邮件而损坏。我已经确认服务器上的文件没问题,所以问题不是由我的上传脚本引起的。
什么可能导致此问题以及如何解决?
另外,有更好的方法来限制下载文件吗?我担心的可能是我的上述方法在服务器/ PHP上放置了过多的工作。在目录上放置Apache密码并要求用户输入它不是一个可行的解决方案。不知道是否存在其他东西,但我想我会问。
谢谢
/* Given: $file='/var/www/private/filename'
$file_name='xx.pdf'
*/
public function dl_file($file,$file_name)
{
//First, see if the file exists
if (!is_file($file)) { die('Document does not exist'); }
//All this function does is get the appropriate mime type
$fileInfo=library::getFileInfo(library::getExt($file_name));
syslog(LOG_INFO,'Content-Type: '.$fileInfo['mime'].' Content-Disposition: attachment; filename="'.$file_name.'" Content-Length: '.filesize($file));
//Begin writing headers
header('Pragma: public');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Cache-Control: public');
header('Content-Description: File Transfer');
//Use the switch-generated Content-Type
header('Content-Type: '.$fileInfo['mime']);
//Force the download
header('Content-Disposition: attachment; filename="'.$file_name.'"' );
header('Content-Transfer-Encoding: binary');
header('Content-Length: '.filesize($file));
readfile($file);
}
从syslog上面输出:
Jun 1 09:24:15 devserver httpd: Content-Type: application/pdf Content-Disposition: attachment; filename="xx.pdf" Content-Length: 86396350
答案 0 :(得分:0)
我没有得到答案为什么大文件下载为零大小,但也许我有一个很大的灵感来自https://stackoverflow.com/a/4126882/1032531的替代方案。
首先,我将在公共HTML空间中创建一个名为" private"的目录。
我会在我的页面中放置HTML链接,该链接表示要下载的文件,指向可公开访问的PHP文件,并在URL中包含文件名。
访问后,我将删除私人目录中超过1秒的所有文件。
然后,我将获取文件名并验证用户是否有权下载该文件。
如果获得授权,我将创建一个位于私人目录中的符号链接,该链接指向相关文件,并将其重定向到该符号链接。
似乎合理吗?
我的方法存在一个缺陷,即文件可以在私人目录中公开访问。我可以使用随机名称,但是,我希望使用真实名称下载文件以供授权用户使用。有什么建议吗?
答案 1 :(得分:0)
我认为有三个原因:
您的脚本超出了执行的最长时间
intenet的速度,也是下载文件的人 慢。所以你的脚本将超过它的最大持续时间 执行,只要用户尚未完成下载 文件
服务器速度很慢,在这种情况下没什么大不了的
解决您的问题 尝试使用函数:set_time_limit()
**`set_time_limit (int $ seconds ) ;`**
例如set_limit_time尝试(120); 将允许用户下载文件少于120秒
您必须计算下载文件所需的时间,相对于客户的互联网速度以及服务器的速度 添加脚本需要执行的时间
这将是你必须给set_limit_time()函数
的时间我希望这有帮助
此处有更多信息:http://www.php.net/manual/en/function.set-time-limit.php
为了更安全,请使用mod_xsendfile,这是一个apache模块
mod_xsendfile是一个小型Apache2模块,用于处理原始输出处理程序注册的X-SENDFILE标头。
如果它遇到这样的头部,它将丢弃所有输出并发送该头部指定的文件,而不是使用Apache内部,包括所有优化,如缓存头和sendfile或mmap(如果已配置)。
对于处理例如脚本输出很有用。 php,perl或任何cgi。
有用?
是的,这很有用。
Some applications require checking for special privileges.
Other have to lookup values first (e.g.. from a DB) in order to correctly process a download request.
Or store values (download-counters come into mind).
etc.
优势
Uses apache internals
Optimal delivery through sendfile and mmap (if available).
Sets correct cache headers such as Etag and If-Modified-Since as if the file was statically served.
Processes cache headers such as If-None-Match or If-Modified-Since.
Support for ranges.