Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dropzone.js upload with PHP failed after 30 seconds upload

I'm trying to upload "large" files to my application. Users must be able to upload video files smallest than 200MB but seem the server drops the connections after 4MB or 30 seconds and the upload fails.

I've already set all the parameters in my php.inifile as this:

max_input_time = 320
max_execution_time = 320
max_file_uploads = 20
memory_limit = 512M
post_max_size = 201M
upload_max_filesize = 200M

Everything is working when I upload a file of 2MB @ 1Mbps/s (I don't know if is a problem relating to filesize or transfer time)

Live php_info() file can be reached at php_info

Although here is DropZone.js conf:

$("#dZUpload").dropzone({
     url: "/ajax/admin/admin.acceptVideo.php",
     maxFilesize: 209715200,
     acceptedFiles: "video/*",
     addRemoveLinks: true,
     dataType: "HTML",
     data: { id: '' },
     success: function (file, response, data) {
         var imgName = response;
         file.previewElement.classList.add("dz-success");
         $('#form_video').val(imgName);
     },
     error: function (file, response) {
     file.previewElement.classList.add("dz-error");
     }
});
Dropzone.autoDiscover = false;
Dropzone.prototype.defaultOptions.dictRemoveFile = "Rimuovi file";
Dropzone.prototype.defaultOptions.dictCancelUpload = "Annulla";

And here is the PHP script that handles uploads:

<?php
require_once '../db.config.php';

header('Content-Type: text/plain; charset=utf-8');

ini_set('upload_max_filesize', '200M');
ini_set('post_max_size', '201M');
ini_set('max_input_time', 320);
ini_set('memory_limit', '256M'); 


try {
    if (
        !isset($_FILES['file']['error']) ||
        is_array($_FILES['file']['error'])
    ) {
        throw new RuntimeException('Invalid parameters.');
    }

    switch ($_FILES['file']['error']) {
    case UPLOAD_ERR_OK:
        break;
    case UPLOAD_ERR_NO_FILE:
        throw new RuntimeException('No file sent.');
        break;
    case UPLOAD_ERR_INI_SIZE:
        break;
    case UPLOAD_ERR_FORM_SIZE:
        throw new RuntimeException('Exceeded filesize limit.');
        break;
    default:
        throw new RuntimeException('Unknown errors.');
        break;
}

    // check filesize. 
    if ($_FILES['file']['size'] > 209715200) {
        throw new RuntimeException('Exceeded filesize limit.');
    }

    // Check MIME Type.
    $finfo = new finfo(FILEINFO_MIME_TYPE);
    if (false === $ext = array_search(
            $finfo->file($_FILES['file']['tmp_name']),
            array(
                'mp4' => 'video/mp4',
                'mov' => 'video/mov',
                'avi' => 'video/avi',
            ),
            true
        )) {
        throw new RuntimeException('Invalid file format.');
    }

    // name uniquely.
    $fileName = sha1_file($_FILES['file']['tmp_name']);
    if (!move_uploaded_file($_FILES['file']['tmp_name'], sprintf('/var/www/html/beta.vedocompro.it/web/webtemp/%s.%s', $fileName, $ext ))) {
        throw new RuntimeException('Failed to move uploaded file.');
    }

    try {

        $PDO = new PDO('mysql:host=' . $DB_HOST . ';dbname=' . $DB_NAME,$DB_USER,$DB_PASS);
        $insert = $PDO->prepare("INSERT INTO `videos` (`id`, `aid`, `accepted`, `uid`, `dir`) VALUES (NULL, '0', '0', '0', $fileName);");
        $insert->execute();

        echo $fileName;

    } catch(PDOException $exception) {
        echo $exception;
    }



} catch (RuntimeException $e) {

    echo $e->getMessage();

}

So everything seems to be ok but server drop the connection after something wrong (I don't think is related to PDOquery cause a smaller file of 2MB will work).

Could you please help identify the problem?

EDIT Doing some tests i've found that the script drop exactly at 30 second of execution, i've tryed to add set_time_limit(0); in top of the script but nothing changed again

like image 654
andreaem Avatar asked Sep 23 '17 13:09

andreaem


2 Answers

Problem was in XHR timeout referred to ajax call configuration.

To avoid this, must to put timeout: 180000(or what you want in ms) in the DropZone.js init parameters.

$("#dZUpload").dropzone({
     url: "/ajax/admin/admin.acceptVideo.php",
     maxFilesize: 209715200,
     acceptedFiles: "video/*",
     addRemoveLinks: true,
     dataType: "HTML",
     timeout: 180000,
     success: function (file, response, data) {
         // Do things on Success
     },
     error: function (file, response) {
     file.previewElement.classList.add("dz-error");
     }
});

This will not cause the 30 seconds timeout when uploading file with DropZone.js.

UPDATE

As @Brendon Muir reported, You can also insert 0 as timeout to disable the timeout.

The DropZone.js Documentation reports that the default timeout is 0, that's incorrect, the default timeout is 30 seconds. A value of 0 will disable the timeout.

like image 145
andreaem Avatar answered Nov 03 '22 07:11

andreaem


I realise this question is a little old but I have had issues with catching the timeout behaviour and discovered this solution instead where the timeout is caught on the sending function as shown below:

$("#dZUpload").dropzone({
     url: "/ajax/admin/admin.acceptVideo.php",
     maxFilesize: 209715200,
     acceptedFiles: "video/*",
     addRemoveLinks: true,
     dataType: "HTML",
     data: { id: '' },
     success: function (file, response, data) {
         var imgName = response;
         file.previewElement.classList.add("dz-success");
         $('#form_video').val(imgName);
     },
     error: function (file, response) {
         file.previewElement.classList.add("dz-error");
     },
     //Called just before each file is sent
     sending: function(file, xhr, formData) {
         //Execute on case of timeout only
         xhr.ontimeout = function(e) {
             //Output timeout error message here
             console.log('Server Timeout');

         };
     }
});
like image 1
karen Avatar answered Nov 03 '22 07:11

karen