为了账号安全,请及时绑定邮箱和手机立即绑定

为什么在使用 HTTP Accept-Ranges 提供大文件时未满足 PHP

为什么在使用 HTTP Accept-Ranges 提供大文件时未满足 PHP

PHP
拉丁的传说 2024-01-19 10:07:42
以下脚本用于(评估)向客户端发送大型视频文件。它在后面使用http headers Accept-Ranges。即使在处理大文件(> 2 GB)时,也不会满足 PHP 限制(为了测试,我设置了较小的值,例如 memory_limit=16MB 和 max_execution_time=30)。我想“理解”后面的上下文,因为 chrome 仅显示一个(部分)请求,每隔几秒增加“时间”和“大小”,尽管 apache 日志文件中没有显示其他请求。$file = './videos/' . basename($_GET['video']);if(!file_exists($file)) return; $fp = @fopen($file, 'rb');      $size   = filesize($file); // File size $length = $size;           // Content length$start  = 0;               // Start byte$end    = $size - 1;       // End byte  header('Content-type: video/mp4');header("Accept-Ranges: 0-$length");header("Accept-Ranges: bytes"); if (isset($_SERVER['HTTP_RANGE'])) {    $c_start = $start;                  $c_end   = $end;                    list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2);    if (strpos($range, ',') !== false) {        header('HTTP/1.1 416 Requested Range Not Satisfiable');        header("Content-Range: bytes $start-$end/$size");        exit;          }                  if ($range == '-') {                    $c_start = $size - substr($range, 1);    }else{                 $range  = explode('-', $range);         $c_start = $range[0];                   $c_end   = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $size;    }    $c_end = ($c_end > $end) ? $end : $c_end;    if ($c_start > $c_end || $c_start > $size - 1 || $c_end >= $size) {         header('HTTP/1.1 416 Requested Range Not Satisfiable');        header("Content-Range: bytes $start-$end/$size");        exit;          }    $start  = $c_start;                 $end    = $c_end;                   $length = $end - $start + 1;        fseek($fp, $start);                 header('HTTP/1.1 206 Partial Content');}   
查看完整描述

1 回答

?
素胚勾勒不出你

TA贡献1827条经验 获得超9个赞

curl通过在不使用任何范围标头的情况下通过命令行请求脚本,同时拥有max_execution_time=1并提供 2.893 GB 文件,找出了更多详细信息。


在同一台机器上(在 7 秒和 678 MB 处中止):


% Total    % Received % Xferd  Average Speed   Time    Time     Time  Current

                                 Dload  Upload   Total   Spent    Left  Speed  

23 2893M   23  678M    0     0  92.5M      0  0:00:31  0:00:07  0:00:24     0 

curl: (18) transfer closed with 2322893144 bytes remaining to read

在带宽较低的外国机器上(在 49 秒和 599 MB 处中止):


% Total    % Received % Xferd  Average Speed   Time    Time     Time  Current

                                 Dload  Upload   Total   Spent    Left  Speed  

20 2893M   20  599M    0     0  12.1M      0  0:03:58  0:00:49  0:03:09 10284 

curl: (18) transfer closed with 2404747608 bytes remaining to read

就此而言,amax_execution_time=30在这种情况下并不是真正的“小”,因为它允许传输估计约 30 * 600 MB(= 18 GB!)。客户端的请求持续时间与服务器端的执行时间完全无关。


事实上,当从 html5 视频对象中调用脚本时,会完成多个部分请求max_execution_time=1(在带宽更低的桌面客户端上,每个请求大约需要 14 分钟,直到中止并传输大约 500 MB)。


最后,我很困惑,因为客户端请求持续时间和服务器端执行时间之间存在巨大差异。


查看完整回答
反对 回复 2024-01-19
  • 1 回答
  • 0 关注
  • 89 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信