Разбор заголовка HTTP_RANGE в PHP - PullRequest
8 голосов
/ 05 февраля 2010

Существует ли способ правильного анализа заголовка HTTP_RANGE в PHP? Думаю, я бы спросил здесь, прежде чем изобретать колесо.

Я сейчас использую

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

для анализа заголовка, но это не охватывает все возможные значения заголовка, поэтому мне интересно, есть ли функция или библиотека, которая может сделать это уже?

Заранее спасибо.

Ответы [ 3 ]

10 голосов
/ 06 февраля 2010

Скорее используйте regex для test it перед отправкой 416. Затем просто разберите , взорвавшись на запятой , и дефисе -. Я также вижу, что вы использовали \d+ в своем регулярном выражении, но на самом деле это , а не . Когда любой из индексов диапазона опущен, он просто означает «первый байт» или «последний байт». Вы должны также указать это в своем регулярном выражении. Также посмотрите заголовок диапазона в спецификации HTTP , как вы должны его обрабатывать.

Пример запуска:

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

2 голосов
/ 06 февраля 2010

Взят из пакета PEAR HTTP_Download :

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

Также рекомендуется использовать этот пакет для подобных вещей!

1 голос
/ 06 февраля 2010

На странице fread() есть фрагмент, реализующий поддержку диапазона HTTP:

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

...