I'm trying to upload a file in my Laravel 9 application. On the localhost, it works just fine, however, the same action fails when I try it from my application running on an Amazon Linux EC2.
What I know:
.env
)What I suspect the issue is:
dd()
call in the first line of the update()
function and it doesn't even get there. The 403
error is thrown before that. see below.What I've done to troubleshoot:
authorize()
function inside the request class returns true
file_uploads = On
, upload_max_filesize = 4M
and max_file_uploads = 20
inside php.ini
Here is what my controller looks like (the authorize()
function inside UpdateContactRequest
returns true
):
//https://myapp.com/contacts/1
//App\Http\Controllers\ContactController
public function update(UpdateContactRequest $request, Contact $contact)
{
dd($request); //This does not get executed. The 403 error happens before reaching this.
$contact->update($request->all());
$this->uploadAvatar($request, $contact);
Flash::success('Contact updated successfully.');
return redirect(route('dealers.contacts.index', $contact->dealer->id));
}
Here is the uploadAvatar
function I use to do the upload:
private function uploadAvatar(Request $request, Contact $contact)
{
if ($request->hasFile('avatar')) {
try {
$contact
->addMediaFromRequest('avatar')
->sanitizingFileName(function ($fileName) {
return strtolower(str_replace(['#', '/', '\\', ' '], '-', $fileName));
})
->toMediaCollection('avatars');
} catch (\Spatie\MediaLibrary\MediaCollections\Exceptions\FileUnacceptableForCollection $e) {
Flash::error($e->getMessage());
}
}
}
How the routes are defined:
Route::get('/', function () {
return view('welcome');
});
Route::get('/test', App\Http\Controllers\TestController::class);
Route::get('/embed-iframe/{uuid}', [App\Http\Controllers\EmbedController::class, 'iframe']);
Route::get('/embed-js/{uuid}', [App\Http\Controllers\EmbedController::class, 'js']);
Auth::routes();
Route::middleware('admin')->group(function () {
Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');
Route::resource('dealers', App\Http\Controllers\DealerController::class);
Route::post('refreshDealerCRMData', [App\Http\Controllers\DealerController::class, 'refreshCRMData']);
Route::post('loadCRMView', [App\Http\Controllers\DealerController::class, 'loadCRMView']);
Route::resource('cms', App\Http\Controllers\CmsController::class);
Route::resource('crms', App\Http\Controllers\CrmController::class);
Route::resource('leads', App\Http\Controllers\LeadController::class);
Route::resource('contacts', App\Http\Controllers\ContactController::class);
Route::resource('attachment-categories', App\Http\Controllers\AttachmentCategoryController::class);
Route::resource('CRMAttachments', App\Http\Controllers\CRMAttachmentController::class);
Route::resource('dealers.leads', App\Http\Controllers\DealerLeadController::class)->scoped([
'dealers' => 'dealer.id',
'leads' => 'lead.id',
]);
Route::resource('dealers.contacts', App\Http\Controllers\DealerContactController::class)->scoped([
'dealers' => 'dealer.id',
'contacts' => 'contact.id',
]);
});
Here is a screenshot of my root directory (/var/www/html
):
Here are my virtual hosts defined in /etc/httpd/conf/httpd.conf
<VirtualHost *:443>
ServerAdmin user@domain.com
ServerName myapp.com
ServerAlias www.myapp.com
DocumentRoot /var/www/html/public
<Directory /var/www/html>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
<VirtualHost *:80>
ServerAdmin user@domain.com
ServerName myapp.com
ServerAlias www.myapp.com
DocumentRoot /var/www/html/public
<Directory /var/www/html>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
Here is my IAM policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:ListBucket",
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::mybucket",
"arn:aws:s3:::mybucket/*"
]
}
]
}
Here is a screenshot of the exact error being thrown:
How can I further troubleshoot this when no actual exception is thrown?
The issue was with an AWS WAF rule preventing HTTP post size from exceeding a certain number. Removed the rule, and it's now working again.