$source = file_create_path($source); - // Transfer file in 1024 byte chunks to save memory usage. if ($fd = fopen($source, 'rb')) { + // Tell that we accept byte-ranges + header('Accept-Ranges: bytes'); + + // Get filesize. + $filesize = filesize($source); + + // Is this a partial request? + if(isset($_SERVER['HTTP_RANGE'])) { + if(preg_match('/^bytes=(\d+)-(\d+)$/', $_SERVER['HTTP_RANGE'], $match)) { + + $range_from = $match[1]; + $range_to = $match[2]; + + if($range_to+1 >= $filesize || $range_from >= $range_to) { + header('416 Requested Range Not Satisfiable'); + $range_from = 0; + $range_to = $filesize-1; + } + else { + header('HTTP/1.1 206 Partial Content'); + // Move file pointer + fseek($fd,$range_from); + } + } + else { + header('416 Requested Range Not Satisfiable'); + $range_from = 0; + $range_to = $filesize-1; + } + + $r = $range_to-$range_from+1; + + header(sprintf('Content-Range: bytes %d-%d/%d',$range_from,$range_to,$filesize)); + header('Content-Length: '.$r); + } + else { + $r = $filesize; + header('Content-Length: '.$filesize); + } + + // Transfer file in 1024 byte chunks to save memory usage. while (!feof($fd)) { - print fread($fd, 1024); + if($r >= 1024) { + $r=$r-1024; + print fread($fd, 1024); + } else { + print fread($fd, $r); + break; + } } fclose($fd); }