【发布时间】:2016-10-19 18:49:29
【问题描述】:
我想从其他网站/网址直接向用户发送/流式传输文件,而不将文件存储在我的服务器上。文件是大约 100MB 到 1GB 的档案
单线程下载工作正常。这是我的代码:
$ch5 = curl_init();
if (isset($_SERVER['HTTP_RANGE'])) {
//http://stackoverflow.com/questions/157318/resumable-downloads-when-using-php-to-send-the-file
preg_match('/bytes=(\d+)-(\d+)?/', $_SERVER['HTTP_RANGE'], $matches);
$offset = intval($matches[1]);
$end = $matches[2] || $matches[2] === '0' ? intval($matches[2]) : $size - 1;
curl_setopt($ch5, CURLOPT_RANGE, "$offset-$end");
}
curl_setopt($ch5, CURLOPT_URL, $direct_link);
curl_setopt($ch5, CURLOPT_TIMEOUT, 3550);
curl_setopt($ch5, CURLOPT_CONNECTTIMEOUT, 15);
curl_setopt($ch5, CURLOPT_HEADERFUNCTION, 'readHeader');
curl_exec($ch5);
$dlsize = curl_getinfo($ch5,CURLINFO_SIZE_DOWNLOAD );
$time = curl_getinfo($ch5,CURLINFO_TOTAL_TIME);
curl_close($ch5);
function readHeader($ch, $header) // Send header from the Downloaded file to the User
{
header($header);
return strlen($header);
}
问题在于,如果请求包含像“Range: bytes=0-”这样的范围,PHP 会下载完整的文件并将其发送给用户。但是用户下载速度要慢得多(导致下载速度较慢)然后将其下载到我的服务器,但是如果文件完全下载,则该文件在外部服务器上不可用。 当客户端对下半部分发出范围请求或其他请求时,请求会发送到外部服务器并且文件不可用,因为第一个请求已经完全下载了它,但我无法访问数据或存在一种获取这些数据的方法,而不将它们保存在我的磁盘上?
我想节省带宽并希望让用户能够进行范围请求。 所以 PHP 应该只下载用户真正想要下载的量或在外部服务器和用户之间建立直接连接。
其实我在 Ubuntu 12.04.5 上使用的是 nginx/1.6.2 和 PHP 5.5.20-1
【问题讨论】:
-
PHP 不是您想要使用的。研究使用 Squid squid-cache.org
-
问题是,用户不应该看到原始 URL,我需要 PHP 来存储下载的大小,因为每个用户都有一个有限的下载队伍。或者是否有可能在 PHP 中使用 Squid
-
Squid 有这些功能。
-
我通过使用带有 X-Sendfile 的 nginx 解决了我的问题。更多信息在这里:wiki.nginx.org/XSendfile