Adding custom Express middleware like jQuery-File-Upload to Sails.js-open source projects blueimp/jQuery-File-Upload

In the case of sails.js and jQuery File upload i think, you can replace sails bodyParser to jQuery file uploader post method, idea from this thread:

nginx / sails.js: incomplete file upload

below example works for me fine. sails js 0.10.5

npm install blueimp-file-upload-expressjs --save
npm install lodash --save

uncomment and add lines in the file /config/http.js:

middleware: {

       cbodyParser: require('../cbodyParser')( { urls: [/\/uploads/]} ),

    order: [
       'startRequestTimer',
       'cookieParser',
       'session',
       'myRequestLogger',

       'cbodyParser',       // intersept multipart requests
       'bodyParser',

       'handleBodyParserError',
       'compress',
       'methodOverride',
       'poweredBy',
       '$custom',
       'router',
       'www',
       'favicon',
       '404',
       '500'
    ]
}

new file in root folder /cbodyParser.js:

var _ = require('lodash');

var options = {
    tmpDir:  __dirname + '/uploads/tmp',
    publicDir: __dirname + '/uploads',
    uploadDir: __dirname + '/uploads',
    uploadUrl:  '/uploads/',
    maxPostSize: 11000000000, // 11 GB
    minFileSize:  1,
    maxFileSize:  10000000000, // 10 GB
    acceptFileTypes:  /.+/i,
    inlineFileTypes:  /\.(gif|jpe?g|png)$/i,
    imageTypes:  /\.(gif|jpe?g|png)$/i,
    imageVersions: {
        width:  220,
        height: 220
    },
    accessControl: {
        allowOrigin: '*',
        allowMethods: 'POST',
        allowHeaders: 'Content-Type, Content-Range, Content-Disposition'
    },
    nodeStatic: {
        cache:  3600 // seconds to cache served files
    }
};

var uploader = require('blueimp-file-upload-expressjs')(options);

function mime(req) {
    var str = req.headers['content-type'] || '';
    return str.split(';')[0];
}

// start jQuery file uploader here:
function parseMultipart(req, res, next) {

    uploader.post(req, res, function (obj) {
        res.send(JSON.stringify(obj));
    });

    next();

}

// check for post method in request
function disable_parser(opts, req, res)  {
    var matched = false;
    try {
        var method = null;
        try {method = req.method.toLowerCase();}
        catch(err){ /* */}
        if(method) {
            _(opts.urls).forEach(function(turl) {
                if (method === 'post' && req.url.match(turl)) {
                    // console.log("matched"+ req.url);
                    if(!matched) matched = true;
                };});
        }
    } catch(err) { debug(err);/* pass */ }
    return matched;
}


// Start all stuff..
module.exports = function toParseHTTPBody(options) {
    options = options || {};

    // NAME of anynonymous func IS IMPORTANT (same as the middleware in config) !!!
    return function cbodyParser(req, res, next) {
        if (disable_parser(options, req, res) && mime(req) == 'multipart/form-data') {  
            // we found multipart request to /uploads, so we can use jQuery file uploader instead
            return parseMultipart(req, res, next);    
        } else {
            return next();
        }
    };
};