1
0
mirror of https://github.com/phpbb/phpbb.git synced 2025-04-21 00:02:18 +02:00

Merge pull request #4440 from danchr/ticket/14774

[ticket/14774] Support partial downloads of attachments

* danchr/ticket/14774:
  [ticket/14774] Support partial downloads of attachments
This commit is contained in:
Tristan Darricau 2016-09-11 13:59:06 +02:00
commit 1a187e0607
No known key found for this signature in database
GPG Key ID: 817043C2E29DB881
2 changed files with 119 additions and 59 deletions

View File

@ -254,11 +254,21 @@ function send_file_to_browser($attachment, $upload_dir, $category)
send_status_line(206, 'Partial Content');
header('Content-Range: bytes ' . $range['byte_pos_start'] . '-' . $range['byte_pos_end'] . '/' . $range['bytes_total']);
header('Content-Length: ' . $range['bytes_requested']);
}
while (!feof($fp))
// First read chunks
while (!feof($fp) && ftell($fp) < $range['byte_pos_end'] - 8192)
{
echo fread($fp, 8192);
}
// Then, read the remainder
echo fread($fp, $range['bytes_requested'] % 8192);
}
else
{
echo fread($fp, 8192);
while (!feof($fp))
{
echo fread($fp, 8192);
}
}
fclose($fp);
}
@ -529,6 +539,9 @@ function phpbb_find_range_request()
*/
function phpbb_parse_range_request($request_array, $filesize)
{
$first_byte_pos = -1;
$last_byte_pos = -1;
// Go through all ranges
foreach ($request_array as $range_string)
{
@ -540,62 +553,61 @@ function phpbb_parse_range_request($request_array, $filesize)
continue;
}
// Substitute defaults
if ($range[0] === '')
{
// Return last $range[1] bytes.
if (!$range[1])
{
continue;
}
if ($range[1] >= $filesize)
{
return false;
}
$first_byte_pos = $filesize - (int) $range[1];
$last_byte_pos = $filesize - 1;
}
else
{
// Return bytes from $range[0] to $range[1]
$first_byte_pos = (int) $range[0];
$last_byte_pos = (int) $range[1];
if ($last_byte_pos && $last_byte_pos < $first_byte_pos)
{
// The requested range contains 0 bytes.
continue;
}
if ($first_byte_pos >= $filesize)
{
// Requested range not satisfiable
return false;
}
// Adjust last-byte-pos if it is absent or greater than the content.
if ($range[1] === '' || $last_byte_pos >= $filesize)
{
$last_byte_pos = $filesize - 1;
}
$range[0] = 0;
}
// We currently do not support range requests that end before the end of the file
if ($last_byte_pos != $filesize - 1)
if ($range[1] === '')
{
$range[1] = $filesize - 1;
}
if ($last_byte_pos >= 0 && $last_byte_pos + 1 != $range[0])
{
// We only support contiguous ranges, no multipart stuff :(
return false;
}
if ($range[1] && $range[1] < $range[0])
{
// The requested range contains 0 bytes.
continue;
}
return array(
'byte_pos_start' => $first_byte_pos,
'byte_pos_end' => $last_byte_pos,
'bytes_requested' => $last_byte_pos - $first_byte_pos + 1,
'bytes_total' => $filesize,
);
// Return bytes from $range[0] to $range[1]
if ($first_byte_pos < 0)
{
$first_byte_pos = (int) $range[0];
}
$last_byte_pos = (int) $range[1];
if ($first_byte_pos >= $filesize)
{
// Requested range not satisfiable
return false;
}
// Adjust last-byte-pos if it is absent or greater than the content.
if ($range[1] === '' || $last_byte_pos >= $filesize)
{
$last_byte_pos = $filesize - 1;
}
}
if ($first_byte_pos < 0 || $last_byte_pos < 0)
{
return false;
}
return array(
'byte_pos_start' => $first_byte_pos,
'byte_pos_end' => $last_byte_pos,
'bytes_requested' => $last_byte_pos - $first_byte_pos + 1,
'bytes_total' => $filesize,
);
}
/**

View File

@ -45,23 +45,71 @@ class phpbb_download_http_byte_range_test extends phpbb_test_case
public function parse_range_request_data()
{
return array(
// Does not read until the end of file.
// Valid request
array(
array('3-4'),
10,
false,
array(
'byte_pos_start' => 3,
'byte_pos_end' => 4,
'bytes_requested' => 2,
'bytes_total' => 10,
),
),
// Valid request, handle second range.
// Get the beginning
array(
array('-5'),
10,
array(
'byte_pos_start' => 0,
'byte_pos_end' => 5,
'bytes_requested' => 6,
'bytes_total' => 10,
),
),
// Get the end
array(
array('5-'),
10,
array(
'byte_pos_start' => 5,
'byte_pos_end' => 9,
'bytes_requested' => 5,
'bytes_total' => 10,
),
),
// Overlong request
array(
array('3-20'),
10,
array(
'byte_pos_start' => 3,
'byte_pos_end' => 9,
'bytes_requested' => 7,
'bytes_total' => 10,
),
),
// Multiple, contiguous range
array(
array('10-20', '21-30'),
125,
array(
'byte_pos_start' => 10,
'byte_pos_end' => 30,
'bytes_requested' => 21,
'bytes_total' => 125,
)
),
// We don't do multiple, non-contiguous range
array(
array('0-0', '120-125'),
125,
array(
'byte_pos_start' => 120,
'byte_pos_end' => 124,
'bytes_requested' => 5,
'bytes_total' => 125,
)
false,
),
);
}