Search code examples
javascripthtmlnode.jsexpressbusboy

Connect-busboy: When piping file to write steam, file is empty or incorrect depending on type


I am testing a simple file upload using connect-busboy. I noticed that when I upload a PNG formatted file, the file is uploaded however the content isn't correct - I am unable to open it. I've done md5sum on the source and destination file and they are different. When I upload a text file containing a mere 15 bytes, I see the file being uploaded in the ./public/ directory however it's empty.

Client side code of interest:

<form method="post" enctype="multipart/form-data" action="/api/upload">
   <input type="file" name="thumbnail"/>
   <input type="submit"/>
</form>

Server side

//includes omitted for readability
var Busboy = require("connect-busboy");
app.use(Busboy());

//Add entires to places
app.post("/api/upload", function (req, res, next) {
    req.pipe(req.busboy);
    var filesNames = [];
    req.busboy.on('file', function(fieldname, file, filename) {
        file.on("data", function(data) {

            var fstream = FS.createWriteStream('./public/' + filename,{flags: "a"});
            file.pipe(fstream);
            filesNames.push(filename);
            fstream.on("close", function() {
                console.log("Closing fstream");
            });
        });

    });
    req.busboy.on("finish", function () {
        res.writeHead(200, {'Connection': 'close'});
        for (var i = 0; i < filesNames.length; i++)
        {
              res.write(filesNames[i] + "\n");
        }
        console.log("busboy done");
        res.end("Done..");
    });

});

I've already looked at multiple posts regarding busboy, so I've done my research prior to asking this question.

Also as a note: If I were to log the data, I can see the bytes coming in as expected, however they are not being written to the file (at least in the .txt files).

What am I doing wrong?


Solution

  • You should not create new writable stream everytime you get a piece of file data. Probably thats enough

    req.busboy.on('file', function(fieldname, file, filename) {
        var ws = FS.createWriteStream('./public/' + filename, {flags: "a"});
        file.pipe(ws);
        filesNames.push(filename);
    });