@@ -16,7 +16,7 @@ discard block |
||
| 16 | 16 | * @package SPIP\Core\Fichier |
| 17 | 17 | **/ |
| 18 | 18 | if (!defined('_ECRIRE_INC_VERSION')) { |
| 19 | - return; |
|
| 19 | + return; |
|
| 20 | 20 | } |
| 21 | 21 | |
| 22 | 22 | /** |
@@ -36,28 +36,28 @@ discard block |
||
| 36 | 36 | */ |
| 37 | 37 | function spip_livrer_fichier($fichier, $content_type = 'application/octet-stream', $options = []) { |
| 38 | 38 | |
| 39 | - $defaut = [ |
|
| 40 | - 'attachment' => false, |
|
| 41 | - 'expires' => 3600, |
|
| 42 | - 'range' => null |
|
| 43 | - ]; |
|
| 44 | - $options = array_merge($defaut, $options); |
|
| 45 | - if (is_numeric($options['expires']) and $options['expires'] > 0) { |
|
| 46 | - $options['expires'] = gmdate('D, d M Y H:i:s', time() + $options['expires']) . ' GMT'; |
|
| 47 | - } |
|
| 48 | - |
|
| 49 | - if (is_null($options) and isset($_SERVER['HTTP_RANGE'])) { |
|
| 50 | - $options['range'] = $_SERVER['HTTP_RANGE']; |
|
| 51 | - } |
|
| 52 | - |
|
| 53 | - spip_livrer_fichier_entetes($fichier, $content_type, $options['attachment'] && !$options['range'], $options['expires']); |
|
| 54 | - |
|
| 55 | - if (!is_null($options['range'])) { |
|
| 56 | - spip_livrer_fichier_partie($fichier, $options['range']); |
|
| 57 | - } |
|
| 58 | - else { |
|
| 59 | - spip_livrer_fichier_entier($fichier); |
|
| 60 | - } |
|
| 39 | + $defaut = [ |
|
| 40 | + 'attachment' => false, |
|
| 41 | + 'expires' => 3600, |
|
| 42 | + 'range' => null |
|
| 43 | + ]; |
|
| 44 | + $options = array_merge($defaut, $options); |
|
| 45 | + if (is_numeric($options['expires']) and $options['expires'] > 0) { |
|
| 46 | + $options['expires'] = gmdate('D, d M Y H:i:s', time() + $options['expires']) . ' GMT'; |
|
| 47 | + } |
|
| 48 | + |
|
| 49 | + if (is_null($options) and isset($_SERVER['HTTP_RANGE'])) { |
|
| 50 | + $options['range'] = $_SERVER['HTTP_RANGE']; |
|
| 51 | + } |
|
| 52 | + |
|
| 53 | + spip_livrer_fichier_entetes($fichier, $content_type, $options['attachment'] && !$options['range'], $options['expires']); |
|
| 54 | + |
|
| 55 | + if (!is_null($options['range'])) { |
|
| 56 | + spip_livrer_fichier_partie($fichier, $options['range']); |
|
| 57 | + } |
|
| 58 | + else { |
|
| 59 | + spip_livrer_fichier_entier($fichier); |
|
| 60 | + } |
|
| 61 | 61 | } |
| 62 | 62 | |
| 63 | 63 | /** |
@@ -70,35 +70,35 @@ discard block |
||
| 70 | 70 | * @param int|string $expires |
| 71 | 71 | */ |
| 72 | 72 | function spip_livrer_fichier_entetes($fichier, $content_type = 'application/octet-stream', $attachment = false, $expires = 0) { |
| 73 | - // toujours envoyer un content type, meme vide ! |
|
| 74 | - header('Accept-Ranges: bytes'); |
|
| 75 | - header('Content-Type: ' . $content_type); |
|
| 76 | - |
|
| 77 | - if ($fs = stat($fichier) |
|
| 78 | - and !empty($fs['size']) |
|
| 79 | - and !empty($fs['mtime'])) { |
|
| 80 | - header("Last-Modified: " . gmdate("D, d M Y H:i:s", $fs['mtime']) . " GMT"); |
|
| 81 | - header(sprintf('Etag: "%x-%x"', $fs['size'], str_pad($fs['mtime'], 16, "0"))); |
|
| 82 | - } |
|
| 83 | - |
|
| 84 | - if ($attachment) { |
|
| 85 | - $f = basename($fichier); |
|
| 86 | - // ce content-type est necessaire pour eviter des corruptions de zip dans ie6 |
|
| 87 | - header('Content-Type: application/octet-stream'); |
|
| 88 | - |
|
| 89 | - header("Content-Disposition: attachment; filename=\"$f\";"); |
|
| 90 | - header('Content-Transfer-Encoding: binary'); |
|
| 91 | - |
|
| 92 | - // fix for IE caching or PHP bug issue |
|
| 93 | - header('Expires: 0'); // set expiration time |
|
| 94 | - header('Pragma: public'); |
|
| 95 | - header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); |
|
| 96 | - } |
|
| 97 | - else { |
|
| 98 | - $f = basename($fichier); |
|
| 99 | - header("Content-Disposition: inline; filename=\"$f\";"); |
|
| 100 | - header('Expires: ' . $expires); // set expiration time |
|
| 101 | - } |
|
| 73 | + // toujours envoyer un content type, meme vide ! |
|
| 74 | + header('Accept-Ranges: bytes'); |
|
| 75 | + header('Content-Type: ' . $content_type); |
|
| 76 | + |
|
| 77 | + if ($fs = stat($fichier) |
|
| 78 | + and !empty($fs['size']) |
|
| 79 | + and !empty($fs['mtime'])) { |
|
| 80 | + header("Last-Modified: " . gmdate("D, d M Y H:i:s", $fs['mtime']) . " GMT"); |
|
| 81 | + header(sprintf('Etag: "%x-%x"', $fs['size'], str_pad($fs['mtime'], 16, "0"))); |
|
| 82 | + } |
|
| 83 | + |
|
| 84 | + if ($attachment) { |
|
| 85 | + $f = basename($fichier); |
|
| 86 | + // ce content-type est necessaire pour eviter des corruptions de zip dans ie6 |
|
| 87 | + header('Content-Type: application/octet-stream'); |
|
| 88 | + |
|
| 89 | + header("Content-Disposition: attachment; filename=\"$f\";"); |
|
| 90 | + header('Content-Transfer-Encoding: binary'); |
|
| 91 | + |
|
| 92 | + // fix for IE caching or PHP bug issue |
|
| 93 | + header('Expires: 0'); // set expiration time |
|
| 94 | + header('Pragma: public'); |
|
| 95 | + header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); |
|
| 96 | + } |
|
| 97 | + else { |
|
| 98 | + $f = basename($fichier); |
|
| 99 | + header("Content-Disposition: inline; filename=\"$f\";"); |
|
| 100 | + header('Expires: ' . $expires); // set expiration time |
|
| 101 | + } |
|
| 102 | 102 | } |
| 103 | 103 | |
| 104 | 104 | /** |
@@ -106,20 +106,20 @@ discard block |
||
| 106 | 106 | * @param string $fichier |
| 107 | 107 | */ |
| 108 | 108 | function spip_livrer_fichier_entier($fichier) { |
| 109 | - if (!file_exists($fichier)) { |
|
| 110 | - throw new \Exception(sprintf('File not found: %s', $fichier)); |
|
| 111 | - } |
|
| 109 | + if (!file_exists($fichier)) { |
|
| 110 | + throw new \Exception(sprintf('File not found: %s', $fichier)); |
|
| 111 | + } |
|
| 112 | 112 | |
| 113 | - if (!is_readable($fichier)) { |
|
| 114 | - throw new \Exception(sprintf('File not readable: %s', $fichier)); |
|
| 115 | - } |
|
| 113 | + if (!is_readable($fichier)) { |
|
| 114 | + throw new \Exception(sprintf('File not readable: %s', $fichier)); |
|
| 115 | + } |
|
| 116 | 116 | |
| 117 | - if ($size = filesize($fichier)) { |
|
| 118 | - header(sprintf('Content-Length: %d', $size)); |
|
| 119 | - } |
|
| 117 | + if ($size = filesize($fichier)) { |
|
| 118 | + header(sprintf('Content-Length: %d', $size)); |
|
| 119 | + } |
|
| 120 | 120 | |
| 121 | - readfile($fichier); |
|
| 122 | - exit(); |
|
| 121 | + readfile($fichier); |
|
| 122 | + exit(); |
|
| 123 | 123 | } |
| 124 | 124 | |
| 125 | 125 | /** |
@@ -132,98 +132,98 @@ discard block |
||
| 132 | 132 | * @throws Exception |
| 133 | 133 | */ |
| 134 | 134 | function spip_livrer_fichier_partie($fichier, $range = null) { |
| 135 | - if (!file_exists($fichier)) { |
|
| 136 | - throw new \Exception(sprintf('File not found: %s', $fichier)); |
|
| 137 | - } |
|
| 135 | + if (!file_exists($fichier)) { |
|
| 136 | + throw new \Exception(sprintf('File not found: %s', $fichier)); |
|
| 137 | + } |
|
| 138 | 138 | |
| 139 | - if (!is_readable($fichier)) { |
|
| 140 | - throw new \Exception(sprintf('File not readable: %s', $fichier)); |
|
| 141 | - } |
|
| 139 | + if (!is_readable($fichier)) { |
|
| 140 | + throw new \Exception(sprintf('File not readable: %s', $fichier)); |
|
| 141 | + } |
|
| 142 | 142 | |
| 143 | 143 | |
| 144 | - // Par defaut on envoie tout |
|
| 145 | - $byteOffset = 0; |
|
| 146 | - $byteLength = $fileSize = filesize($fichier); |
|
| 144 | + // Par defaut on envoie tout |
|
| 145 | + $byteOffset = 0; |
|
| 146 | + $byteLength = $fileSize = filesize($fichier); |
|
| 147 | 147 | |
| 148 | 148 | |
| 149 | - // Parse Content-Range header for byte offsets, looks like "bytes=11525-" OR "bytes=11525-12451" |
|
| 150 | - if ($range and preg_match('%bytes=(\d+)-(\d+)?%i', $range, $match)) { |
|
| 151 | - ### Offset signifies where we should begin to read the file |
|
| 152 | - $byteOffset = (int)$match[1]; |
|
| 149 | + // Parse Content-Range header for byte offsets, looks like "bytes=11525-" OR "bytes=11525-12451" |
|
| 150 | + if ($range and preg_match('%bytes=(\d+)-(\d+)?%i', $range, $match)) { |
|
| 151 | + ### Offset signifies where we should begin to read the file |
|
| 152 | + $byteOffset = (int)$match[1]; |
|
| 153 | 153 | |
| 154 | 154 | |
| 155 | - ### Length is for how long we should read the file according to the browser, and can never go beyond the file size |
|
| 156 | - if (isset($match[2])) { |
|
| 157 | - $finishBytes = (int)$match[2]; |
|
| 158 | - $byteLength = $finishBytes + 1; |
|
| 159 | - } else { |
|
| 160 | - $finishBytes = $fileSize - 1; |
|
| 161 | - } |
|
| 155 | + ### Length is for how long we should read the file according to the browser, and can never go beyond the file size |
|
| 156 | + if (isset($match[2])) { |
|
| 157 | + $finishBytes = (int)$match[2]; |
|
| 158 | + $byteLength = $finishBytes + 1; |
|
| 159 | + } else { |
|
| 160 | + $finishBytes = $fileSize - 1; |
|
| 161 | + } |
|
| 162 | 162 | |
| 163 | - $cr_header = sprintf('Content-Range: bytes %d-%d/%d', $byteOffset, $finishBytes, $fileSize); |
|
| 164 | - } |
|
| 165 | - else { |
|
| 166 | - // si pas de range valide, on delegue a la methode d'envoi complet |
|
| 167 | - spip_livrer_fichier_entier($fichier); |
|
| 168 | - // redondant, mais facilite la comprehension du code |
|
| 169 | - exit(); |
|
| 170 | - } |
|
| 163 | + $cr_header = sprintf('Content-Range: bytes %d-%d/%d', $byteOffset, $finishBytes, $fileSize); |
|
| 164 | + } |
|
| 165 | + else { |
|
| 166 | + // si pas de range valide, on delegue a la methode d'envoi complet |
|
| 167 | + spip_livrer_fichier_entier($fichier); |
|
| 168 | + // redondant, mais facilite la comprehension du code |
|
| 169 | + exit(); |
|
| 170 | + } |
|
| 171 | 171 | |
| 172 | - // Remove headers that might unnecessarily clutter up the output |
|
| 173 | - header_remove('Cache-Control'); |
|
| 174 | - header_remove('Pragma'); |
|
| 172 | + // Remove headers that might unnecessarily clutter up the output |
|
| 173 | + header_remove('Cache-Control'); |
|
| 174 | + header_remove('Pragma'); |
|
| 175 | 175 | |
| 176 | - // partial content |
|
| 177 | - header('HTTP/1.1 206 Partial content'); |
|
| 178 | - header($cr_header); ### Decrease by 1 on byte-length since this definition is zero-based index of bytes being sent |
|
| 176 | + // partial content |
|
| 177 | + header('HTTP/1.1 206 Partial content'); |
|
| 178 | + header($cr_header); ### Decrease by 1 on byte-length since this definition is zero-based index of bytes being sent |
|
| 179 | 179 | |
| 180 | 180 | |
| 181 | - $byteRange = $byteLength - $byteOffset; |
|
| 181 | + $byteRange = $byteLength - $byteOffset; |
|
| 182 | 182 | |
| 183 | - header(sprintf('Content-Length: %d', $byteRange)); |
|
| 183 | + header(sprintf('Content-Length: %d', $byteRange)); |
|
| 184 | 184 | |
| 185 | - // Variable containing the buffer |
|
| 186 | - $buffer = ''; |
|
| 187 | - // Just a reasonable buffer size |
|
| 188 | - $bufferSize = 512 * 16; |
|
| 189 | - // Contains how much is left to read of the byteRange |
|
| 190 | - $bytePool = $byteRange; |
|
| 185 | + // Variable containing the buffer |
|
| 186 | + $buffer = ''; |
|
| 187 | + // Just a reasonable buffer size |
|
| 188 | + $bufferSize = 512 * 16; |
|
| 189 | + // Contains how much is left to read of the byteRange |
|
| 190 | + $bytePool = $byteRange; |
|
| 191 | 191 | |
| 192 | - if (!$handle = fopen($fichier, 'r')) { |
|
| 193 | - throw new \Exception(sprintf('Could not get handle for file %s', $fichier)); |
|
| 194 | - } |
|
| 192 | + if (!$handle = fopen($fichier, 'r')) { |
|
| 193 | + throw new \Exception(sprintf('Could not get handle for file %s', $fichier)); |
|
| 194 | + } |
|
| 195 | 195 | |
| 196 | - if (fseek($handle, $byteOffset, SEEK_SET) == -1) { |
|
| 197 | - throw new \Exception(sprintf('Could not seek to byte offset %d', $byteOffset)); |
|
| 198 | - } |
|
| 196 | + if (fseek($handle, $byteOffset, SEEK_SET) == -1) { |
|
| 197 | + throw new \Exception(sprintf('Could not seek to byte offset %d', $byteOffset)); |
|
| 198 | + } |
|
| 199 | 199 | |
| 200 | 200 | |
| 201 | - while ($bytePool > 0) { |
|
| 202 | - // How many bytes we request on this iteration |
|
| 203 | - $chunkSizeRequested = min($bufferSize, $bytePool); |
|
| 201 | + while ($bytePool > 0) { |
|
| 202 | + // How many bytes we request on this iteration |
|
| 203 | + $chunkSizeRequested = min($bufferSize, $bytePool); |
|
| 204 | 204 | |
| 205 | - // Try readin $chunkSizeRequested bytes from $handle and put data in $buffer |
|
| 206 | - $buffer = fread($handle, $chunkSizeRequested); |
|
| 205 | + // Try readin $chunkSizeRequested bytes from $handle and put data in $buffer |
|
| 206 | + $buffer = fread($handle, $chunkSizeRequested); |
|
| 207 | 207 | |
| 208 | - // Store how many bytes were actually read |
|
| 209 | - $chunkSizeActual = strlen($buffer); |
|
| 208 | + // Store how many bytes were actually read |
|
| 209 | + $chunkSizeActual = strlen($buffer); |
|
| 210 | 210 | |
| 211 | - // If we didn't get any bytes that means something unexpected has happened since $bytePool should be zero already |
|
| 212 | - if ($chunkSizeActual == 0) { |
|
| 213 | - // For production servers this should go in your php error log, since it will break the output |
|
| 214 | - trigger_error('Chunksize became 0', E_USER_WARNING); |
|
| 215 | - break; |
|
| 216 | - } |
|
| 211 | + // If we didn't get any bytes that means something unexpected has happened since $bytePool should be zero already |
|
| 212 | + if ($chunkSizeActual == 0) { |
|
| 213 | + // For production servers this should go in your php error log, since it will break the output |
|
| 214 | + trigger_error('Chunksize became 0', E_USER_WARNING); |
|
| 215 | + break; |
|
| 216 | + } |
|
| 217 | 217 | |
| 218 | - // Decrease byte pool with amount of bytes that were read during this iteration |
|
| 219 | - $bytePool -= $chunkSizeActual; |
|
| 218 | + // Decrease byte pool with amount of bytes that were read during this iteration |
|
| 219 | + $bytePool -= $chunkSizeActual; |
|
| 220 | 220 | |
| 221 | - // Write the buffer to output |
|
| 222 | - print $buffer; |
|
| 221 | + // Write the buffer to output |
|
| 222 | + print $buffer; |
|
| 223 | 223 | |
| 224 | - // Try to output the data to the client immediately |
|
| 225 | - flush(); |
|
| 226 | - } |
|
| 224 | + // Try to output the data to the client immediately |
|
| 225 | + flush(); |
|
| 226 | + } |
|
| 227 | 227 | |
| 228 | - exit(); |
|
| 228 | + exit(); |
|
| 229 | 229 | } |