diff options
author | Dan Villiom Podlaski Christiansen <danchr@gmail.com> | 2016-09-07 03:58:33 +0200 |
---|---|---|
committer | Dan Villiom Podlaski Christiansen <danchr@gmail.com> | 2016-09-07 03:58:33 +0200 |
commit | d2750b650fb3600ef2cf7b7139998e1a71c7d5ef (patch) | |
tree | 7c7a018e29f0fcd293609bee8ae32a6b42c5c557 /phpBB/includes/functions_download.php | |
parent | 65921a78915e0c9bf494e8c780681522644abf7d (diff) | |
download | forums-d2750b650fb3600ef2cf7b7139998e1a71c7d5ef.tar forums-d2750b650fb3600ef2cf7b7139998e1a71c7d5ef.tar.gz forums-d2750b650fb3600ef2cf7b7139998e1a71c7d5ef.tar.bz2 forums-d2750b650fb3600ef2cf7b7139998e1a71c7d5ef.tar.xz forums-d2750b650fb3600ef2cf7b7139998e1a71c7d5ef.zip |
[ticket/14774] Support partial downloads of attachments
phpBB already had limited support for partial downloads, but only for
resuming downloads, disregarding any range ending before EOF.
WebKit on iOS and OS X uses partial downloads when fetching media
files. Previously, only MP3 attachments could play directly in the
browser, reported as a live stream, but with this change, all
supported media formats should render as expected.
Tested using cURL by verifying that partial downloads give exactly the
same results compared to Apache.
PHPBB3-14774
Diffstat (limited to 'phpBB/includes/functions_download.php')
-rw-r--r-- | phpBB/includes/functions_download.php | 98 |
1 files changed, 55 insertions, 43 deletions
diff --git a/phpBB/includes/functions_download.php b/phpBB/includes/functions_download.php index 2c6f62227c..78ccebf276 100644 --- a/phpBB/includes/functions_download.php +++ b/phpBB/includes/functions_download.php @@ -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; - } + $range[0] = 0; + } - if ($range[1] >= $filesize) - { - return false; - } + if ($range[1] === '') + { + $range[1] = $filesize - 1; + } - $first_byte_pos = $filesize - (int) $range[1]; - $last_byte_pos = $filesize - 1; + if ($last_byte_pos >= 0 && $last_byte_pos + 1 != $range[0]) + { + // We only support contiguous ranges, no multipart stuff :( + return false; } - else + + if ($range[1] && $range[1] < $range[0]) { - // Return bytes from $range[0] to $range[1] + // The requested range contains 0 bytes. + continue; + } + // 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 ($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; - } + $last_byte_pos = (int) $range[1]; - // 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 >= $filesize) + { + // Requested range not satisfiable + return false; } - // We currently do not support range requests that end before the end of the file - if ($last_byte_pos != $filesize - 1) + // Adjust last-byte-pos if it is absent or greater than the content. + if ($range[1] === '' || $last_byte_pos >= $filesize) { - continue; + $last_byte_pos = $filesize - 1; } + } - 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, - ); + 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, + ); } /** |