Create a temporary file in /public

Hi,

I need to create temporary files in the /public folder.
Why? I need to generate small static .html snippets to avoid to call database every time when user refresh the page.

I made this code:

Meteor.startup(() => {

if (Meteor.isServer) {

    const fs = require('fs');

    Meteor.methods({

        generateFile() {

            const fileName = 'denis.txt';

            let datapath = process.env.PWD + '/public/files/' + fileName;

            if (Meteor.settings.environment === 'production') { 
                let meteorRoot = fs.realpathSync( process.cwd() + '/../' );
                let publicPath = meteorRoot + '/web.browser/app/files/';
                datapath = publicPath + fileName;
            }

            fs.writeFile(datapath, 'JUST SIMPLE TEXT', 
                function (err) {
                    if (err) {
                        throw err;
                    }
                    console.log('Done!');
                }
            );
        }
    });
}
});

So I created a forlder in /public/files.

On localhost it woks perfect. I can access the file like http://localhost:4000/files/denis.txt

On Galaxy hosting I see that it works and I get ‘Done!’ response in the log.

But when I try to get in touch the file like www.mysite.com/files/denis.txt It cannot be found there.

Any ideas how to solve it? Thanks! :slight_smile:

  • /public is not suitable for temporary files
  • you could use a mongo-collection for cached content, i don’t think you should try to avoid the database call unless you really have a performance problem with it
  • generally i would avoid the filesystem. In particular if you deploy to cloud infrastructure.
  • if you really really want a filesystem cache, then you will have to provide an env-variable to a path where you can write files. Also you need to create a webhandler that will serve your file, if you need to access it from outside
  • be extra careful if you concatinate file system paths, so that its not possible to craft a request that can be resolved to an arbitrary file path. Either you will enable attackers to overwrite files on your filesystem or they are able to read arbitrary files. Both is really bad
  • Bottom line: avoid the filesystem.

by the way: Meteor.settings.environment === ‘production’ --> Meteor.isProduction, no need to use settings.json for that

4 Likes

Thank you @macrozone! It was a good and complete answer!

I will go for:

:slight_smile:

1 Like

I would use the standard tools for stuff like this. Nginx is great as a cache, reverse-proxy, and load balancer. You could also use a CDN like cloudflare or cloudfront