Jump to content

[solved] Using WireTempDir


fedeb
 Share

Recommended Posts

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

 

Link to comment
Share on other sites

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
Link to comment
Share on other sites

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
Link to comment
Share on other sites

  • 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
 Share

  • Recently Browsing   0 members

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