1

I am having some problems properly storing and retrieving files with GridFS. Currently, if I submit a .txt file I end up getting the contents of the file back, but if i submit a .doc file, I get a bunch of gibberish (like blackdiamonds with question marks in it).

My end goal is just to be able to submit the file and then allow someone to download the file later on a different request.

Writing Code:

router.post('/jobs/listing/:job/apply', multipartyMiddleware, function(req, res, next){
  var myFile = req.files.file;
  var conn = mongoose.createConnection('mongodb://localhost/test');
  conn.once('open', function () {

    var gfs = Grid(conn.db, mongoose.mongo);
    var readfile = fs.createReadStream(myFile.path);
    var f = readfile.pipe(gfs.createWriteStream({
        filename: myFile.name
    }));
    f.on('close', function(){
        console.log('File Added to GRIDFS');
        res.end();
    });
  });
}

Reading Code:

var conn = mongoose.createConnection('mongodb://localhost/test');
conn.once('open', function () {
        var gfs = Grid(conn.db, mongoose.mongo);

        var readstream = gfs.createReadStream({
            filename: req.file //set to desired filename
        });

        var f = readstream.pipe(res);
});

Any suggestions? I would really appreciate any help you can provide. Thanks.

Edit: Problem had to do with an uploading issue in angular.

Dave M
  • 418
  • 3
  • 15

2 Answers2

0

Here's a simple implementation that I copied from another developer and modified. This is working for me:

https://gist.github.com/pos1tron/094ac862c9d116096572

var Busboy = require('busboy'); // 0.2.9
var express = require('express'); // 4.12.3
var mongo = require('mongodb'); // 2.0.31
var Grid = require('gridfs-stream'); // 1.1.1"
var app = express();
var server = app.listen(9002);

var db = new mongo.Db('test', new mongo.Server('127.0.0.1', 27017));
var gfs;
db.open(function(err, db) {
  if (err) throw err;
  gfs = Grid(db, mongo);
});

app.post('/file', function(req, res) {
  var busboy = new Busboy({ headers : req.headers });
  var fileId = new mongo.ObjectId();

  busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
    console.log('got file', filename, mimetype, encoding);
    var writeStream = gfs.createWriteStream({
      _id: fileId,
      filename: filename,
      mode: 'w',
      content_type: mimetype,
    });
    file.pipe(writeStream);
  }).on('finish', function() {
    // show a link to the uploaded file
    res.writeHead(200, {'content-type': 'text/html'});
    res.end('<a href="/file/' + fileId.toString() + '">download file</a>');
  });

  req.pipe(busboy);
});

app.get('/', function(req, res) {
  // show a file upload form
  res.writeHead(200, {'content-type': 'text/html'});
  res.end(
    '<form action="/file" enctype="multipart/form-data" method="post">'+
    '<input type="file" name="file"><br>'+
    '<input type="submit" value="Upload">'+
    '</form>'
  );
});

app.get('/file/:id', function(req, res) {
  gfs.findOne({ _id: req.params.id }, function (err, file) {
    if (err) return res.status(400).send(err);
    if (!file) return res.status(404).send('');

    res.set('Content-Type', file.contentType);
    res.set('Content-Disposition', 'attachment; filename="' + file.filename + '"');

    var readstream = gfs.createReadStream({
      _id: file._id
    });

    readstream.on("error", function(err) {
      console.log("Got error while processing stream " + err.message);
      res.end();
    });

    readstream.pipe(res);
  });
});
Devon Sams
  • 1,324
  • 2
  • 12
  • 19
  • No I haven't figured it out yet. Very frustrating! – Dave M May 12 '15 at 17:52
  • Doesn't work for me - I still get the same output. Have you gotten this to work with a .docx file? I'm still trying to get it to work with mongoose - which may be the problem. Word is telling me that it cannot open it because it found problems with its contents. – Dave M May 13 '15 at 18:23
  • The code works by itself. I'll recheck my code and report back when I have time. – Dave M May 13 '15 at 18:45
  • The problem with my code was something to do with the upload. This is a good example though for the upload/download that I couldn't really find elsewhere. Thanks! – Dave M May 13 '15 at 19:09
  • I found out why it wasn't working in my app. Turns out, [connect-livereload](https://github.com/intesso/connect-livereload) was the culprit. If you're using that middleware, check out this [issue](https://github.com/intesso/connect-livereload/issues/39). – Devon Sams May 14 '15 at 01:03
  • Thank you for your example. However I needed to do gfs.files.findOne(...). Since I want to open the file (pdf in my case) in the browser I replaced "attachment" with "inline". – zevero Mar 08 '16 at 00:54
0

For anyone who ends up with this issue, I had the same symptoms and the issue was a middleware. This was a gnarly bug. The response was being corrupted by connect-livereload.

Github Issue on busboy

Github Issue on gridfs stream

My response on a Similar Stack Overflow Issue

Community
  • 1
  • 1