Cereal Killer
Cereal Killer

Reputation: 3414

Where are uploaded file in a deployed Meteor app?

I'm a bit confused about where meteor saves static files (the ones in the /public folder);

I have a method for uploading files:

saveFile: function(blob, name, path, encoding) {        
    if (!Meteor.isServer) return;

    var fs = Npm.require('fs'), 
        chroot = Meteor.chroot || 'public';

    //path = cleanPath(path);
    name = cleanName(name || 'file');
    encoding = encoding || 'binary';

    path = chroot + (path ? '/' + path + '/' : '/');

    var basePath = process.env.PWD;
    var fullPath = basePath + '/' + path + name;
    var dirs = (path.split('/'));
    var currentCreatedPath = basePath;

    //create needed folders
    dirs.forEach(function(dir, index) {
        if (dir.length > 0) {
            currentCreatedPath = currentCreatedPath + '/' + dir;
            if (!fs.existsSync(currentCreatedPath)){
                fs.mkdirSync(currentCreatedPath);
            }
        }
    });

    fs.writeFile(fullPath, blob, encoding, function(err) {
        if (err) console.log(err); //throw (new Meteor.Error(500, 'Failed to save file.', err));
        else console.log('The file ' + fullPath + 'has been saved');
    }); 

    function cleanPath(str) {
        if (str) return str.replace(/\.\./g,'').replace(/\/+/g,'').replace(/^\/+/,'').replace(/\/+$/,'');
    }
    function cleanName(str) {
        return str.replace(/\.\./g,'').replace(/\//g,'');
    }

    return true;
}

Then in the template I reach the file like this:

    {{#each this.files}}
        <li>
            <a href="/{{path}}" target="_blank">
                {{title}}
            </a>
        </li>
    {{/each}}

where path is /public/folder/to/file/file.ext

This works great locally; but once deployed, it is not able to find uploaded files; in which folder of the deployed project does meteor save the files?

Upvotes: 2

Views: 804

Answers (1)

Tarang
Tarang

Reputation: 75955

Its not advised to use this practice. If you deploy your app and have more than one instance or 'drone' running each one will not be able to see each others files.

Its best to use something like s3 to store your files on a 3rd party server due to this.

Anyway If you do decide to store your files on the same machine you just need to use an absolute path outside your meteor project.

If you use the public folder Meteor will restart due to the file change. If you use the bundled asset static folder you will have a bit of trouble finding your files.

Something like this may help (saves on your desktop):

var path = Npm.require("path").resolve("~/Desktop/");

saveFile(blob, name, path, encoding)

To view the files you can have some kind of proxy (if you use iron router):

Server side code (may need some tweaking):

Router.route('/file/:filename', function() {
    var self = this;
    var res = this.response;
    var filename = this.params.filename
    var path = Npm.require("path");
    var fs = Npm.require("fs");

    fs.readFile(path.join(path.resolve("~/Desktop"), filename), function(err, fileContent) {
        if(err) console.log(err);

        self.response.statusCode = 200;
        //self.response.setHeader("Content-Type", response.headers['content-type']);
        self.response.setHeader("Content-disposition", filename);
        self.response.end(fileContent);
    });

}, { where: 'server' });

For simplicity, I've used your Desktop folder (OS X). I'd advise to use another more secure folder.

Then you can use the url http://localhost:3000/file/your_file_name to download it.

Upvotes: 1

Related Questions