Fix uploads over 4 GB failing with a misleading size error

Livewire's temporary upload rule was hard-coded to max:4194304 (4 GB),
so /livewire/upload-file rejected any larger file no matter how high
PHP_UPLOAD_MAX_FILESIZE or the admin's max file size were set.
_uploadErrored() then replaced Livewire's actual message with "file
exceeds the maximum size of N MB", quoting the admin limit the file was
under.

The cap is removed: PHP's upload_max_filesize is the hard limit and the
admin setting is still enforced in updatedFiles() and createShare(). A
rejected upload now logs the real validation errors and tells the user
the server could not accept the file.

max_upload_time is configurable via LIVEWIRE_MAX_UPLOAD_TIME, and the
README documents every limit large uploads depend on.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017XYnWFt9pJEwvAmNFN38XD
This commit is contained in:
Andreas Reinhold / reini
2026-09-10 10:42:21 +02:00
co-authored by Claude Opus 5
parent 992f3da084
commit 126c0a5cdb
6 changed files with 67 additions and 18 deletions
+34
View File
@@ -5,6 +5,7 @@ use App\Livewire\SystemPasswordPrompt;
use App\Models\Setting;
use App\Models\Share;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use Livewire\Livewire;
@@ -119,6 +120,39 @@ test('files added in multiple batches end up in the same share', function () {
expect($share->files->pluck('original_name')->all())->toBe(['first.txt', 'second.txt']);
});
test('files larger than 4 GB can be shared when within the admin file size limit', function () {
Storage::fake('shares');
Setting::set('max_file_size', 15000 * 1024 * 1024);
Setting::set('max_size_per_share', 20 * 1024 * 1024 * 1024);
Livewire::test(FileUploader::class)
->set('files', [UploadedFile::fake()->create('backup.dump', 6 * 1024 * 1024)])
->assertHasNoErrors('files')
->call('createShare')
->assertHasNoErrors()
->assertRedirectContains('/share/');
expect(Share::query()->first()->total_size)->toBe(6 * 1024 * 1024 * 1024);
});
test('a rejected upload logs the real reason instead of blaming the file size limit', function () {
Log::spy();
Setting::set('max_file_size', 15000 * 1024 * 1024);
$errors = ['files.0' => ['The files.0 failed to upload.']];
$component = Livewire::test(FileUploader::class)
->call('_uploadErrored', 'files', json_encode(['errors' => $errors]), true)
->assertDispatched('upload:errored');
expect($component->errors()->first('files'))
->toBe('Upload failed: the server could not accept the file. Please try again or contact the administrator.');
Log::shouldHaveReceived('warning')
->withArgs(fn (string $message, array $context): bool => $context['errors'] === $errors)
->once();
});
test('file upload requires at least one file', function () {
Livewire::test(FileUploader::class)
->set('files', [])