PluginProbe ʕ •ᴥ•ʔ
JetBackup – Backup, Restore & Migrate / 3.1.11.1
JetBackup – Backup, Restore & Migrate v3.1.11.1
3.1.23.6 3.1.23.5 3.1.23.3 3.1.22.4 3.1.22.3 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.8.1 1.4.9 1.5.0 1.5.1 1.5.1.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.6.0 1.6.10 1.6.11 1.6.12 1.6.13 1.6.15 1.6.5.1 1.6.8.8 1.6.9 1.6.9.1 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7.5 2.0.8.7 2.0.9.11 2.0.9.14 2.0.9.15 2.0.9.6 2.0.9.7 2.0.9.9 3.1.10.7 3.1.11.1 3.1.12.3 3.1.13.4 3.1.14.17 3.1.15.4 3.1.16.1 3.1.17.5 3.1.18.10 3.1.18.8 3.1.18.9 3.1.19.8 3.1.20.3 3.1.21.3 3.1.7.9 3.1.9.2 trunk 1.1.90 1.1.91 1.2.0 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2
backup / src / JetBackup / Downloader / Downloader.php
backup / src / JetBackup / Downloader Last commit date
.htaccess 1 year ago Downloader.php 1 year ago index.html 1 year ago web.config 1 year ago
Downloader.php
91 lines
1 <?php
2
3 namespace JetBackup\Downloader;
4
5 use JetBackup\Exception\DownloaderException;
6 use JetBackup\Factory;
7 use JetBackup\JetBackup;
8
9 if (!defined( '__JETBACKUP__')) die('Direct access is not allowed');
10
11 class Downloader {
12
13 const DEFAULT_CHUNK = 4096; // 4k
14
15 private ?string $_filename;
16 private string $_source;
17
18 /**
19 * @param string $source
20 * @param string|null $filename
21 */
22 public function __construct(string $source, ?string $filename=null) {
23 $this->_source = $source;
24 $this->_filename = $filename;
25 }
26
27 /**
28 * @return \stdClass
29 */
30 private static function _getRange($filesize):object {
31 $output = new \stdClass();
32 $output->start = 0;
33 $output->end = $filesize-1;
34
35 if (
36 !isset($_SERVER['HTTP_RANGE']) ||
37 !preg_match('/bytes=(\d+)-(\d*)/', $_SERVER['HTTP_RANGE'], $matches)
38 ) return $output;
39
40 $output->start = (int) $matches[1];
41 if (!empty($matches[2])) $output->end = (int) $matches[2];
42
43 return $output;
44 }
45
46 /**
47 * @param int $chunk
48 *
49 * @return void
50 * @throws DownloaderException
51 */
52 public function download(int $chunk=self::DEFAULT_CHUNK):void {
53
54 if( !$this->_source || !file_exists($this->_source) || is_dir($this->_source))
55 throw new DownloaderException('The provided download file not exists');
56
57 if (!str_starts_with(trim($this->_source), trim(Factory::getLocations()->getDataDir()))) {
58 throw new DownloaderException('Invalid download source path');
59 }
60
61 if(!($fd = fopen($this->_source, 'rb')))
62 throw new DownloaderException('Unable to open download file');
63
64 if(!$this->_filename) $this->_filename = basename($this->_source);
65
66 $filesize = filesize($this->_source);
67 $range = self::_getRange($filesize);
68
69 // gzip compression may corrupt binary data
70 if (function_exists('apache_setenv')) @apache_setenv('no-gzip', 1);
71 @ini_set('zlib.output_compression', 'Off');
72 while (ob_get_level()) @ob_end_clean();
73 flush();
74
75 header("Content-Type: application/octet-stream");
76 header("Content-Disposition: attachment; filename=\"{$this->_filename}\"");
77 header("Accept-Ranges: bytes");
78 header("Content-Length: " . ($range->end - $range->start + 1));
79 header("Content-Range: bytes $range->start-$range->end/".$filesize);
80
81 if($range->start > 0) fseek($fd, $range->start);
82
83 while (!feof($fd) && ($pos = ftell($fd)) <= $range->end) {
84 echo fread($fd, min($chunk, $range->end - $pos + 1));
85 flush();
86 }
87
88 fclose($fd);
89 exit;
90 }
91 }