Jump to content

Recommended Posts

Posted

Hi,

I am trying to use wire tempDir (/site/assets/cache/WireTempDir) to store temporary files for users to download.

The idea is that the files are created on request, they exist for a few hours till the download is over and then the folder is cleaned automatically.

Based on some useful posts I found in the forum I am able to create the files on demand using the following lines:

$wire_temp_dir = $files->tempDir('temp_downloads');
$wire_temp_dir->setRemove(false);
$temp_path = (string)$wire_temp_dir;;
$zip = $temp_path . "test.zip";
$result_zip = $files->zip($zip, $files_array);

The problem comes when I try to download the file from the website. I get the infamous error:

Forbidden You don't have permission to access this resource.

I am not able to reach the files from the website and I don't understand why. Permissions to the folder are correct (I created a test folder under assets with the same permissions as cache and I can reach the files there). I am using apache2.

I searched a lot before posting this but I am currently out of ideas. Keep in mind I am quiet new to web development and processwire.

 

Lastly, I have an additional error: I notice the files are not eliminated after the default 120 seconds specified in the docs.

Thanks in advance!

Fede

 

Posted

To be honest I've never really understood the maxage setting ?

I tried to understand how it works again... but didn't. But I've found this working solution:

$td = $files->tempDir('hello-world');
$td->setRemove(false);
$td->removeExpiredDirs(dirname($td), 10); // remove dirs older than 10 seconds
file_put_contents($td.'some-file.txt', 'Hello world');

Fire that from the tracy console several times and you'll see that on each request a new dir is created and also old dirs are removed.

14 hours ago, fedeb said:

Forbidden You don't have permission to access this resource.

That's because you can't access files in a hidden folder! You'd need to write your own custom logic to include() the content of this file and show that on a custom url (maybe using the new url hooks). But the problem is that you have to keep track of the exact file/folder name of your temporary file. And another problem is, that you can end up with security problems, because the file content of a file can change over time whereas the link to that file could still be the one from an earlier version of another file.

eg

create temp file --> .../0/yourfile.txt
create another --> .../1/yourfile.txt
create another --> .../0/yourfile.txt (because the old file in folder 0 does not exist any more because it was too old and was removed)

Now you got 2 links: yoursite.com/tempfile0 and yoursite.com/tempfile1 and tempfile0 will show different files depending on WHEN the link is clicked. I guess that's not a good idea ? 

I'll open an issue regarding the tempDir though. https://github.com/processwire/processwire-issues/issues/1356

  • Like 1
Posted

Hi!

I just tried out your solution and it worked perfectly! Thanks a lot for the quick reply and the amazing explanation!

Quote

But the problem is that you have to keep track of the exact file/folder name of your temporary file. And another problem is, that you can end up with security problems, because the file content of a file can change over time whereas the link to that file could still be the one from an earlier version of another file.

Since I am creating temporary files on demand for download I think I don't have a big security issue nor I need to track the files, right?

Basically there is a link to a download.php which triggers the download of the file. There is no visible link to that file.

I include the download.php code just to close the thread properly. It is probably not the best code so if there something I should change please let me know.

// create temp dir
$temp_dir = $files->tempDir('downloads');
$temp_dir->setRemove(false);
$temp_dir->removeExpiredDirs(dirname($temp_dir), $config->erase_tmpfiles); // remove dirs older than $config->erase_tmpfiles seconds

// create zip
$zip_file = $temp_dir . "test.zip";
$result_zip = $files->zip($zip_file, $data);

// download pop-up
if (headers_sent()) {
    echo 'HTTP header already sent';
} else {
    if (!is_file($zip_file)) {
        header($_SERVER['SERVER_PROTOCOL'].' 404 Not Found');
        echo 'File not found';
    } else if (!is_readable($zip_file)) {
        header($_SERVER['SERVER_PROTOCOL'].' 403 Forbidden');
        echo 'File not readable';
    } else {
        header($_SERVER['SERVER_PROTOCOL'].' 200 OK');
        header("Content-Type: application/zip");
        header("Content-Transfer-Encoding: Binary");
        header("Content-Length: ".filesize($zip_file));
        header("Content-Disposition: attachment; filename=\"".basename($zip_file)."\"");
        readfile($zip_file);
        exit;
    }
}

 

  • Like 2
  • fedeb changed the title to [solved] Using WireTempDir

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...