Skip to content

Instantly share code, notes, and snippets.

@boostbob
Forked from dariocravero/README.md
Created July 25, 2017 03:22

Revisions

  1. Darío Javier Cravero created this gist Oct 20, 2012.
    1 change: 1 addition & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    Create a Meteor app and put the client_/server_ files in a client/server directories. Also, create a public dir to save the uploaded files.
    7 changes: 7 additions & 0 deletions client_example.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,7 @@
    Template.example.events({
    'change input': function(ev) {
    _.each(ev.srcElement.files, function(file) {
    Meteor.saveFile(file, file.name);
    });
    }
    });
    3 changes: 3 additions & 0 deletions client_example.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,3 @@
    <template name="example">
    <input type=file />
    </template>
    31 changes: 31 additions & 0 deletions client_save_file.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,31 @@
    /**
    * @blob (https://developer.mozilla.org/en-US/docs/DOM/Blob)
    * @name the file's name
    * @type the file's type: binary, text (https://developer.mozilla.org/en-US/docs/DOM/FileReader#Methods)
    *
    * TODO Support other encodings: https://developer.mozilla.org/en-US/docs/DOM/FileReader#Methods
    * ArrayBuffer / DataURL (base64)
    */
    Meteor.saveFile = function(blob, name, path, type, callback) {
    var fileReader = new FileReader(),
    method, encoding = 'binary', type = type || 'binary';
    switch (type) {
    case 'text':
    // TODO Is this needed? If we're uploading content from file, yes, but if it's from an input/textarea I think not...
    method = 'readAsText';
    encoding = 'utf8';
    break;
    case 'binary':
    method = 'readAsBinaryString';
    encoding = 'binary';
    break;
    default:
    method = 'readAsBinaryString';
    encoding = 'binary';
    break;
    }
    fileReader.onload = function(file) {
    Meteor.call('saveFile', file.srcElement.result, name, path, encoding, callback);
    }
    fileReader[method](blob);
    }
    34 changes: 34 additions & 0 deletions server_save_file.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,34 @@
    /**
    * TODO support other encodings:
    * http://stackoverflow.com/questions/7329128/how-to-write-binary-data-to-a-file-using-node-js
    */
    Meteor.methods({
    saveFile: function(blob, name, path, encoding) {
    var path = cleanPath(path), fs = __meteor_bootstrap__.require('fs'),
    name = cleanName(name || 'file'), encoding = encoding || 'binary',
    chroot = Meteor.chroot || 'public';
    // Clean up the path. Remove any initial and final '/' -we prefix them-,
    // any sort of attempt to go to the parent directory '..' and any empty directories in
    // between '/////' - which may happen after removing '..'
    path = chroot + (path ? '/' + path + '/' : '/');

    // TODO Add file existance checks, etc...
    fs.writeFile(path + name, blob, encoding, function(err) {
    if (err) {
    throw (new Meteor.Error(500, 'Failed to save file.', err));
    } else {
    console.log('The file ' + name + ' (' + encoding + ') was saved to ' + path);
    }
    });

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