From eb6e518465c5e2a6e3689618938a65a5e672122b Mon Sep 17 00:00:00 2001 From: Guntur Sarwohadi Date: Sat, 12 Oct 2013 09:22:53 +0700 Subject: [PATCH 1/2] Collect formData on 'field' event from form property in UploadHandler.prototype.post method to req.fields object (created new object if undefined). Extend fileInfo with req.fields on 'end' event. --- lib/uploadhandler.js | 360 ++++++++++++++++++++++--------------------- 1 file changed, 182 insertions(+), 178 deletions(-) diff --git a/lib/uploadhandler.js b/lib/uploadhandler.js index ece4b55..05f60ba 100644 --- a/lib/uploadhandler.js +++ b/lib/uploadhandler.js @@ -1,184 +1,188 @@ var EventEmitter = require('events').EventEmitter, - path = require('path'), - fs = require('fs'), - formidable = require('formidable'), - imageMagick = require('imagemagick'), - mkdirp = require('mkdirp'), - _ = require('lodash'); + path = require('path'), + fs = require('fs'), + formidable = require('formidable'), + imageMagick = require('imagemagick'), + mkdirp = require('mkdirp'), + _ = require('lodash'); module.exports = function (options) { - var FileInfo = require('./fileinfo')( - _.extend({ - baseDir: options.uploadDir - }, _.pick(options, 'minFileSize', 'maxFileSize', 'acceptFileTypes')) - ); - - var UploadHandler = function (req, res, callback) { - EventEmitter.call(this); - this.req = req; - this.res = res; - this.callback = callback; - }; - require('util').inherits(UploadHandler, EventEmitter); - - UploadHandler.prototype.noCache = function () { - this.res.set({ - 'Pragma': 'no-cache', - 'Cache-Control': 'no-store, no-cache, must-revalidate', - 'Content-Disposition': 'inline; filename="files.json"' - }); - }; - - UploadHandler.prototype.get = function () { - this.noCache(); - var files = []; - fs.readdir(options.uploadDir(), _.bind(function (err, list) { - _.each(list, function (name) { - var stats = fs.statSync(options.uploadDir() + '/' + name), - fileInfo; - if (stats.isFile()) { - fileInfo = new FileInfo({ - name: name, - size: stats.size - }); - this.initUrls(fileInfo); - files.push(fileInfo); - } - }, this); - this.callback({files: files}); - }, this)); - }; - - UploadHandler.prototype.post = function () { - var self = this, - form = new formidable.IncomingForm(), - tmpFiles = [], - files = [], - map = {}, - counter = 1, - redirect, - finish = _.bind(function () { - if (!--counter) { - _.each(files, function (fileInfo) { - this.initUrls(fileInfo); - this.emit('end', fileInfo); - }, this); - this.callback({files: files}, redirect); - } - }, this); - - this.noCache(); - - form.uploadDir = options.tmpDir; - form - .on('fileBegin', function (name, file) { - tmpFiles.push(file.path); - var fileInfo = new FileInfo(file); - fileInfo.safeName(); - map[path.basename(file.path)] = fileInfo; - files.push(fileInfo); - self.emit('begin', fileInfo); - }) - .on('field', function (name, value) { - if (name === 'redirect') { - redirect = value; - } - }) - .on('file', function (name, file) { - var fileInfo = map[path.basename(file.path)]; - if (fs.existsSync(file.path)) { - fileInfo.size = file.size; - if (!fileInfo.validate()) { - fs.unlink(file.path); - return; - } - - var generatePreviews = function () { - if (options.imageTypes.test(fileInfo.name)) { - _.each(options.imageVersions, function (value, version) { - // creating directory recursive - if (!fs.existsSync(options.uploadDir() + '/' + version + '/')) - mkdirp.sync(options.uploadDir() + '/' + version + '/'); - - counter++; - var opts = options.imageVersions[version]; - imageMagick.resize({ - width: opts.width, - height: opts.height, - srcPath: options.uploadDir() + '/' + fileInfo.name, - dstPath: options.uploadDir() + '/' + version + '/' + fileInfo.name, - customArgs: opts.imageArgs || ['-auto-orient'] - }, finish); - }); - } - } - - if (!fs.existsSync(options.uploadDir() + '/')) - mkdirp.sync(options.uploadDir() + '/'); - - counter++; - fs.rename(file.path, options.uploadDir() + '/' + fileInfo.name, function (err) { - if (!err) { - generatePreviews(); - finish(); - } else { - var is = fs.createReadStream(file.path); - var os = fs.createWriteStream(options.uploadDir() + '/' + fileInfo.name); - is.on('end', function (err) { - if (!err) { - fs.unlinkSync(file.path); - generatePreviews(); - } - finish(); - }); - is.pipe(os); - } - }); - } - }) - .on('aborted', function () { - _.each(tmpFiles, function (file) { - var fileInfo = map[path.basename(file)]; - self.emit('abort', fileInfo); - fs.unlink(file); - }); - }) - .on('error', function (e) { - self.emit('error', e); - }) - .on('progress', function (bytesReceived, bytesExpected) { - if (bytesReceived > options.maxPostSize) - self.req.connection.destroy(); - }) - .on('end', finish) - .parse(self.req); - }; - - UploadHandler.prototype.destroy = function () { - var self = this, - fileName = path.basename(decodeURIComponent(this.req.url)); - - fs.unlink(options.uploadDir() + '/' + fileName, function (ex) { - _.each(options.imageVersions, function (value, version) { - fs.unlink(options.uploadDir() + '/' + version + '/' + fileName); - }); - self.emit('delete', fileName); - self.callback({success: !ex}); - }); - }; - - UploadHandler.prototype.initUrls = function (fileInfo) { - var baseUrl = (options.ssl ? 'https:' : 'http:') + '//' + (options.hostname || this.req.get('Host')); - fileInfo.setUrl(null, baseUrl + options.uploadUrl()); - fileInfo.setUrl('delete', baseUrl + this.req.originalUrl); - _.each(options.imageVersions, function (value, version) { - if (fs.existsSync(options.uploadDir() + '/' + version + '/' + fileInfo.name)) { - fileInfo.setUrl(version, baseUrl + options.uploadUrl() + '/' + version); - } - }, this); - }; - - return UploadHandler; + var FileInfo = require('./fileinfo')( + _.extend({ + baseDir: options.uploadDir + }, _.pick(options, 'minFileSize', 'maxFileSize', 'acceptFileTypes')) + ); + + var UploadHandler = function (req, res, callback) { + EventEmitter.call(this); + this.req = req; + this.res = res; + this.callback = callback; + }; + require('util').inherits(UploadHandler, EventEmitter); + + UploadHandler.prototype.noCache = function () { + this.res.set({ + 'Pragma': 'no-cache', + 'Cache-Control': 'no-store, no-cache, must-revalidate', + 'Content-Disposition': 'inline; filename="files.json"' + }); + }; + + UploadHandler.prototype.get = function () { + this.noCache(); + var files = []; + fs.readdir(options.uploadDir(), _.bind(function (err, list) { + _.each(list, function (name) { + var stats = fs.statSync(options.uploadDir() + '/' + name), + fileInfo; + if (stats.isFile()) { + fileInfo = new FileInfo({ + name: name, + size: stats.size + }); + this.initUrls(fileInfo); + files.push(fileInfo); + } + }, this); + this.callback({files: files}); + }, this)); + }; + + UploadHandler.prototype.post = function () { + var self = this, + form = new formidable.IncomingForm(), + tmpFiles = [], + files = [], + map = {}, + counter = 1, + redirect, + finish = _.bind(function () { + if (!--counter) { + _.each(files, function (fileInfo) { + this.initUrls(fileInfo); + fileInfo = _.extend(fileInfo, self.req.fields); + this.emit('end', fileInfo); + }, this); + this.callback({files: files}, redirect); + } + }, this); + + this.noCache(); + + form.uploadDir = options.tmpDir; + form + .on('fileBegin', function (name, file) { + tmpFiles.push(file.path); + var fileInfo = new FileInfo(file); + fileInfo.safeName(); + map[path.basename(file.path)] = fileInfo; + files.push(fileInfo); + self.emit('begin', fileInfo); + }) + .on('field', function (name, value) { + if (name === 'redirect') { + redirect = value; + } + if ( !self.req.fields ) + self.req.fields = {}; + self.req.fields[name] = value; + }) + .on('file', function (name, file) { + var fileInfo = map[path.basename(file.path)]; + if (fs.existsSync(file.path)) { + fileInfo.size = file.size; + if (!fileInfo.validate()) { + fs.unlink(file.path); + return; + } + + var generatePreviews = function () { + if (options.imageTypes.test(fileInfo.name)) { + _.each(options.imageVersions, function (value, version) { + // creating directory recursive + if (!fs.existsSync(options.uploadDir() + '/' + version + '/')) + mkdirp.sync(options.uploadDir() + '/' + version + '/'); + + counter++; + var opts = options.imageVersions[version]; + imageMagick.resize({ + width: opts.width, + height: opts.height, + srcPath: options.uploadDir() + '/' + fileInfo.name, + dstPath: options.uploadDir() + '/' + version + '/' + fileInfo.name, + customArgs: opts.imageArgs || ['-auto-orient'] + }, finish); + }); + } + } + + if (!fs.existsSync(options.uploadDir() + '/')) + mkdirp.sync(options.uploadDir() + '/'); + + counter++; + fs.rename(file.path, options.uploadDir() + '/' + fileInfo.name, function (err) { + if (!err) { + generatePreviews(); + finish(); + } else { + var is = fs.createReadStream(file.path); + var os = fs.createWriteStream(options.uploadDir() + '/' + fileInfo.name); + is.on('end', function (err) { + if (!err) { + fs.unlinkSync(file.path); + generatePreviews(); + } + finish(); + }); + is.pipe(os); + } + }); + } + }) + .on('aborted', function () { + _.each(tmpFiles, function (file) { + var fileInfo = map[path.basename(file)]; + self.emit('abort', fileInfo); + fs.unlink(file); + }); + }) + .on('error', function (e) { + self.emit('error', e); + }) + .on('progress', function (bytesReceived, bytesExpected) { + if (bytesReceived > options.maxPostSize) + self.req.connection.destroy(); + }) + .on('end', finish) + .parse(self.req); + }; + + UploadHandler.prototype.destroy = function () { + var self = this, + fileName = path.basename(decodeURIComponent(this.req.url)); + + fs.unlink(options.uploadDir() + '/' + fileName, function (ex) { + _.each(options.imageVersions, function (value, version) { + fs.unlink(options.uploadDir() + '/' + version + '/' + fileName); + }); + self.emit('delete', fileName); + self.callback({success: !ex}); + }); + }; + + UploadHandler.prototype.initUrls = function (fileInfo) { + var baseUrl = (options.ssl ? 'https:' : 'http:') + '//' + (options.hostname || this.req.get('Host')); + fileInfo.setUrl(null, baseUrl + options.uploadUrl()); + fileInfo.setUrl('delete', baseUrl + this.req.originalUrl); + _.each(options.imageVersions, function (value, version) { + if (fs.existsSync(options.uploadDir() + '/' + version + '/' + fileInfo.name)) { + fileInfo.setUrl(version, baseUrl + options.uploadUrl() + '/' + version); + } + }, this); + }; + + return UploadHandler; } From 83668f56623a99f0e781622e7d68f5d9f4b165b4 Mon Sep 17 00:00:00 2001 From: Guntur Sarwohadi Date: Sat, 12 Oct 2013 11:37:36 +0700 Subject: [PATCH 2/2] Collect formData on 'field' event from form property in UploadHandler.prototype.post method to req.fields object (created new object if undefined). Extend fileInfo with req.fields on 'end' event. --- lib/uploadhandler.js | 364 +++++++++++++++++++++---------------------- 1 file changed, 182 insertions(+), 182 deletions(-) diff --git a/lib/uploadhandler.js b/lib/uploadhandler.js index 05f60ba..6099e58 100644 --- a/lib/uploadhandler.js +++ b/lib/uploadhandler.js @@ -1,188 +1,188 @@ var EventEmitter = require('events').EventEmitter, - path = require('path'), - fs = require('fs'), - formidable = require('formidable'), - imageMagick = require('imagemagick'), - mkdirp = require('mkdirp'), - _ = require('lodash'); + path = require('path'), + fs = require('fs'), + formidable = require('formidable'), + imageMagick = require('imagemagick'), + mkdirp = require('mkdirp'), + _ = require('lodash'); module.exports = function (options) { - var FileInfo = require('./fileinfo')( - _.extend({ - baseDir: options.uploadDir - }, _.pick(options, 'minFileSize', 'maxFileSize', 'acceptFileTypes')) - ); - - var UploadHandler = function (req, res, callback) { - EventEmitter.call(this); - this.req = req; - this.res = res; - this.callback = callback; - }; - require('util').inherits(UploadHandler, EventEmitter); - - UploadHandler.prototype.noCache = function () { - this.res.set({ - 'Pragma': 'no-cache', - 'Cache-Control': 'no-store, no-cache, must-revalidate', - 'Content-Disposition': 'inline; filename="files.json"' - }); - }; - - UploadHandler.prototype.get = function () { - this.noCache(); - var files = []; - fs.readdir(options.uploadDir(), _.bind(function (err, list) { - _.each(list, function (name) { - var stats = fs.statSync(options.uploadDir() + '/' + name), - fileInfo; - if (stats.isFile()) { - fileInfo = new FileInfo({ - name: name, - size: stats.size - }); - this.initUrls(fileInfo); - files.push(fileInfo); - } - }, this); - this.callback({files: files}); - }, this)); - }; - - UploadHandler.prototype.post = function () { - var self = this, - form = new formidable.IncomingForm(), - tmpFiles = [], - files = [], - map = {}, - counter = 1, - redirect, - finish = _.bind(function () { - if (!--counter) { - _.each(files, function (fileInfo) { - this.initUrls(fileInfo); - fileInfo = _.extend(fileInfo, self.req.fields); - this.emit('end', fileInfo); - }, this); - this.callback({files: files}, redirect); - } - }, this); - - this.noCache(); - - form.uploadDir = options.tmpDir; - form - .on('fileBegin', function (name, file) { - tmpFiles.push(file.path); - var fileInfo = new FileInfo(file); - fileInfo.safeName(); - map[path.basename(file.path)] = fileInfo; - files.push(fileInfo); - self.emit('begin', fileInfo); - }) - .on('field', function (name, value) { - if (name === 'redirect') { - redirect = value; - } - if ( !self.req.fields ) - self.req.fields = {}; - self.req.fields[name] = value; - }) - .on('file', function (name, file) { - var fileInfo = map[path.basename(file.path)]; - if (fs.existsSync(file.path)) { - fileInfo.size = file.size; - if (!fileInfo.validate()) { - fs.unlink(file.path); - return; - } - - var generatePreviews = function () { - if (options.imageTypes.test(fileInfo.name)) { - _.each(options.imageVersions, function (value, version) { - // creating directory recursive - if (!fs.existsSync(options.uploadDir() + '/' + version + '/')) - mkdirp.sync(options.uploadDir() + '/' + version + '/'); - - counter++; - var opts = options.imageVersions[version]; - imageMagick.resize({ - width: opts.width, - height: opts.height, - srcPath: options.uploadDir() + '/' + fileInfo.name, - dstPath: options.uploadDir() + '/' + version + '/' + fileInfo.name, - customArgs: opts.imageArgs || ['-auto-orient'] - }, finish); - }); - } - } - - if (!fs.existsSync(options.uploadDir() + '/')) - mkdirp.sync(options.uploadDir() + '/'); - - counter++; - fs.rename(file.path, options.uploadDir() + '/' + fileInfo.name, function (err) { - if (!err) { - generatePreviews(); - finish(); - } else { - var is = fs.createReadStream(file.path); - var os = fs.createWriteStream(options.uploadDir() + '/' + fileInfo.name); - is.on('end', function (err) { - if (!err) { - fs.unlinkSync(file.path); - generatePreviews(); - } - finish(); - }); - is.pipe(os); - } - }); - } - }) - .on('aborted', function () { - _.each(tmpFiles, function (file) { - var fileInfo = map[path.basename(file)]; - self.emit('abort', fileInfo); - fs.unlink(file); - }); - }) - .on('error', function (e) { - self.emit('error', e); - }) - .on('progress', function (bytesReceived, bytesExpected) { - if (bytesReceived > options.maxPostSize) - self.req.connection.destroy(); - }) - .on('end', finish) - .parse(self.req); - }; - - UploadHandler.prototype.destroy = function () { - var self = this, - fileName = path.basename(decodeURIComponent(this.req.url)); - - fs.unlink(options.uploadDir() + '/' + fileName, function (ex) { - _.each(options.imageVersions, function (value, version) { - fs.unlink(options.uploadDir() + '/' + version + '/' + fileName); - }); - self.emit('delete', fileName); - self.callback({success: !ex}); - }); - }; - - UploadHandler.prototype.initUrls = function (fileInfo) { - var baseUrl = (options.ssl ? 'https:' : 'http:') + '//' + (options.hostname || this.req.get('Host')); - fileInfo.setUrl(null, baseUrl + options.uploadUrl()); - fileInfo.setUrl('delete', baseUrl + this.req.originalUrl); - _.each(options.imageVersions, function (value, version) { - if (fs.existsSync(options.uploadDir() + '/' + version + '/' + fileInfo.name)) { - fileInfo.setUrl(version, baseUrl + options.uploadUrl() + '/' + version); - } - }, this); - }; - - return UploadHandler; + var FileInfo = require('./fileinfo')( + _.extend({ + baseDir: options.uploadDir + }, _.pick(options, 'minFileSize', 'maxFileSize', 'acceptFileTypes')) + ); + + var UploadHandler = function (req, res, callback) { + EventEmitter.call(this); + this.req = req; + this.res = res; + this.callback = callback; + }; + require('util').inherits(UploadHandler, EventEmitter); + + UploadHandler.prototype.noCache = function () { + this.res.set({ + 'Pragma': 'no-cache', + 'Cache-Control': 'no-store, no-cache, must-revalidate', + 'Content-Disposition': 'inline; filename="files.json"' + }); + }; + + UploadHandler.prototype.get = function () { + this.noCache(); + var files = []; + fs.readdir(options.uploadDir(), _.bind(function (err, list) { + _.each(list, function (name) { + var stats = fs.statSync(options.uploadDir() + '/' + name), + fileInfo; + if (stats.isFile()) { + fileInfo = new FileInfo({ + name: name, + size: stats.size + }); + this.initUrls(fileInfo); + files.push(fileInfo); + } + }, this); + this.callback({files: files}); + }, this)); + }; + + UploadHandler.prototype.post = function () { + var self = this, + form = new formidable.IncomingForm(), + tmpFiles = [], + files = [], + map = {}, + counter = 1, + redirect, + finish = _.bind(function () { + if (!--counter) { + _.each(files, function (fileInfo) { + this.initUrls(fileInfo); + fileInfo = _.extend(fileInfo, self.req.fields); + this.emit('end', fileInfo); + }, this); + this.callback({files: files}, redirect); + } + }, this); + + this.noCache(); + + form.uploadDir = options.tmpDir; + form + .on('fileBegin', function (name, file) { + tmpFiles.push(file.path); + var fileInfo = new FileInfo(file); + fileInfo.safeName(); + map[path.basename(file.path)] = fileInfo; + files.push(fileInfo); + self.emit('begin', fileInfo); + }) + .on('field', function (name, value) { + if (name === 'redirect') { + redirect = value; + } + if ( !self.req.fields ) + self.req.fields = {}; + self.req.fields[name] = value; + }) + .on('file', function (name, file) { + var fileInfo = map[path.basename(file.path)]; + if (fs.existsSync(file.path)) { + fileInfo.size = file.size; + if (!fileInfo.validate()) { + fs.unlink(file.path); + return; + } + + var generatePreviews = function () { + if (options.imageTypes.test(fileInfo.name)) { + _.each(options.imageVersions, function (value, version) { + // creating directory recursive + if (!fs.existsSync(options.uploadDir() + '/' + version + '/')) + mkdirp.sync(options.uploadDir() + '/' + version + '/'); + + counter++; + var opts = options.imageVersions[version]; + imageMagick.resize({ + width: opts.width, + height: opts.height, + srcPath: options.uploadDir() + '/' + fileInfo.name, + dstPath: options.uploadDir() + '/' + version + '/' + fileInfo.name, + customArgs: opts.imageArgs || ['-auto-orient'] + }, finish); + }); + } + } + + if (!fs.existsSync(options.uploadDir() + '/')) + mkdirp.sync(options.uploadDir() + '/'); + + counter++; + fs.rename(file.path, options.uploadDir() + '/' + fileInfo.name, function (err) { + if (!err) { + generatePreviews(); + finish(); + } else { + var is = fs.createReadStream(file.path); + var os = fs.createWriteStream(options.uploadDir() + '/' + fileInfo.name); + is.on('end', function (err) { + if (!err) { + fs.unlinkSync(file.path); + generatePreviews(); + } + finish(); + }); + is.pipe(os); + } + }); + } + }) + .on('aborted', function () { + _.each(tmpFiles, function (file) { + var fileInfo = map[path.basename(file)]; + self.emit('abort', fileInfo); + fs.unlink(file); + }); + }) + .on('error', function (e) { + self.emit('error', e); + }) + .on('progress', function (bytesReceived, bytesExpected) { + if (bytesReceived > options.maxPostSize) + self.req.connection.destroy(); + }) + .on('end', finish) + .parse(self.req); + }; + + UploadHandler.prototype.destroy = function () { + var self = this, + fileName = path.basename(decodeURIComponent(this.req.url)); + + fs.unlink(options.uploadDir() + '/' + fileName, function (ex) { + _.each(options.imageVersions, function (value, version) { + fs.unlink(options.uploadDir() + '/' + version + '/' + fileName); + }); + self.emit('delete', fileName); + self.callback({success: !ex}); + }); + }; + + UploadHandler.prototype.initUrls = function (fileInfo) { + var baseUrl = (options.ssl ? 'https:' : 'http:') + '//' + (options.hostname || this.req.get('Host')); + fileInfo.setUrl(null, baseUrl + options.uploadUrl()); + fileInfo.setUrl('delete', baseUrl + this.req.originalUrl); + _.each(options.imageVersions, function (value, version) { + if (fs.existsSync(options.uploadDir() + '/' + version + '/' + fileInfo.name)) { + fileInfo.setUrl(version, baseUrl + options.uploadUrl() + '/' + version); + } + }, this); + }; + + return UploadHandler; }