Roundcube Community Forum

 

File upload failed.

Started by adb101, January 24, 2017, 12:58:47 PM

Previous topic - Next topic

adb101

Nope - not had any luck getting attachments to work. Just tried version 1.3.0 and still get the same error (so still having to log into Horde to add attachments to emails!).  :(

Obviously I get loads back from the phpinfo() call - what sections in particular are of interest?

SKaero

upload_max_filesize and max_post_size

adb101

upload_max_filesize   20M   20M
post_max_size                   25M   25M

Just to note: file uploads/attachments work fine through Horde running on the same server (same apache/php etc)

SKaero

Whats in the Roundcube error log?

adb101

I have "$config['debug_level'] = 1;" set but no "error" log file being generated in "logs" directory.

I have set the debug for the imap etc and they are generating logs in the "logs" directory, but don't contain any errors.

The only error is the one generated by the UI (see attached). Nothing in /var/log either.

SKaero

Do you have any logs that relate to the upload in your main web server logs?

adb101

No, nothing in OS or Apache logs. Ideally I'd like to know what the function is trying to do, but my PHP skillz are not sufficiently in-depth to work it out. Obviously RC can write to the directory (as it creates a zero length file), it's just the writing of the data to that file that seems to fail. Clearly it's a configuration issue with the server but until I can work out what the file upload function is failing on exactly I'm a bit stuck as to what's going on (could strace it I guess...)  :-\

phil2k

Hi,

I had the same issue  :o !
And after loosing some long hours doing some debuging on every side of the problem (browser side: JS, Networking, etc., server side: web-server, php-config, memcache config, Filesystem: owners, permissions, disk-space, etc. ::) ) :( , I found out that somehow the exec_hook "attachment_upload" is called twice (don't know why  :o because I'm not a dev-guy for roundcube, neither PHP OOP  :-[ ) :
1. first call somehow alters(empty) the value of args['path'] (loosing the original uploaded file), than
2. at the second exec_hook calls the function upload() (from plugins/filesystem_attachments/filesystem_attachments.php), having this argument altered(emptied) already because as comments from above definition of the function exec_hook() says:
QuoteThe (probably) altered hook arguments
, this already happened ( that "probably" should be emphasised ;D ) :

./program/lib/Roundcube/rcube_plugin_api.php :
   /**
     * Triggers a plugin hook.
     * This is called from the application and executes all registered handlers
     *
     * @param string $hook Hook name
     * @param array $args Named arguments (key->value pairs)
     *
     * @return array The (probably) altered hook arguments
     */
    public function exec_hook($hook, $args = array())
    {
        if (!is_array($args)) {
            $args = array('arg' => $args);
        }

        // TODO: avoid recursion by checking in_array($hook, $this->exec_stack) ?

        $args += array('abort' => false);
        array_push($this->exec_stack, $hook);

        // Use for loop here, so handlers added in the hook will be executed too
        for ($i = 0; $i < count($this->handlers[$hook]); $i++) {
            if ($hook=="attachment_upload") error_log("debug: exec_hook(".$hook."): i=$i, args = ".print_r($args, true));
            $ret = call_user_func($this->handlers[$hook][$i], $args);
            if ($hook=="attachment_upload") error_log("debug: exec_hook(".$hook."): i=$i, ret = ".print_r($ret, true));
            if ($ret && is_array($ret)) {
                $args = $ret + $args;
            }

            if ($args['break']) {
                break;
            }
        }

        array_pop($this->exec_stack);
        return $args;
    }


The temporary fix that it seems to work for the moment for me, was to add a backup value stored as key "uploaded_full_path" (beside existing "path") in the constructed args array from program/steps/mail/attachments.inc at line 123, like below:

// handle file(s) upload
if (is_array($_FILES['_attachments']['tmp_name'])) {
    $multiple = count($_FILES['_attachments']['tmp_name']) > 1;

    foreach ($_FILES['_attachments']['tmp_name'] as $i => $filepath) {
        // Process uploaded attachment if there is no error
        $err = $_FILES['_attachments']['error'][$i];

        if (!$err) {
            $attachment = $RCMAIL->plugins->exec_hook('attachment_upload', array(
                'uploaded_full_path' => $filepath,
                'path' => $filepath,
                'size' => $_FILES['_attachments']['size'][$i],
                'name' => $_FILES['_attachments']['name'][$i],
                'mimetype' => rcube_mime::file_content_type($filepath, $_FILES['_attachments']['name'][$i], $_FILES['_attachments']['type'][$i]),
                'group' => $COMPOSE_ID,
            ));
        }


than to change the used value by move_uploaded_file() in upload() function in plugins/filesystem_attachments/filesystem_attachments.php, from $args['path'] to $args['uploaded_full_path'], like below:

    /**
     * Save a newly uploaded attachment
     */
    function upload($args)
    {
        $args['status'] = false;
        $group  = $args['group'];
        $rcmail = rcube::get_instance();

        // use common temp dir for file uploads
        $temp_dir = $rcmail->config->get('temp_dir');
        $tmpfname = tempnam($temp_dir, 'rcmAttmnt');

        if (move_uploaded_file($args['uploaded_full_path'], $tmpfname) && file_exists($tmpfname)) {
            $args['id']     = $this->file_id();
            $args['path']   = $tmpfname;
            $args['status'] = true;
            @chmod($tmpfname, 0600);  // set correct permissions (#1488996)

            // Note the file for later cleanup
            $_SESSION['plugins']['filesystem_attachments'][$group][$args['id']] = $tmpfname;
        }

        return $args;
    }


Proving logs (after I've added some debugs):

[16-Mar-2018 04:06:46 Europe/Bucharest] debug: Array
(
    [_attachments] => Array
        (
            [name] => Array
                (
                    [0] => IMG-20180315-WA0026.jpg
                )

            [type] => Array
                (
                    [0] => image/jpeg
                )

            [tmp_name] => Array
                (
                    [0] => /var/lib/roundcube/uploads/php9MztBt
                )

            [error] => Array
                (
                    [0] => 0
                )

            [size] => Array
                (
                    [0] => 81506
                )

        )

)

[16-Mar-2018 04:06:46 Europe/Bucharest] debug: i=0 filepath=/var/lib/roundcube/uploads/php9MztBt err=0
[16-Mar-2018 04:06:46 Europe/Bucharest] debug: exec_hook(attachment_upload): i=0, args = Array
(
    [uploaded_full_path] => /var/lib/roundcube/uploads/php9MztBt
    [path] => /var/lib/roundcube/uploads/php9MztBt
    [size] => 81506
    [name] => IMG-20180315-WA0026.jpg
    [mimetype] => image/jpeg
    [group] => 1606078455aab1a19cacae
    [abort] =>
)

[16-Mar-2018 04:06:46 Europe/Bucharest] debug: exec_hook(attachment_upload): i=0, ret = Array
(
    [uploaded_full_path] => /var/lib/roundcube/uploads/php9MztBt
    [path] =>
    [size] => 81506
    [name] => IMG-20180315-WA0026.jpg
    [mimetype] => image/jpeg
    [group] => 1606078455aab1a19cacae
    [abort] =>
    [status] => 1
    [id] => 1606078455aab1a19cacae71e3f4515469c99be6682965159bc06a
)
[16-Mar-2018 04:06:46 Europe/Bucharest] debug: exec_hook(attachment_upload): i=1, args = Array
(
    [uploaded_full_path] => /var/lib/roundcube/uploads/php9MztBt
    [path] =>
    [size] => 81506
    [name] => IMG-20180315-WA0026.jpg
    [mimetype] => image/jpeg
    [group] => 1606078455aab1a19cacae
    [abort] =>
    [status] => 1
    [id] => 1606078455aab1a19cacae71e3f4515469c99be6682965159bc06a
)

[16-Mar-2018 04:06:46 Europe/Bucharest] debug: upload(args= Array
(
    [uploaded_full_path] => /var/lib/roundcube/uploads/php9MztBt
    [path] =>
    [size] => 81506
    [name] => IMG-20180315-WA0026.jpg
    [mimetype] => image/jpeg
    [group] => 1606078455aab1a19cacae
    [abort] =>
    [status] =>
    [id] => 1606078455aab1a19cacae71e3f4515469c99be6682965159bc06a
)
)
[16-Mar-2018 04:06:46 Europe/Bucharest] debug: exec_hook(attachment_upload): i=1, ret = Array
(
    [uploaded_full_path] => /var/lib/roundcube/uploads/php9MztBt
    [path] => /var/lib/roundcube/temp/rcmAttmnt9y92Px
    [size] => 81506
    [name] => IMG-20180315-WA0026.jpg
    [mimetype] => image/jpeg
    [group] => 1606078455aab1a19cacae
    [abort] =>
    [status] => 1
    [id] => 1181521166006064803400
)



P.S.: My Roundcube version is the latest from Ubuntu LTS 16.04: roundcube-1.2~beta+dfsg.1-0ubuntu1.

SKaero

You running a beta version of Roundcube from 2015 I highly recommend that you upgrade because your version is very out of date.

phil2k

#24
Hi SKaero,

Thank you for your answer  8)

Unfortunately the version "1.2~beta+dfsg.1-0ubuntu1" is the latest version offered by the last stable version of Ubuntu LTS sever (16.04)  :(
I know, I have the option to either install the last roundcube version from the sources, or try another new Ubuntu version (non LTS) like 17.10.1 (artful) that comes with rouncube version 1.3.0+dfsg.1-1  ::)
But that server is a production server with hundreds of mailboxes, so I guess I'll have to try the first approach  :-\

P.S.: Good lesson over howto not losing time doing debugging, but rather finding newer versions in the "wild"  :-[

nikitasius

Quote from: phil2k on March 17, 2018, 06:18:29 AM
Hi SKaero,

Thank you for your answer  8)

Unfortunately the version "1.2~beta+dfsg.1-0ubuntu1" is the latest version offered by the last stable version of Ubuntu LTS sever (16.04)  :(
I know, I have the option to either install the last roundcube version from the sources, or try another new Ubuntu version (non LTS) like 17.10.1 (artful) that comes with rouncube version 1.3.0+dfsg.1-1  ::)
But that server is a production server with hundreds of mailboxes, so I guess I'll have to try the first approach  :-\

P.S.: Good lesson over howto not losing time doing debugging, but rather finding newer versions in the "wild"  :-[

I had same problem on my server with attachements.  My solution very simple:

In a config file keep/add in active plugins filesystem_attachments and remove database_attachments (if you had it).
They can't work together and attachements needs at least a filesystem_attachments.
And all will work like a charm :)

I tried all, even setting basedir, and fullfilling upload* php variables. But finally disabling database_attachements let my roundcube work and it doesn't create empty files.

Tested on 1.3.3, 1.3.4 and on actual 1.3.5.