diff --git a/.gitignore b/.gitignore index 40b878d..0ca9404 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,25 @@ -node_modules/ \ No newline at end of file +### intellij ### +*.iml +*.ipr +*.iws +.idea/ + +### node ### +lib-cov +*.seed +*.log +*.csv +*.dat +*.out +*.pid +*.gz + +pids +logs +results + +npm-debug.log +node_modules + +### example ### +public/lib/ \ No newline at end of file diff --git a/History.md b/History.md index b47f606..8a03709 100644 --- a/History.md +++ b/History.md @@ -1,3 +1,49 @@ +0.1.7 / 2014-10-09 +================== + + * #58 improved support for IE9 + +0.1.6 / 2014-10-04 +================== + + * #56 avoid path traversal in DELETE requests + +0.1.5 / 2014-08-02 +================== + + * #31 request and response objects passed to event handlers + +0.1.4 / 2014-07-06 +================== + + * #53 documentation update + +0.1.3 / 2014-07-05 +================== + + * #46 merged in (reduce synchronous disk IO operations) + +0.1.2 / 2014-06-08 +================== + + * #31 merged in + +0.1.1 / 2014-02-04 +================== + + * #5 fixed + +0.1.0 / 2013-10-07 +================== + + * documentation cleanup + + +0.0.9 / 2013-10-07 +================== + + * compatibility with jQuery File Upload Plugin 5.32.6 + 0.0.8 / 2013-01-01 ================== diff --git a/README.md b/README.md index 0aaac0a..204c7a3 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,38 @@ On the frontend: ``` +To prevent access to /upload except for post (for security) +```javascript +upload.configure({ + uploadDir: __dirname + '/public/uploads/', + uploadUrl: '/uploads' +}); + +/// Redirect all to home except post +app.get('/upload', function( req, res ){ + res.redirect('/'); +}); + +app.put('/upload', function( req, res ){ + res.redirect('/'); +}); + +app.delete('/upload', function( req, res ){ + res.redirect('/'); +}); + +app.use('/upload', function(req, res, next){ + upload.fileHandler({ + uploadDir: function () { + return __dirname + '/public/uploads/' + }, + uploadUrl: function () { + return '/uploads' + } + })(req, res, next); +}); +``` + Overriding global configuration ```javascript @@ -68,7 +100,7 @@ More sophisticated example - Events app.use('/upload', upload.fileHandler()); // events - upload.on('begin', function (fileInfo) { + upload.on('begin', function (fileInfo, req, res) { // fileInfo structure is the same as returned to browser // { // name: '3 (3).jpg', @@ -81,10 +113,10 @@ More sophisticated example - Events // thumbnail_url: 'http://youhost/uploads/thumbnail/3%20(3).jpg' // } }); - upload.on('abort', function (fileInfo) { ... }); - upload.on('end', function (fileInfo) { ... }); - upload.on('delete', function (fileInfo) { ... }); - upload.on('error', function (e) { + upload.on('abort', function (fileInfo, req, res) { ... }); + upload.on('end', function (fileInfo, req, res) { ... }); + upload.on('delete', function (fileInfo, req, res) { ... }); + upload.on('error', function (e, req, res) { console.log(e.message); }); ``` @@ -245,6 +277,10 @@ Other options and their default values: ## Contributors * [@soomtong](http://github.com/soomtong) + * [@gsarwohadi](https://github.com/gsarwohadi) + * [@peecky](https://github.com/peecky) + * [@tonyspiro](https://github.com/tonyspiro) + * [@derjust](https://github.com/derjust) ## License Copyright (c) 2012 [Aleksandr Guidrevitch](http://aguidrevitch.blogspot.com/) diff --git a/examples/.bowerrc b/examples/.bowerrc new file mode 100644 index 0000000..0f29f6a --- /dev/null +++ b/examples/.bowerrc @@ -0,0 +1,4 @@ +{ + "directory": "public/lib", + "json": "bower.json" +} \ No newline at end of file diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 0000000..32c2010 --- /dev/null +++ b/examples/README.md @@ -0,0 +1,15 @@ +## YET ANOTHER JQUERY FILE UPLOAD MIDDLEWARE EXAMPLES + +- use bower to install jquery-file-upload script (tested version 8.8.5) + +to run + +``` +project > npm insatll +project > cd examples +project/examples > npm insatll +project/examples > bower insatll +project/examples > node app.js +``` + +- to image resize : need imagemagick `http://www.imagemagick.org/script/binary-releases.php` \ No newline at end of file diff --git a/examples/app.js b/examples/app.js new file mode 100644 index 0000000..429526d --- /dev/null +++ b/examples/app.js @@ -0,0 +1,144 @@ +/* +* to run : +* node app.js +* */ + +/* +* dependencies +* */ +var express = require('express'), + http = require('http'), + upload = require('../'); + +var swig = require('swig'); + + +// configuration +var resizeConf = require('./config').resizeVersion; +var dirs = require('./config').directors; + + + +// express setup +var app = express(); + + +// set template engine +app.engine('html', swig.renderFile); +swig.setDefaults({ + cache: false // default 'memory' +}); + + +// jquery-file-upload helper +app.use('/upload/default', function (req, res, next) { + upload.fileHandler({ + tmpDir: dirs.temp, + uploadDir: __dirname + dirs.default, + uploadUrl: dirs.default_url, + imageVersions: resizeConf.default + })(req, res, next); +}); + +app.use('/upload/location', upload.fileHandler({ + tmpDir: dirs.temp, + uploadDir: __dirname + dirs.location, + uploadUrl: dirs.location_url, + imageVersions: resizeConf.location +})); + +app.use('/upload/location/list', function (req, res, next) { + upload.fileManager({ + uploadDir: function () { + return __dirname + dirs.location; + }, + uploadUrl: function () { + return dirs.location_url; + } + }).getFiles(function (files) { + res.json(files); + }); +}); + +// bind event +upload.on('end', function (fileInfo) { + // insert file info + console.log("files upload complete"); + console.log(fileInfo); +}); + +upload.on('delete', function (fileName) { + // remove file info + console.log("files remove complete"); + console.log(fileName); +}); + +upload.on('error', function (e) { + console.log(e.message); +}); + + + +// Configuration +app.configure(function () { + app.set('port', process.env.PORT || 3001); + app.set('view engine', 'html'); + app.set('view options', { layout: false }); + app.set('views', __dirname + '/views'); + + app.use(express.bodyParser()); + app.use(express.methodOverride()); + app.use(express.cookieParser('token')); + app.use(express.session({ secret: 'secret' })); + app.use(express.favicon()); + app.use(express.static(__dirname + '/public')); +}); + +app.configure('development', function () { + app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); + app.set('view cache', false); +}); + +app.configure('production', function () { + app.use(express.errorHandler()); + app.set('view cache', true); +}); + + + +/* +* routes +* */ +app.get('/', function (req, res) { + var html = [ + '
Call this url in browser : http://localhost:3001/location/input Go
', + 'Call this url in browser : http://localhost:3001/upload/location/list Go
' + ].join(''); + res.send(html); +}); + + +app.get('/location/input', function (req, res) { + var params = { + title: "jquery file upload example" + }; + + res.render('form', params); +}); + +app.post('/location/input', function (req, res) { + console.log('\n===============================================\n'); + console.log(req.body); + res.send(req.body); +}); + + + +/* + * start server + * */ +http.createServer(app).listen(app.get('port'), function () { + console.log("Express server listening on port " + app.get('port')); + console.log("access url /location/input"); + console.log("access url /upload/location/list"); +}); diff --git a/examples/bower.json b/examples/bower.json new file mode 100644 index 0000000..1c7639f --- /dev/null +++ b/examples/bower.json @@ -0,0 +1,13 @@ +{ + "name": "jquery-file-upload-middleware", + "version": "0.0.1", + "ignore": [ + ".jshintrc", + "**/*.txt" + ], + "dependencies": { + "jquery-file-upload": "8.8.5" + }, + "devDependencies": { + } +} \ No newline at end of file diff --git a/examples/config.js b/examples/config.js new file mode 100644 index 0000000..b4138cc --- /dev/null +++ b/examples/config.js @@ -0,0 +1,56 @@ +exports.resizeVersion = { + default: { + thumbnail:{ + width:80, + height:"80!" + }, + small: { + width:200, + height:"150!" + }, + medium:{ + width:400, + height:300 + }, + large: { + width: 800, + height: 600 + } + }, + location : { + thumbnail:{ + width:80, + height:"80^", + imageArgs: [ + "-gravity", "center", + "-extent", "80x80" + ] + }, + small: { + width:"200", + height:"150^", + imageArgs: [ + "-gravity", "center", + "-extent", "200x150" + ] + }, + medium:{ + width:400, + height:300 + }, + large: { + width: 800, + height: 600 + } + } +}; + +exports.directors = { + temp: './tmp', + + default: '/public/uploads/default', + default_url: '/uploads/default', + + location: '/public/uploads/location', + location_url: '/uploads/location' +}; \ No newline at end of file diff --git a/examples/package.json b/examples/package.json new file mode 100644 index 0000000..c435dee --- /dev/null +++ b/examples/package.json @@ -0,0 +1,8 @@ +{ + "name":"examples", + "version":"0.0.1", + "dependencies":{ + "express":"3.3.x", + "swig":"1.0.x" + } +} \ No newline at end of file diff --git a/examples/public/scripts/file_upload.js b/examples/public/scripts/file_upload.js new file mode 100644 index 0000000..603c48f --- /dev/null +++ b/examples/public/scripts/file_upload.js @@ -0,0 +1,174 @@ +$('#location_gallery').fileupload({ + dataType:'json', + url:'/upload/location', + autoUpload: true, + sequentialUploads:true, + acceptFileTypes:/(\.|\/)(gif|jpe?g|png)$/i, + process:[ + { + action:'load', + fileTypes:/^image\/(gif|jpeg|png)$/, + maxFileSize: 20000000 // 20MB + }, + { + action:'resize', + maxWidth:1200, + maxHeight:800 + }, + { + action:'save' + } + ], + dropZone: $('#gallery_dropzone'), + progressall:function (e, data) { + var progress = parseInt(data.loaded / data.total * 100, 10); + $('#gallery_progress .bar').css('width', progress + '%'); + }, + filesContainer:$('#upload_gallery_files'), + uploadTemplate:function (o) { + var rows = $(); + $.each(o.files, function (index, file) { + var row = $('