diff --git a/.env.example b/.env.example index bb3df40..927e07c 100644 --- a/.env.example +++ b/.env.example @@ -11,6 +11,7 @@ UPLOAD_MAX_FILES=1000 UPLOAD_LIMIT_IPS=127.0.0.1 UPLOAD_PREVENT_DUPLICATES=true HASH_MAX_FILESIZE=1G +LIMIT_DOWNLOAD_RATE=1M FILESYSTEM_DISK=local SESSION_DRIVER=file diff --git a/app/Http/Controllers/BundleController.php b/app/Http/Controllers/BundleController.php index af38e9d..bd0168c 100644 --- a/app/Http/Controllers/BundleController.php +++ b/app/Http/Controllers/BundleController.php @@ -68,7 +68,28 @@ public function downloadZip(Request $request, $bundleId) { // Adding the files into the Zip with their real names foreach ($metadata['files'] as $k => $file) { if (file_exists(config('filesystems.disks.uploads.root').'/'.$file['fullpath'])) { - $zip->addFile(config('filesystems.disks.uploads.root').'/'.$file['fullpath'], $file['original']); + $name = $file['original']; + + // If a file in the archive has the same name + if (false !== $zip->locateName($name)) { + $i = 0; + + // Exploding the basename and extension + $basename = (false === strrpos($name, '.')) ? $name : substr($name, 0, strrpos($name, '.')); + $extension = (false === strrpos($name, '.')) ? null : substr($name, strrpos($name, '.')); + + // Looping to find the right name + do { + $i++; + $newname = $basename.'-'.$i.$extension; + } + while ($zip->locateName($newname)); + + // Final name was found + $name = $newname; + } + // Finally adding files + $zip->addFile(config('filesystems.disks.uploads.root').'/'.$file['fullpath'], $name); if (! empty($metadata['password'])) { $zip->setEncryptionIndex($k, ZipArchive::EM_AES_256); @@ -83,14 +104,40 @@ public function downloadZip(Request $request, $bundleId) { fclose($bundlezip); } + // Getting file size + $filesize = filesize($filename); + + // Should we limit the download rate? + $limit_rate = config('sharing.download_limit_rate', false); + if ($limit_rate !== false) { + $limit_rate = Upload::humanReadableToBytes($limit_rate); + } + else { + $limit_rate = $filesize; + } + // Let's download now header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="'.Str::slug($metadata['title']).'-'.time().'.zip'.'"'); header('Cache-Control: no-cache, must-revalidate'); header('Expires: Sat, 26 Jul 1997 05:00:00 GMT'); - //TODO : fix this header('Content-Length: '.filesize($bundlezip)); - readfile($filename); + header('Content-Length: '.$filesize); + + flush(); + + + $fh = fopen($filename, 'rb'); + while (! feof($fh)) { + echo fread($fh, round($limit_rate)); + flush(); + + if ($limit_rate !== false) { + sleep(1); + } + } + fclose($filename); exit; + } // Could not find the metadata file diff --git a/config/sharing.php b/config/sharing.php index d2d3041..a5a2c25 100644 --- a/config/sharing.php +++ b/config/sharing.php @@ -29,6 +29,8 @@ */ 'upload_ip_limit' => env('UPLOAD_LIMIT_IPS', null), + 'download_limit_rate' => env('LIMIT_DOWNLOAD_RATE', false), + 'upload_prevent_duplicates' => env('UPLOAD_PREVENT_DUPLICATES', true), /** diff --git a/readme.md b/readme.md index a4b59e9..6347e7b 100644 --- a/readme.md +++ b/readme.md @@ -95,6 +95,7 @@ In order to configure your application, copy the .env.example file into .env. Th | `UPLOAD_MAX_FILES` | (*optional*) maximal number of files per bundle | | `UPLOAD_MAX_FILESIZE` | (*optional*) change this to the value you want (K, M, G, T, ...). Attention : you must configure your PHP settings too (`post_max_size`, `upload_max_filesize` and `memory_limit`). When missing, using PHP lowest configuration | | `UPLOAD_LIMIT_IPS` | (*optional*) a comma separated list of IPs from which you may upload files. Different formats are supported : Full IP address (192.168.10.2), Wildcard format (192.168.10.*), CIDR Format (192.168.10/24 or 1.2.3.4/255.255.255.0) or Start-end IP (192.168.10.0-192.168.10.10). When missing, filtering is disabled. | +| `LIMIT_DOWNLOAD_RATE` | (*optional*) if set, limit the download rate. For instance, you may set `LIMIT_DOWNLOAD_RATE=100K` to limit download rate to 100Ko/s | ## Authentication