mirror of
https://github.com/php-curl-class/php-curl-class.git
synced 2026-08-30 12:14:36 +00:00
Add limited support for 416 Requested Range Not Satisfiable
This commit is contained in:
@@ -8,8 +8,6 @@ class ContentRangeServer
|
||||
{
|
||||
public function serve($path)
|
||||
{
|
||||
$range = new RangeHeader($_SERVER['HTTP_RANGE']);
|
||||
|
||||
$filesize = filesize($path);
|
||||
$fp = fopen($path, 'r');
|
||||
|
||||
@@ -19,16 +17,25 @@ class ContentRangeServer
|
||||
header('Accept-Ranges: bytes');
|
||||
fpassthru($fp);
|
||||
} else {
|
||||
header('HTTP/1.1 206 Partial Content');
|
||||
header('Content-Length: ' . $range->getLength($filesize));
|
||||
header('Content-Range: ' . $range->getContentRangeHeader($filesize));
|
||||
$range = new RangeHeader($_SERVER['HTTP_RANGE'], $path);
|
||||
|
||||
$start = $range->getFirstBytePosition($filesize);
|
||||
if (!$range->isValid()) {
|
||||
header('HTTP/1.1 416 Requested Range Not Satisfiable');
|
||||
header('Content-Range: ' . $range->getContentRangeHeader());
|
||||
exit;
|
||||
}
|
||||
|
||||
$length = $range->getLength();
|
||||
|
||||
header('HTTP/1.1 206 Partial Content');
|
||||
header('Content-Length: ' . $length);
|
||||
header('Content-Range: ' . $range->getContentRangeHeader());
|
||||
|
||||
$start = $range->getFirstBytePosition();
|
||||
if ($start > 0) {
|
||||
fseek($fp, $start, SEEK_SET);
|
||||
}
|
||||
|
||||
$length = $range->getLength($filesize);
|
||||
$chunk_size = 4096;
|
||||
while ($length) {
|
||||
$read = $length > $chunk_size ? $chunk_size : $length;
|
||||
|
||||
@@ -6,48 +6,65 @@ class RangeHeader
|
||||
{
|
||||
private $first_byte;
|
||||
private $last_byte;
|
||||
private $filesize;
|
||||
private $is_valid = true;
|
||||
|
||||
public function __construct($http_range_header)
|
||||
public function __construct($http_range_header, $file_path)
|
||||
{
|
||||
// Simulate basic support for the Content-Range header.
|
||||
preg_match('/bytes=(\d+)?-(\d+)?/', $http_range_header, $matches);
|
||||
$this->first_byte = isset($matches['1']) ? (int)$matches['1'] : null;
|
||||
$this->last_byte = isset($matches['2']) ? (int)$matches['2'] : null;
|
||||
|
||||
$this->filesize = filesize($file_path);
|
||||
|
||||
// Start position begins after end of file.
|
||||
if ($this->first_byte >= $this->filesize) {
|
||||
$this->is_valid = false;
|
||||
}
|
||||
|
||||
// "If the last-byte-pos value is present, it MUST be greater than or equal to the first-byte-pos in that
|
||||
// byte-range-spec, or the byte- range-spec is syntactically invalid."
|
||||
if (!($this->last_byte === null) && !($this->last_byte >= $this->first_byte)) {
|
||||
$this->is_valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
public function getFirstBytePosition($file_size)
|
||||
public function getFirstBytePosition()
|
||||
{
|
||||
$size = (int)$file_size;
|
||||
|
||||
if ($this->first_byte === null) {
|
||||
return $size - 1 - $this->last_byte;
|
||||
return $this->filesize - 1 - $this->last_byte;
|
||||
}
|
||||
|
||||
return $this->first_byte;
|
||||
}
|
||||
|
||||
public function getLastBytePosition($file_size)
|
||||
public function getLastBytePosition()
|
||||
{
|
||||
$size = (int)$file_size;
|
||||
|
||||
if ($this->last_byte === null) {
|
||||
return $size - 1;
|
||||
return $this->filesize - 1;
|
||||
}
|
||||
|
||||
return $this->last_byte;
|
||||
}
|
||||
|
||||
public function getLength($file_size)
|
||||
public function getLength()
|
||||
{
|
||||
$size = (int)$file_size;
|
||||
|
||||
return $this->getLastBytePosition($size) - $this->getFirstBytePosition($size) + 1;
|
||||
return $this->getLastBytePosition() - $this->getFirstBytePosition() + 1;
|
||||
}
|
||||
|
||||
public function getContentRangeHeader($file_size)
|
||||
public function getByteRangeSpec()
|
||||
{
|
||||
return
|
||||
'bytes ' . $this->getFirstBytePosition($file_size) . '-' . $this->getLastBytePosition($file_size) . '/' .
|
||||
$file_size;
|
||||
return $this->is_valid ? $this->getFirstBytePosition() . '-' . $this->getLastBytePosition() : '*';
|
||||
}
|
||||
|
||||
public function getContentRangeHeader()
|
||||
{
|
||||
return 'bytes ' . $this->getByteRangeSpec() . '/' . $this->filesize;
|
||||
}
|
||||
|
||||
public function isValid()
|
||||
{
|
||||
return $this->is_valid;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user