please ignore "Original" information since I already know this is nothing to do with CI.
In order to simplify problems, I create another vhost and put only one HTML and one PHP files, just to try pure file upload without CI.
<html><body>
<form method="post" enctype="multipart/form-data" action="upload.php">
<input type="file" name="my_file">
<input type="submit" value="Upload">
</form>
</body></html>
And pure file upload like this:
# Check if file uploaded
if ($_FILES['my_file']['error'] === UPLOAD_ERR_OK){
echo 'file name: ' . $_FILES['my_file']['name'] . '<br/>';
echo 'file type: ' . $_FILES['my_file']['type'] . '<br/>';
echo 'file size: ' . ($_FILES['my_file']['size'] / 1024) . ' KB<br/>';
echo 'tmp file: ' . $_FILES['my_file']['tmp_name'] . '<br/>';
# check if file exits
if (file_exists('/tmp/' . $_FILES['my_file']['name'])){
echo 'file already exists。<br/>';
} else {
$file = $_FILES['my_file']['tmp_name'];
$dest = '/tmp/after-' . $_FILES['my_file']['name'];
# try moving file and rename
move_uploaded_file($file, $dest);
}
} else {
echo 'Error:' . $_FILES['my_file']['error'] . '<br/>';
}
Upload file less than 10MB is fine, will receive echo message. But upload file larger than 10MB will receive no echo message. Check my /tmp folder can see upload is success. There is a "after-firewall.pdf.zip" file which is 21MB, so upload and move is done.
-rw-r--r-- 1 apache apache 21M 2月 9 07:25 after-firewall.pdf.zip
-rw-r--r-- 1 apache apache 420K 2月 9 07:31 after-LINE_ALBUM_230117_6.jpg
-rw-r--r-- 1 apache apache 8.1M 2月 9 07:24 after-test_upload.zip
-rw-r--r-- 1 apache apache 141 2月 9 06:50 upload_log.txt
But why browser and POSTMAN cannot get response? Is there any setting block or delay php-fpm or Apache2 response?
————- Original Question ———
You can ignore below complex statement….
We already know this is nothing to do with CodeIgniter.
We have an up and running services which using CodeIgniter 3.1.11. I am trying to add an upload file function and it works. But somehow if file is larger than 10MB, browser cannot get response (it will wait until time out). I am sure file upload is success and can upload up to 100MB file. (PHP max upload and post size is set to 100MB, max execution time is set to 300 seconds.)
Amazon Linux 2
Apache version: 2.4.54
PHP version: 7.2.34
CodeIgniter version: 3.1.11
Upload related code like this. After upload completed, it will bring file information to next page.
if($this->upload->do_upload('uploadfile')){
$file1 = $this->upload->data();
$arr_info['file']['file_size'] = $file1['file_size'];
$arr_info['file']['ori_file_name'] = $file1['orig_name'];
$arr_info['file']['file_extension'] = $file1['file_ext'];
$arr_info['file']['fullpath'] = $file1['full_path'];
}
else {
echo "Upload failed! Please try again!";
exit;
}
$pagedata['data'] = $arr_info;
$this->template->load('layout', '/build/end_upload', $pagedata);
When upload a 5.5MB filename schedule.json, it will success.
Select a 5.5 MB file to upload
It will go to next page and show file information (array) like this.
Browser can get response, file upload success.
But if I upload file larger than 10MB, although file can successfully upload to server, my browser will not get response and wait until timeout. Here is my /tmp folder where upload file placed. You can see a 61MB file name "2023TaipeiNewYear.mp4" successfully uploaded.
enter image description here
CodeIgniter logs are like this:
CI says it was finished
Since last few lines says it has loaded view file, and "Final output sent to browser". I think it means CodeIgniter had done his job. But browser still hang and wait until timeout.
I tested in Chrome(109.0.5414.119), FireFox (109.0.1), Edge(109.0.1518.78 ) but got the same result.
I wonder if php-fpm have some issue so open DEBUG mode to trace, when upload started it showed
[08-Feb-2023 05:37:39.040845] DEBUG: pid 8604, fpm_pctl_perform_idle_server_maintenance(), line 378: [pool www] currently 1 active children, 5 spare children, 6 running children. Spawning rate 1
and after few seconds, active children turn to 0, and file did uploaded to /tmp folder. But, browser still get nothing.
[08-Feb-2023 05:37:40.042082] DEBUG: pid 8604, fpm_pctl_perform_idle_server_maintenance(), line 378: [pool www] currently 0 active children, 6 spare children, 6 running children. Spawning rate 1
I think it means php-fpm had done his part.
some php.ini settings may be related:
max_input_time= 300
output_buffering= off
max_execution_time = 300
memory_limit = 512M
post_max_size = 100M
file_uploads = On
upload_max_filesize = 100M
I wonder if anything happened or hanged in upload process, or can load CodeIgniter view for some reason. so I try to write a log in server after upload, then echo result to browser.
if($this->upload->do_upload('uploadfile')){
$file1 = $this->upload->data();
$arr_info['success'] = 1;
$arr_info['file']['file_size'] = $file1['file_size'];
$arr_info['file']['file_name'] = $file_name;
$arr_info['file']['ori_file_name'] = $file1['orig_name'];
$arr_info['file']['file_md5'] = md5_file($file1['full_path']);
$arr_info['file']['file_extension'] = $file1['file_ext'];
$arr_info['file']['file_md5_type'] = 'md5';
}
else {
echo "Upload failed! Please try again!";
exit;
}
$log = json_encode($arr_info);
exec('echo "'. $log . '" >> /tmp/upload_log.txt &');
header('Content-Type: application/json; charset=utf-8');
echo $log;
flush();
exit;
After try to upload two files which are 8.2MB and 10.2MB, I get this log.
{success:1,file:{file_size:8217.24,file_name:s-test_upload.zip,ori_file_name:test_upload.zip,file_md5:34d8753e37df705fc3358c4b4e5e2754,file_extension:.zip,file_md5_type:md5}}
{success:1,file:{file_size:10250.2,file_name:s-AINTD.png,ori_file_name:AINTD.png,file_md5:0eb1b12a08ee913102cfb5db29a9589d,file_extension:.png,file_md5_type:md5}}
So two uploads are success, but only the first one can get JSON output on browser, the second one which larger than 10MB still hangs and get nothing response.
I can’t see any error messages in php-fpm and apache logs.
Not sure what happens. If anyone needs any more information please let me know. Thanks!
2
Answers
After create a few other AWS instances to test, we finally find out that this is a HTTP protocol issue.
We were running services inside our internal network when coding on development environment, so we just use internal IP and HTTP for connection on dev servers.
After I register a real domain and give it SSL certification, running through HTTPS protocol to upload file more than 10MB would be okay.
But I don't think HTTP POST have any limitation before..... we had coding on HTTP only dev environment for years..... not sure if major browsers have a new limitations on HTTP protocol.
https://codeigniter.com/userguide3/libraries/file_uploading.html#the-controller
put display_error in else block:
$this->upload->display_errors('<pre>', '</pre>');
if you have some time, please try it out to see what the result will be if you use
move_upload_file()
function https://www.php.net/manual/en/function.move-uploaded-file.phpcheck
phpinfo()
that the settings are real in php-side((we also use codeigniter 3.1, we can easily upload a 500mb file))