在PHP中解析HTTP_RANGE标头

时间:2010-02-05 17:52:06

标签: php apache http range http-headers

是否存在在PHP中正确解析HTTP_RANGE标头的方法?我想在重新发明轮子之前我会问这里。

我目前正在使用

preg_match('/bytes=(\d+)-(\d+)/', $_SERVER['HTTP_RANGE'], $matches);

解析标题但是没有涵盖标题的所有可能值,所以我想知道是否有可以执行此操作的函数或库?

提前致谢。

3 个答案:

答案 0 :(得分:10)

而是在发送416之前使用正则表达式测试。然后通过在逗号,和连字符-上展开来解析它。我还看到你在你的正则表达式中使用了\d+,但实际上这些不是。当省略任何一个范围索引时,它只是意味着“第一个字节”或“最后一个字节”。你应该在你的正则表达式中覆盖它。另请参阅Range header in the HTTP spec您应该如何处理它。

开球示例:

if (isset($_SERVER['HTTP_RANGE'])) {
    if (!preg_match('^bytes=\d*-\d*(,\d*-\d*)*$', $_SERVER['HTTP_RANGE'])) {
        header('HTTP/1.1 416 Requested Range Not Satisfiable');
        header('Content-Range: bytes */' . filelength); // Required in 416.
        exit;
    }

    $ranges = explode(',', substr($_SERVER['HTTP_RANGE'], 6));
    foreach ($ranges as $range) {
        $parts = explode('-', $range);
        $start = $parts[0]; // If this is empty, this should be 0.
        $end = $parts[1]; // If this is empty or greater than than filelength - 1, this should be filelength - 1.

        if ($start > $end) {
            header('HTTP/1.1 416 Requested Range Not Satisfiable');
            header('Content-Range: bytes */' . filelength); // Required in 416.
            exit;
        }

        // ...
    }
}

编辑:$ start必须始终小于$ end

答案 1 :(得分:2)

取自PEAR Package HTTP_Download

function getRanges()
{
    return preg_match('/^bytes=((\d*-\d*,? ?)+)$/', @$_SERVER['HTTP_RANGE'], $matches) ? $matches[1] : array();
}

this packages用于此类内容也是一个好主意!

答案 2 :(得分:1)

fread()页面上有一个实现HTTP范围支持的代码段:

http://www.php.net/manual/en/function.fread.php#84115