Created
May 14, 2013 22:48
-
-
Save der-On/5580296 to your computer and use it in GitHub Desktop.
node.js uploader based on "formidable"
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var formidable = require('formidable'); | |
var path = require('path'); | |
var fs = require('fs'); | |
var UploaderException = function(message) | |
{ | |
this.message = message; | |
this.toString = function() | |
{ | |
return 'Uploader error: '+this.message; | |
} | |
} | |
/** | |
* @class Uploader | |
* @static | |
*/ | |
var Uploader = { | |
MSG_ERROR_NO_FIELD_NAME: 'Missing option "fieldNames".', | |
MSG_ERROR_NO_FIELE_NAMES: 'Option keepFileNames is set to false, but no fileNames are given.', | |
MSG_ERROR_NO_DEST: 'Missing option "dest".', | |
MSG_ERROR_WRONG_METHDO: 'Request method is not POST', | |
/** | |
* @method upload | |
* @param {Http.ServerRequest} req | |
* @param {Object} options | |
* @param {Function} callback(err, {Array} fields, {Array} files) | |
* | |
* Available options: | |
* | |
* - tempDir: (default=false) temp directory for uploads, if false the systems temp dir will be used | |
* - dest: Destination directory for the uploaded files. | |
* - fieldNames: Array of file field names in the form to upload | |
* - keepFileNames: (default=true) true | false, if true will keep the original file names, if false you must specifify the fileNames | |
* - fileNames: (default=null) Array of new file names for the uploaded files. Use the same order as in fieldNames. | |
*/ | |
upload: function(req, options, callback) | |
{ | |
var self = this; | |
var err = false; | |
var files = []; | |
var valid = true; | |
var options = { | |
tempDir: options.tempDir || false, // temp directory for uploads | |
fieldNames: options.fieldNames || null, // names of the file fields in the form | |
keepFileNames: options.keepFileNames || true, // keep the original file name | |
fileNames: options.fileNames || null, // if keepFilename = false, provide new file names | |
dest: options.dest || null, // destination directory where to move the uploaded file, | |
validator: options.validator || null // a file validation function that gets called for each file and must return true if the file passes validation and should be uploaded or false if not. | |
}; | |
if (!options.fieldNames) err = new UploaderException(Uploader.MSG_ERROR_NO_FIELD_NAME); | |
if (!options.dest) err = new UploaderException(Uploader.MSG_ERROR_NO_DEST); | |
if (!options.keepFileNames && !options.fileNames) err = new new UploaderException(Uploader.MSG_ERROR_NO_FILE_NAMES); | |
if (req.method.toLowerCase() != 'post') err = new UploaderException(Uploader.MSG_ERROR_WRONG_METHOD); | |
if (!err) { | |
req.pause(); | |
req.resume(); | |
var formOpts = { | |
keepExtensions: true | |
}; | |
if (options.tempDir) { | |
formOpts.uploadDir = options.tempDir; | |
} | |
var form = new formidable.IncomingForm(formOpts); | |
form.parse(req,function onFormParsed(formErr, formFields, formFiles) { | |
if (err) { | |
if (callback) callback(err, null, null); | |
} else { | |
options.fieldNames.forEach(function processFileFields(fieldName,i){ | |
if (fieldName in formFiles && formFiles[fieldName].path && formFiles[fieldName].name != null && formFiles[fieldName].name != '') { | |
var formFile = formFiles[fieldName]; | |
if (typeof options.validator == 'function') { | |
valid = options.validator(formFile); | |
} else { | |
valid = true; | |
} | |
if (valid) { | |
var fileName = (options.keepFileNames) ? formFile.name : options.fileNames[i]; | |
var filePath = path.join(options.dest,fileName); | |
self.moveUploadedFile(formFile.path, filePath); | |
files.push(filePath); | |
} | |
} | |
}); | |
if (callback) callback(false, formFields, files); | |
} | |
}); | |
} else { | |
if (callback) callback(err, null, null); | |
} | |
}, | |
moveUploadedFile: function(src,dest) | |
{ | |
var dir = path.dirname(dest); | |
// create directory if not existing yet | |
if (!fs.existsSync(dir)) { | |
fs.mkdirSync(dir,0755); | |
} | |
fs.renameSync(src,dest); | |
} | |
}; | |
module.exports = Uploader; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment