1
votes

This storage just doesn't seem to work to me. I configured everything correctly and I can connect to my SFTP server using the same credentials through WinSCP or Putty, but when uploading a file through this library, no error is displayed and code just seems to work fine, but there's no file on the server.

const multer = require('multer');
const sftpStorage = require('multer-sftp');

const storage = sftpStorage({
    sftp: {
        host: process.env.CDN_HOST,
        port: 22,
        username: process.env.CDN_USERNAME,
        password: process.env.CDN_PASSWORD,
    },
    destination: function(req, file, cb) {
        cb(null, `${process.env.CDN_BASEPATH}/folder`); // /var/www/CDN/folder
    },
    filename: function(req, file, cb) {
        const extension = path.extname(file.originalname);
        if (req.fileId) { // req.fileId is set as a MongoDB object id
            cb(null, req.fileId + extension);
        } else {
            cb(null, file.originalname);
        }
    }
});

const upload = multer({
    storage: storage,
    limits: {
        fieldSize: 8 * 1000000, // 8 MB in bytes
    },
    fileFilter: function(req, file, cb) {
        if (file.mimetype !== 'image/jpg' && file.mimetype !== 'image/jpeg' && file.mimetype !== 'image/png' && file.mimetype !== 'image/gif') cb(new Error("IMG_EXT_UNSUPPORTED"), false);
        else cb(null, true);
    },
}).single('image');

/* Then, in my request */
upload(req, res, function(err) {
    console.log(err); // undefined
});

The upload is executed without error of any sort, but the file just isn't there. I wonder why this happens.

fileFilter, filename and destination functions are NEVER called, and any log placed in those functions is never executed. Instead, any console.log executed before and after the upload call and inside its callback is working correctly. Seems that upload never even tries to handle the file.

Where could the problem lie?

EDIT: I noticed that I'm using formidable to parse multipart fields (including the image) and then, only after validating these fields, calling the function "upload". Could it be that formidable's parsed image isn't compatible with multer? What can I do if so?

1

1 Answers

1
votes

Afaik you should not mix formidable and multer. Probably formidable already parses the request and there will be nothing for multer to consume. Try removing formidable and just using multer, e.g.

const upload = multer({
    storage: storage,
    limits: {
        fieldSize: 8 * 1000000, // 8 MB in bytes
    },
    fileFilter: (req, file, cb) => {
        if (file.mimetype !== 'image/jpg' && file.mimetype !== 'image/jpeg' && file.mimetype !== 'image/png' && file.mimetype !== 'image/gif') cb(new Error("IMG_EXT_UNSUPPORTED"), false);
        else cb(null, true);
    },
});

app.post('/your-upload-route', upload.single('image'), (req, res, next) => {
  // req.file should hold the `image` here
  // req.body will hold the text fields, if there were any
})