PHP使用Safari内置Web服务器和范围请求

时间:2016-05-27 04:11:51

标签: php http safari

我正在研究这个原型,我使用了内置的web服务器,除了处理来自Safari的mp4文件的范围请求外,所有工作都很完美。我有以下引导代码,为每个内置服务器的内置请求执行

$extensions = array("html");
$path = parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH);
$ext = pathinfo($path, PATHINFO_EXTENSION);
if (!in_array($ext, $extensions)) {
    return isRangeRequest();
}

require_once(__DIR__ . $path);


function isRangeRequest()
{
    $filelength = filesize(__DIR__ . '/video/video.mp4');
    if (isset($_SERVER['HTTP_RANGE'])) {
        $ranges = explode(',', substr($_SERVER['HTTP_RANGE'], 6));
        $parts = explode('-', $ranges[0]);
        $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 (intval($end) == 0) return false;

        $readBytes = $end - $start + 1;
        header('HTTP/1.1 206 Partial Content');
        header("Content-Length: " . $readBytes);
        header('Content-Type: video/mp4');
        header('Content-Range: bytes '.$start.'-'.$end.'/'.$filelength);
    ini_set('memory_limit', "512M");
        $fp = fopen(__DIR__ . '/video/video.mp4', 'rb');
        if ($readBytes < 4096) {
            print(fread($fp, $readBytes));
            flush();
        } else {
        fpassthru($fp);
        }
        fclose($fp);
        exit;
    }
    return false;
}

我已经使用tcpdump验证上面的代码发送了所有正确的标题,我设法让safari开始播放视频。但是safari只能播放前几帧然后视频停止。

这是来自nginx服务器的响应头,用于来自safari的相同请求

GET /video/video.mp4 HTTP/1.1
Host: job.local
Accept-Language: en-us
X-Playback-Session-Id: CD33782F-F257-4506-95C4-94ABD4E200CE
Cookie: PHPSESSID2=avrunqgk9rkb3941fe24q9asd6
Range: bytes=0-1
Accept: */*
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/601.4.4 (KHTML, like Gecko) Version/9.0.3 Safari/601.4.4
Referer: http://job.local/test.html
Accept-Encoding: identity
Connection: keep-alive

    
HTTP/1.1 206 Partial Content
Server: nginx/1.6.2 (Ubuntu)
Date: Fri, 27 May 2016 03:29:16 GMT
Content-Type: video/mp4
Content-Length: 2
Last-Modified: Thu, 26 May 2016 17:53:49 GMT
Connection: keep-alive
ETag: "5747382d-8c6c509"
Expires: Thu, 31 Dec 2037 23:55:55 GMT
Cache-Control: max-age=315360000
Content-Range: bytes 0-1/147244297

    
GET /video/video.mp4 HTTP/1.1
Host: job.local
Accept-Language: en-us
X-Playback-Session-Id: CD33782F-F257-4506-95C4-94ABD4E200CE
Cookie: PHPSESSID2=avrunqgk9rkb3941fe24q9asd6
Range: bytes=0-147244296
Accept: */*
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/601.4.4 (KHTML, like Gecko) Version/9.0.3 Safari/601.4.4
Referer: http://job.local/test.html
Accept-Encoding: identity
Connection: keep-alive

    
HTTP/1.1 206 Partial Content
Server: nginx/1.6.2 (Ubuntu)
Date: Fri, 27 May 2016 03:29:16 GMT
Content-Type: video/mp4
Content-Length: 147244297
Last-Modified: Thu, 26 May 2016 17:53:49 GMT
Connection: keep-alive
ETag: "5747382d-8c6c509"
Expires: Thu, 31 Dec 2037 23:55:55 GMT
Cache-Control: max-age=315360000
Content-Range: bytes 0-147244296/147244297

这里是使用上面的引导代码的内置服务器中的php的标题

GET /video/video.mp4 HTTP/1.1
Host: localhost:8005
Accept-Language: en-us
X-Playback-Session-Id: 740A36CB-C116-4F5E-A3BD-5B4B3A27B543
Range: bytes=0-1
Accept: */*
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/601.4.4 (KHTML, like Gecko) Version/9.0.3 Safari/601.4.4
Referer: http://localhost:8005/index.html
Accept-Encoding: identity
Connection: keep-alive

HTTP/1.1 206 Partial Content
Host: localhost:8005
Connection: close
X-Powered-By: PHP/5.5.30
Content-Length: 2
Content-Type: video/mp4
Content-Range: bytes 0-1/147244297

GET /video/video.mp4 HTTP/1.1
Host: localhost:8005
Accept-Language: en-us
X-Playback-Session-Id: 740A36CB-C116-4F5E-A3BD-5B4B3A27B543
Range: bytes=0-147244296
Accept: */*
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/601.4.4 (KHTML, like Gecko) Version/9.0.3 Safari/601.4.4
Referer: http://localhost:8005/index.html
Accept-Encoding: identity
Connection: keep-alive

HTTP/1.1 206 Partial Content
Host: localhost:8005
Connection: close
X-Powered-By: PHP/5.5.30
Content-Length: 147244297
Content-Type: video/mp4
Content-Range: bytes 0-147244296/147244297

除了内置的php服务器不支持Connection: keep-alive之外,我没有看到响应中的任何其他差异。你在这看到任何潜在的问题吗? mp4文件大约是100MB,如果我使用data-url而不是文件引用,那可以吗?

此项目适用于仅在本地计算机上使用的原型,因此没有性能或安全问题,请避免发表此类评论。核心问题是为什么safari只播放前几帧。 (我也观察到如果范围请求没有得到正确处理,safari甚至不会播放前几帧。所以还有一些其他问题可能不那么明显。

0 个答案:

没有答案