From 0eabc4ed417f9d159586c3b446cc04c18dbfd952 Mon Sep 17 00:00:00 2001 From: rr- Date: Wed, 30 Dec 2015 20:08:16 +0100 Subject: [PATCH] Added support for HTTP ranges (= .webm + seeking) --- src/Services/NetworkingService.php | 75 ++++++++++++++++++++++++++---- 1 file changed, 66 insertions(+), 9 deletions(-) diff --git a/src/Services/NetworkingService.php b/src/Services/NetworkingService.php index fbba649a..60becd78 100644 --- a/src/Services/NetworkingService.php +++ b/src/Services/NetworkingService.php @@ -22,20 +22,17 @@ class NetworkingService $lastModified = filemtime($fullPath); $eTag = md5($fullPath . $lastModified); - $ifModifiedSince = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) - ? $_SERVER['HTTP_IF_MODIFIED_SINCE'] - : false; - - $eTagHeader = isset($_SERVER['HTTP_IF_NONE_MATCH']) - ? trim($_SERVER['HTTP_IF_NONE_MATCH'], "\" \t\r\n") - : null; + $ifModifiedSince = $this->httpHelper->getRequestHeader('HTTP_IF_MODIFIED_SINCE'); + $eTagHeader = trim($this->httpHelper->getRequestHeader('HTTP_IF_NONE_MATCH'), "\" \t\r\n"); $this->httpHelper->setHeader('ETag', '"' . $eTag . '"'); $this->httpHelper->setHeader('Last-Modified', gmdate('D, d M Y H:i:s \G\M\T', $lastModified)); $this->httpHelper->setHeader('Pragma', 'public'); $this->httpHelper->setHeader('Cache-Control', 'public, max-age=' . $secondsToLive); $this->httpHelper->setHeader('Expires', gmdate('D, d M Y H:i:s \G\M\T', time() + $secondsToLive)); + $this->httpHelper->setHeader('Content-Transfer-Encoding', 'binary'); $this->httpHelper->setHeader('Content-Type', MimeHelper::getMimeTypeFromFile($fullPath)); + $this->httpHelper->setHeader('Accept-Ranges', 'bytes'); if ($customFileName) $this->httpHelper->setHeader('Content-Disposition', 'inline; filename="' . $customFileName . '"'); @@ -43,11 +40,71 @@ class NetworkingService if (strtotime($ifModifiedSince) === $lastModified || $eTagHeader === $eTag) { $this->httpHelper->setResponseCode(304); + exit; + } + + $fileSize = filesize($fullPath); + $range = $this->httpHelper->getRequestHeader('HTTP_RANGE'); + if (!$range) + { + $this->httpHelper->setHeader('Content-Length', $fileSize); + $this->httpHelper->setResponseCode(200); + readfile($fullPath); + } + + list ($param, $range) = explode('=', $range); + if (strtolower(trim($param)) !== 'bytes') + { + $this->httpHelper->setResponseCode(400); + exit; + } + $range = explode(',', $range); + $range = explode('-', $range[0]); + if (count($range) != 2) + { + $this->httpHelper->setResponseCode(400); + exit; + } + if ($range[0] === '') + { + $end = $fileSize - 1; + $start = $end - intval($range[0]); + } + else if ($range[1] === '') + { + $start = intval($range[0]); + $end = $fileSize - 1; } else { - $this->httpHelper->setResponseCode(200); - readfile($fullPath); + $start = intval($range[0]); + $end = intval($range[1]); + if ($end >= $fileSize || (!$start && (!$end || $end == ($fileSize - 1)))) + { + $this->httpHelper->setHeader('Content-Length', $fileSize); + $this->httpHelper->setResponseCode(200); + readfile($fullPath); + } + } + $length = $end - $start + 1; + + $this->httpHelper->setResponseCode(206); + $this->httpHelper->setHeader('Content-Range', sprintf('bytes %d-%d/%d', $start, $end, $fileSize)); + $fp = fopen($file, 'rb'); + try + { + if ($start) + fseek($fp, $start); + while ($length) + { + $read = ($length > 8192) ? 8192 : $length; + $length -= $read; + $this->httpHelper->output(fread($fp,$read)); + } + } + finally + { + fclose($fp); } exit; }