Search code examples
javascriptnode.jsmongodbgridfsgridfs-stream

node.js upload and download pdf file


Framework: node.js/express.js/busboy/gridfs-stream(mongodb)

I am using busboy to upload files and then use gridfs-stream to store files in mongodb gridfs.

                req.pipe(req.busboy);
                req.busboy.on('file', function (bus_fieldname, bus_file, bus_filename) {

                var writestream = gfs.createWriteStream({
                    filename: bus_filename,
                });

                bus_file.pipe(writestream);

                writestream.on('close', function (file) {
                    res.redirect('/xxxxx/');
                });
            });

Download is simple: Use gridfs-stream's createReadStream I read the contents from mongodb and then use the following code to send it to browser.

            gfs.findOne({_id: attachmentid}, function (err, file) {
            if (err || !file){
                res.send(404);
            }else{
                var fileName = file.filename;
                var readstream = gfs.createReadStream({_id: attachmentid});
                var buffer = "";
                readstream.on("data", function (chunk) {
                    buffer += chunk;
                });

                // dump contents to buffer
                readstream.on("end", function () {
                    res.set("Content-Disposition","attachment; filename=" + fileName);
                    res.send(buffer);
                });

            }

Problem: When I upload a 90kb pdf file, it uploads fine. I see the size is correct in mongodb. But when I download, the file size of the downloaded file is about 165kb. There is a mismatch. This does not happen with text files. Sure its something to do with data type.

can anyone please help?


Solution

  • Pipe the gfs read stream to the response directly. This is what works for me

    res.set("Content-Disposition","attachment; filename=" + fileName);
    var readstream = gfs.createReadStream({_id: attachmentid});
    readstream.pipe(res);