plupload module lets us configure the server directory where temporary files will be stored via:

  • plupload_temporary_uri variable in d7.
  • plupload.settings -> temporary_uri config value in d8.
  • In both cases it defaults to temporary:// PHP stream wrapper, but for some values it doesn't work as expected:

  1. A stream wrapper without trailing slash: Specified directory is not used but its parent. File upload works fine.
  2. A stream wrapper with trailing slash: Works as expected.
  3. A directory path without trailing slash: Same as 1.
  4. A directory path with trailing slash: Specified directory is not used but its parent when writing. File upload fails because reading in the child directory.
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

slashrsm’s picture

Cannot reproduce this. You probably have some other problems.

juampynr’s picture

Title: Error in uploads » Error in uploads due to file_prepare_directory() removing forward slashes for non-stream paths
Status: Active » Needs review
FileSize
1.03 KB

The problem is that if variable plupload_temporary_uri has a path instead of a file stream, file_prepare_directory() gets rid of the trailing slash, so when later on the code does fopen(), it fails since there is no slash between $temp_directory and $file_name.

This code in includes/file.inc converts /tmp/ into /tmp. Note that $directory is passed by reference.

function file_prepare_directory(&$directory, $options = FILE_MODIFY_PERMISSIONS) {
  if (!file_stream_wrapper_valid_scheme(file_uri_scheme($directory))) {
    // Only trim if we're not dealing with a stream.
    $directory = rtrim($directory, '/\\');
  }

Attached is a patch that I tested with both a path and a stream wrapper.

vishy_singhal’s picture

@jaumy - That does not work either.

I have tried taking a deeper look at this. The exception message while trying to upload files with 1.png, 2.png, 3.png is the following

'PDOException' with message 'SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'public://uploads/1/2_0.jpg' for key 'uri'' in main/www/includes/database/database.inc:2168

I tried the following method which worked. Modified main/www/includes/database/database.inc line 2168 to

try { $return = parent::execute($args); }
catch(Exception $e) { watchdog("error","Error during upload: ".$e); }

I am not sure if the above is a good way to solve the problem. A very temporary fix that I am not comfortable with.

adammalone’s picture

@vishy_singhal I'm not sure that's the root cause of this issue and certainly not worth modifying database.inc for.

@slashrsm I've been able to repro this on a HA environment using the plupload_temporary_uri to point to an alternate path for plupload files.

File /path/to/temp/filesp187kdg91hfjsik8n941a7b111spq1.tmp could not be copied because it does not exist.

This points to a particular issue within plupload where the slash is removed from the temporary path as juampy says in #2

juampynr’s picture

Here is an updated version where I am fixing another part of the logic which causes the same issue. I will post testing instructions in the next comment.

juampynr’s picture

  1. +++ b/plupload.module
    @@ -190,7 +190,7 @@ function plupload_element_value(&$element, $input = FALSE, $form_state = NULL) {
    +        $files[$i]['tmppath'] = variable_get('plupload_temporary_uri', 'temporary://') . '/' . $value;
    

    This change makes sure that even though plupload_temporary_uri has a values like /tmp (note there is no trailing slash), we do add it in order to build a full path to an uploaded file such as /tmp/foo.jpg.

  2. +++ b/plupload.module
    @@ -378,6 +378,13 @@ function plupload_handle_uploads() {
    +    $temp_directory .= '/';
    

    This change addresses the fact that file_prepare_directory() removes the trailing slash from a path like /tmp/.

juampynr’s picture

Title: Error in uploads due to file_prepare_directory() removing forward slashes for non-stream paths » Cannot upload files when plupload_temporary_uri is not a PHP stream

Oops, used the wrong field to change the title.

vishy_singhal’s picture

Not fixed, Did it work for you?

juampynr’s picture

Yes @vishy_singhal.

vishy_singhal’s picture

@juampy Let me try again with various other combinations

vishy_singhal’s picture

@juampy - rechecking, did you use the same patch as #5 or did you do any other changes?

juampynr’s picture

Issue summary: View changes

@vishy_singhal, yes, I used the patch at #5.

vishy_singhal’s picture

@juampy - The problem still exists. Try doing the following

upload file names 0.jpg, 1.jpg, 2.jpg
Once you have successfully uploaded, try uploading them again.
Expected result - the files should be renamed to 0-1.jpg, 1-1.jpg and so on.
Actual result - Plupload fails to upload throwing php error

@Juampy - have you tried this?

juampynr’s picture

I am sorry @vishy_singhal, I cann't test this issue more. Already had a problem and gave solution to it.

jbloomfield’s picture

This issue still exists in the latest dev and stable releases. I applied the patch from @juampynr from comment #5 and this fixes the issue. Can this patch be applied to the dev release?

leolandotan’s picture

I'm experiencing this issue too and specifically getting the error:

The specified file temporary://jc2m8j3r92h3r98f23rsad.tmp could not be copied, because no file by that name exists. Please check that you supplied the correct filename.

What's weird is that when I try to upload 1 or 2 images, it passes but when I upload like 7 images about 800KB plus I get the said error.

I'm also using Pantheon as my host and the test/staging site is fine while production has the error. Also I checked my temporary directory value and it's formed as /srv/bindings/some-hash-here/tmp so there's not trailing slash.

Any ideas on why this inconsistency is happening?

budalokko’s picture

Version: 7.x-1.3 » 7.x-2.x-dev
Priority: Critical » Major
FileSize
2.49 KB

Patch in #5 by juampynr doesn't work for a plupload_temporary_uri in the form of a PHP stream without a trailing slash like this:

temporary://plupload-temp

While reviewing the patch, I found that current module is not really working as expected in this situation: when plupload_temporary_uri is a PHP stream without a trailing slash.

It works, but the used temp file is not stored in the correct directory: directory and file name are concatenated resulting in things like:

temporary://plupload-tempo_1bc3ntv2s1pknqb316bu15lp14i6a.tmp

This second problem happens exactly in the same piece of code we are talking about so I think they are too related to solve them separately.

Attached patch solves the problem in a consistent way for all kind of value for plupload_temporary_uri:

$conf['plupload_temporary_uri'] = 'temporary://';
$conf['plupload_temporary_uri'] = 'temporary://plupload-temp';
$conf['plupload_temporary_uri'] = 'temporary://plupload-temp/';
$conf['plupload_temporary_uri'] = 'sites/default/files/tmp/plupload-temp';
$conf['plupload_temporary_uri'] = 'sites/default/files/tmp/plupload-temp/';

It could have been solved in the opposite way maybe with a bit less of code, but looking at file_stream_wrapper_uri_normalize and file_prepare_directory it seems uris not having trailing slashes are more aligned with core than having them.

budalokko’s picture

And this is the patch for 8.x-2.x branch, which has exactly the same problem.

Updated issue summary because it doesn't reflect the problem we are currently solving.

dalin’s picture

Confirmed that the patch in #17 works great. I can't comment about D8 though, otherwise I'd mark this RTBC.

steveoriol’s picture

Hello,
For me on D8, I still have links on temporary files, even with patch # 18
I do not know what to try to make the plupload module work :-(

martin.davidson’s picture

#17 works great.