EzDevInfo.com

busboy

A streaming parser for HTML form data for node.js

node.js server not responding while large file upload with express and busboy

I am developping an file sharing platform with node.js and express.js, using busboy.

It works nicely at this time but uploading large file.

If I do, the server doesn't accept any new request while the large file is uploaded.

I that normal ? If it is, how to improve this behavior, even if that means the upload will take more time...

For now I develop and test on localhost on a pretty good PC (asus i7/8G) on ubuntu.

When I start uploadind a large file, and open a new tab to go to the app, the tab loads only when the upload is completed.

Application loading:

var app = express();

//...

app.use(bodyParser.urlencoded({
    extended: true
}));
app.use(bodyParser.json());
app.use(methodOverride());

// Request multipart parsing middleware
app.use(busboy());

// default options, immediately start reading from the request stream and 
// parsing 
app.use(busboy({ immediate: true }));

My upload method in files controller:

exports.create = function(req, res) {

    var _file = new File(req.body);

    req.busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {

        file.on('data', function(data) {
            _file.data += data;
        });
        file.on('end', function() {
            _file.save(function(err) {
                if (err) {
                    console.error(err);
                    return res.status(500).send({
                        message: errorHandler.getErrorMessage(err)
                    });
                } else {
                    // doing some stuff on save
                }
            });
        });
    });

    // req.busboy.on('field', function(key, value, keyTruncated, valueTruncated) {
    //  console.log('Field [' + key + ']: value: ' + value);
    // });
    // req.busboy.on('finish', function() {
    //  console.log('Done parsing form!');
    // });

    req.pipe(req.busboy);
};

Source: (StackOverflow)

Node Busboy abort upload

I'm using busboy, writing my uploaded file to a buffer and performing some validation on it (width, height and filesize). I can't for the life of me figure out how to abort / stop the stream once I find something wrong with the upload.

For instance if I have a max filesize of 500kb that I want to allow, I keep track of the size of the buffer as it's uploading and I want to abort if the size is over 500kb.

Here's a simplified version of my code.

var self = this;
var busboy = new Busboy({
    headers: self.req.headers,
    limits: {
        files: 1
    }
});
busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {

    file.fileRead = [];
    var size = 0;
    file.on('data', function(chunk) {

        size += chunk.length;

        /* DO VALIDATION HERE */
        if( size > 500000) {
            /*** ABORT HERE ***/
        }


        file.fileRead.push(chunk);
    });

    file.on('end', function() {
        var data = Buffer.concat(file.fileRead, size);
        // ... upload to S3
    });

    self.req.pipe(busboy);
});

Source: (StackOverflow)

Advertisements

Why is req.busboy undefined?

I am using connect-busboy in Express.js 4 in order to upload files. I have added app.use(busboy({ immediate: true }); in app.js. My route handler looks like this:

router.post('/upload', function (req, res) {
    var fstream;

    req.pipe(req.busboy);
    console.log(req.busboy);
    req.busboy.on('file', function (fieldName, file, fileName) {
        console.log('Uploading ' + fileName + '...');
        fstream = fs.createWriteStream(__dirname + '/data/' + fileName);
        file.pipe(fstream);
        fstream.on('close', function () {
            res.end('ok');
        });
    });
});

The console.log(req.busboy); returns undefined. Why?!??!


Source: (StackOverflow)

node js busboy not emitting events with angular js $http post

Busboy seems just stuck in there.

I've tested all 3 events(file, field, finish) but nothing was emitted.

My angular code is below.

$http({
    method : 'POST',
    url : mublAConfig.server + '/api/v3/user/friend',
    headers : {
        'Content-Type' : 'application/x-www-form-urlencoded',
        'Authorization' : access_token
    },
    transformRequest : function(obj) {
        var str = [];
        for (var p in obj) {
            str.push(encodeURIComponent(p) + '=' + encodeURIComponent(obj[p]));
        }
        return str.join('&');
    },
    data : {
        id : $scope.writes[0].input,
        say : $scope.writes[1].input
    }
}).success(function(data) {
    console.log('Received data : ', data);
}).error(function(data) {
    console.log('Error! ', data);
});

all i did with busboy was below

req.busboy = new busboy({headers:req.headers});
req.pipe(req.busboy);
req.busboy.on('file', function(field, file, name) {
    console.log('file event');
});
req.busboy.on('field', function(name, value) {
    console.log('field event');
});
req.busboy.on('finish', function() {
    console.log('busboy finished');
});

How can i solve it?


Source: (StackOverflow)

how to set encoding file upload

I'm using angular-file-upload, and when I upload a document that isn't txt, like a picture, pdf or doc document and I try to download it, the file is different from the one I've uploaded( take a look to the picture ), I'm not sure if this is because a wrong encoding when uploading the file..

enter image description here The left document is the original file.

The client:

var uploader = $scope.uploader = new FileUploader({
   scope: $scope,
   url: '/file/upload/',
   method:'POST',
   headers: {
    'X-XSRF-TOKEN': 'some token'
   }
});

$scope.upload = function(){
    uploader.queue.forEach(function(item){
        item.formData = [
        {'filename': 'friendlyName' },
        {'objectType': 'element' },
        {'elementId': 'someId'}
        ];
    });
    uploader.uploadAll();
};

The backend POST...

In here the encoding variable within the file event of busboy is '7bit'..

exports.uploadDocument = function(req,res){
    req.pipe(req.busboy);
    var doc = new DocumentModel();

    req.busboy.on('file',function(fieldname, file, filename, encoding, contentType){
        doc.contentType = contentType;
        doc.encoding= encoding;
        doc.filename= filename;
        doc.content = '';
        doc.size = 0;
        file.on('data',function(data){
            doc.content += data;
            doc.size += data.length;
        });
    });

    //updating req.body with busboy parameters
    req.busboy.on('field',function(fieldname,val){
        req.body[fieldname] = val;
    });

    req.busboy.on('finish', function() {
        if(req.body.hasOwnProperty('filename')){
            doc.friendlyName = req.body.filename;
        }
        if(req.body.hasOwnProperty('objectType')){
            doc.reference.objectType = req.body.objectType;
        }
        if(req.body.hasOwnProperty('elementId')){
            doc.reference._id= req.body.elementId;
        }
        doc.save(function(err,savedFile){
            if(err){
                res.json(500,err.message);
            }else{
                res.json(200,doc);
            }
        });
    });
};

Backend: GET...

exports.downloadDocument = function(req,res){
    var id = mongoose.Types.ObjectId(req.params.documentId);
        DocumentModel.findOneAsync({_id:id}).then(
        function(doc){
            console.log('doc', doc);
            if(doc!==undefined){
                DocumentModel.getFile(doc.fileInfoId).then(function(binaryData){
                    res.setHeader('x-timestamp', Date.now());
                    res.setHeader('x-sent',true);
                    res.setHeader('Content-disposition', 'attachment; filename=' + doc.filename);
                    res.setHeader('Content-Type',doc.contentType);
                    res.send(binaryData);   
                }).error(function(e){
                    res.status(500).send(e.message);
                });
            }
            else{
                res.status(404).send('file not found.');
            }
        });
};

How can I set the correct encoding ? or is not an encoding issue?

This is the error I get when I try to see the downloaded file. enter image description here

Thanks in advance.

PD: Im using gridFS to store the document in mongoDB.


Source: (StackOverflow)

Connect-busboy - Amazon S3 - Validation and return

I am trying to directly upload files from the browser to Amazon S3 using connect-busboy with the following code (https://github.com/thaume/s3-streaming)

route - index.js: var awsUpload = require('../services/aws-streaming');

// Index route
// ===========
exports.index = function(req, res){
  if (req.method === 'POST') {
    return awsUpload(req, function(err, url) {
      res.send(JSON.stringify(url));
    });
  }

  res.writeHead(200, { Connection: 'close' });
  res.end('<html><head></head><body>\
             <form method="POST" enctype="multipart/form-data">\
              <input type="file" name="filefield"><br />\
              <input type="submit">\
            </form>\
          </body></html>');
};

with my modified version of aws-streaming.js

// Initialize aws client
// =====================
var config = require('../config/' + 'development');
var Knox = require('knox');
var moment = require('moment');
var crypto = require('crypto');

// Create the knox client with your aws settings
Knox.aws = Knox.createClient({
  key: config.aws.AWS_ACCESS_KEY_ID,
  secret: config.aws.AWS_SECRET_ACCESS_KEY,
  bucket: config.aws.S3_BUCKET_NAME,
  region: 'eu-west-1'
});

// S3 upload service - stream buffers to S3
// ========================================
var s3UploadService = function(req, next) {
  req.files = {};

  req.busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
    if (!filename) {
      // If filename is not truthy it means there's no file
      return;
    }
    //////////////// CHECK FOR MIMETYE /////////////////////
    // If file is not "text/plain" - return //
    if (mimetype != "text/plain") {
      console.log('true!')
      return;  // A JSON array with an error "Wrong file type"!
    }
    // Create the initial array containing the stream's chunks
    file.fileRead = [];

    file.on('data', function(chunk) {
      // Push chunks into the fileRead array
      this.fileRead.push(chunk);
    });

    file.on('error', function(err) {
      console.log('Error while buffering the stream: ', err);
    });

    file.on('end', function() {
      // Concat the chunks into a Buffer
      var finalBuffer = Buffer.concat(this.fileRead);

      req.files[fieldname] = {
        buffer: finalBuffer,
        size: finalBuffer.length,
        filename: filename,
        mimetype: mimetype
      };

      // Generate date based folder prefix
      var datePrefix = moment().format('YYYY[/]MM');
      var key = crypto.randomBytes(10).toString('hex');
      var hashFilename = key + '-' + filename;

      var pathToArtwork = '/artworks/' + datePrefix + '/' + hashFilename;

      var headers = {
        'Content-Length': req.files[fieldname].size,
        'Content-Type': req.files[fieldname].mimetype,
        'x-amz-acl': 'public-read'
      };

      Knox.aws.putBuffer( req.files[fieldname].buffer, pathToArtwork, headers, function(err, response){
        if (err) {
          console.error('error streaming image: ', new Date(), err);
          return next(err);
        }
        if (response.statusCode !== 200) {
          console.error('error streaming image: ', new Date(), err);
          return next(err);
        }
        console.log('Amazon response statusCode: ', response.statusCode);
        console.log('Your file was uploaded');
        next();
      });
    });
  });

  req.busboy.on('error', function(err) {
    console.error('Error while parsing the form: ', err);
    next(err);
  });

  req.busboy.on('finish', function() {
    console.log('Done parsing the form!');
    // When everythin's done, render the view
    next(null, 'http://www.google.com');
  });

  // Start the parsing
  req.pipe(req.busboy);
};

module.exports = s3UploadService;

What I would like to do is to validate the mimetype and return a json array with the error message, ending the parsing of the form and not upload the file. Have added code to aws-streaming, but it will not return even if validates to true. What have I done wrong?

Also the code runs the callback when it is finished parsing the form, but I would like it to be run when the file is actually uploaded. How can I achieve this, comment out the next() in 'finish' event and move it to the Knox.aws.putBuffer?

Im using Express 4


Source: (StackOverflow)

Angular not POSTing multipart data so express doesn't receive a thing?

I have a form with 2 file and a text area to post to the serverside made with node.js to handle the upload part on node/express(4.0) I used multer. While to handle the upload from the angular side I relayed on angular-file-upload

I'm trying to keep the express part super simple for now just to test out the fact that it actually works

/// NODE JS EXPRESS

        app.use(multer({    dest: __dirname + '/public/uploads/', 
                            rename: function (fieldname, filename) {
                                return filename; //.replace(/\W+/g, '-').toLowerCase() + Date.now()
                            }
                      }))

/// ANGULAR

        cmsApp.controller("MyController", ['$scope', '$location', '$upload', function($scope, $location, $upload) {
            $scope.title = $location;


            //$scope.saveMiscs = function() {
            $scope.submit = function() {
              console.log("saving miscs");
              var file_1 = $scope.formfile1;
              var file_2  = $scope.formfile2;

              //console.log('file is ', JSON.stringify(file_regole), " + " + JSON.stringify(file_statuto));
              $scope.upload = $upload.upload({
                    url: '/api/misc/filupload1', //upload.php script, node.js route, or servlet url
                    file: file_1,       // or list of files ($files) for html5 only
                  }).progress(function(evt) {
                    console.log('percent: ' + parseInt(100.0 * evt.loaded / evt.total));
                  }).success(function(data, status, headers, config) {
                    // file is uploaded successfully
                    console.log("upload completed: ", data);
                  });
            };


            $scope.onFileSelect = function($files) {
                $scope.files = angular.copy($files);
                console.log($scope.files); // Returns my object
            }


            $scope.setFiles = function(element) {
            $scope.$apply(function($scope) {
                console.log(element.files);
                if(element.id == "form__file1")
                  file_1 = element.files;
                else if(element.id == "form__file2")
                  file_2 = element.files;
              });
            };

        }]);

/// ANGULAR HTML

    <form id="modify_form" ng-submit="submit()" ng-controller="MyController" enctype="multipart/form-data">

        <div class="intro_detail" style="margin-top:36px;">
            <div class="dotted blue"></div>
            <div class="box_title">Documents</div>
            Load file 1 here<br>
            <input type="file" id="form_1_fld" class="" name="" 
                    onchange="angular.element(this).scope().setFiles(this);" ng-model="file_1"/><br>
            <br>
            Load file 2 here<br>
            <input type="file" id="form_2_fld" class="" name="" 
                    onchange="angular.element(this).scope().setFiles(this);" ng-model="file_1"/>
            <div class="dotted spacer_small blue"></div>
        </div><!-- END INTRO DETAIL -->

        <div class="form_viewport">

            <div class="full_container">
                <label>Write something in here:</label><br>
                <textarea ng-model="text_desc" id="form__desc"></textarea>
            </div>

            <div class="clearfix"></div>

            <div class="full_container" style="text-align:center; margin-top:50px;">
                <input type="button" class="submit_cancel" value="Cancel" />
                <input type="submit" class="submit_save" value="Save" />
            </div>


        </div><!-- END FORM VIEWPORT -->

    </form>

If I try to post with a plain form, that does not involve angular, a simple multipart form with one "file" field, nodejs/multer takes the file and uploads is with no problem, but if I use this scenario involving express in the game, it looks like there's no file posted to the server.


Source: (StackOverflow)

node.js - How does Busboy actually work?

I'm a bit confused with Busboy module. I don't understand where it takes file data to stream as it accepts only request headers as parameter?! Take a look on example from docs:

var busboy = new Busboy({ headers: req.headers });
busboy.on('file', function (fieldname, file, filename, encoding, mimetype) {
   //...
   // btw file is ReadableStream!
});

Source: (StackOverflow)

NodeJS error with connect-busboy, "TypeError: Cannot call method 'on' of undefined"

I have this piece of code:

router.route("/post")
        .get(function(req, res) {
            ...
        })
        .post(authReq, function(req, res) {
            ...
            // Get uploaded file
            var fstream
            req.pipe(req.busboy)
            req.busboy.on('file', function (fieldname, file, filename, encoding, mimetype) {
            ...

            var fileSuffix = mimetype.split("/")[1] // Get suffix, may not always be correct
            var tmpFileName = postCount + "." + fileSuffix
            var tmpFileURL = __dirname + "/tmp/" + tmpFileName
            // Start writing
            fstream = fs.createWriteStream(tmpFileURL)
            file.pipe(fstream)
            fstream.on('close', function() {
                 ...
            })
        })
    })
})

This use to work perfectly. However, I don't know quite what happened, but I picked up my computer today and found this error occurring every time I attempt to post:

TypeError: Cannot call method 'on' of undefined
    at IncomingMessage.Readable.pipe (_stream_readable.js:494:8)
    at /Users/nathan/Library/Mobile Documents/com~apple~CloudDocs/Dev/LaughItUp/Code/Server/apiRoutes.js:139:8
    at Layer.handle [as handle_request] (/Users/nathan/Library/Mobile Documents/com~apple~CloudDocs/Dev/LaughItUp/Code/Server/node_modules/express/lib/router/layer.js:82:5)
    at next (/Users/nathan/Library/Mobile Documents/com~apple~CloudDocs/Dev/LaughItUp/Code/Server/node_modules/express/lib/router/route.js:100:13)
    at authReq (/Users/nathan/Library/Mobile Documents/com~apple~CloudDocs/Dev/LaughItUp/Code/Server/apiRoutes.js:17:3)
    at Layer.handle [as handle_request] (/Users/nathan/Library/Mobile Documents/com~apple~CloudDocs/Dev/LaughItUp/Code/Server/node_modules/express/lib/router/layer.js:82:5)
    at next (/Users/nathan/Library/Mobile Documents/com~apple~CloudDocs/Dev/LaughItUp/Code/Server/node_modules/express/lib/router/route.js:100:13)
    at next (/Users/nathan/Library/Mobile Documents/com~apple~CloudDocs/Dev/LaughItUp/Code/Server/node_modules/express/lib/router/route.js:94:14)
    at Route.dispatch (/Users/nathan/Library/Mobile Documents/com~apple~CloudDocs/Dev/LaughItUp/Code/Server/node_modules/express/lib/router/route.js:81:3)
    at Layer.handle [as handle_request] (/Users/nathan/Library/Mobile Documents/com~apple~CloudDocs/Dev/LaughItUp/Code/Server/node_modules/express/lib/router/layer.js:82:5)

_stream_readable.js:501
    dest.end();
         ^
TypeError: Cannot call method 'end' of undefined
    at IncomingMessage.onend (_stream_readable.js:501:10)
    at IncomingMessage.g (events.js:180:16)
    at IncomingMessage.emit (events.js:92:17)
    at _stream_readable.js:943:16
    at process._tickCallback (node.js:419:13)

In my index.js file, I have this code to use Busboy:

app.use(busboy())

Then this code to include my route:

app.use("/api", require("./apiRoutes.js")())

Thanks in advance!

EDIT: I was doing a bit more debugging and I think I pinpointed the issue. req.busboy is not defined. So I went digging through source code. Here is some of the code in the connect-busboy module:

if (req.busboy
|| req.method === 'GET'
|| req.method === 'HEAD'
|| !hasBody(req)
|| !RE_MIME.test(mime(req)))
return next()

When I print out the actual values, busboy does not exist, the request method is 'POST', hasBody(req) results true, yet RE_MIME.test(mime(req))) results false, which is why busboy is not added to the request.

My example file's MIME type is image/gif. Here is the regular expression connect-busboy is testing image/gif off of (aka RE_MIME variable):

/^(?:multipart\/.+)|(?:application\/x-www-form-urlencoded)$/i;

Therefore, I've come to the verdict I'm misunderstanding the API. Is Busboy only for HTML forms?

EDIT #2: I simply switched to Multer and it works fine. However, I believe my issue was that I needed to place the file in a multipart part of the request; I'm not sure why it was working before. Thanks!


Source: (StackOverflow)

How to stop upload and redirect in busboy if mime type is invalid?

I am fairly new to Node.js, and I am using Express and Busboy-Connect to create a simple file upload form, for wav files only. Here is what I am trying to do : - start the upload - if the mimetype is not wav, redirect to an error page - else : write the file on the server and redirect back.

If the mimetype is valid, everything works fine, but if it isn't I cannot redirect and the browser is just hanging and eventually times out. My understanding of it is that the browser doesn't want to redirect because it is waiting for the upload to finish, but how can I cancel the upload then within my js code ? I could work around the issue and write the file then delete it if it's not the right mimetype, but I think it's a bit stupid to do that, I'd rather find a way to trigger an event that will stop it and redirect immediately. Here is (a snippet of) my app code :

app.get('/', function (req, res) {
    res.render(__dirname + '/public/index.ejs', {error: 0});
});

app.get('/error', function (req, res) {
    res.render(__dirname + '/public/index.ejs', {error: 1});
});

app.post('/upload', function (req, res) {
    var timestamp = new Date().getTime().toString();
    //console.log(timestamp);
    var fstream;
    req.pipe(req.busboy);
    req.busboy.on('file', function (fieldname, file, filename, encoding, mimetype) {

        if ("audio/wav" != mimetype)
        {
           console.log("invalid mimetype"); // that prints ok
           // req.busboy.end();  // I tried that but it doesn't work
           res.redirect('/error');


        }
        else
        {
            console.log("Uploading: " + mimetype); 
            fstream = fs.createWriteStream(__dirname + '/tmp/' + timestamp + filename);
            file.pipe(fstream);
            fstream.on('close', function () {
                res.redirect('back');

            });
        }
    });



});

Can anyone point me in the right direction? Thank you for your help !


Source: (StackOverflow)

Unsupported content type Image/PNG

I am trying to upload a image file on server using NodeJS busboy and I am getting this error:

Service Listening for request on: 8080
Error: Unsupported content type: image/png
    at Busboy.parseHeaders (D:\ImageUploadService\node_modules\busboy\lib\main.j
s:66:9)
    at new Busboy (D:\ImageUploadService\node_modules\busboy\lib\main.js:21:10)
    at D:\ImageUploadService\server.js:15:15
    at Layer.handle [as handle_request] (D:\ImageUploadService\node_modules\expr
ess\lib\router\layer.js:76:5)
    at next (D:\ImageUploadService\node_modules\express\lib\router\route.js:100:
13)
    at Route.dispatch (D:\ImageUploadService\node_modules\express\lib\router\rou
te.js:81:3)
    at Layer.handle [as handle_request] (D:\ImageUploadService\node_modules\expr
ess\lib\router\layer.js:76:5)
    at D:\ImageUploadService\node_modules\express\lib\router\index.js:234:24
    at Function.proto.process_params (D:\ImageUploadService\node_modules\express
\lib\router\index.js:312:12)
    at D:\ImageUploadService\node_modules\express\lib\router\index.js:228:12

Below is my code:

app.post('/uploadImage',function(req,res){
    var alias=req.query.alias;
    var imagetype=req.query.imagetype;  //can be media/profile
    var busboy = new Busboy({ headers: req.headers });
    busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
        var saveTo = ".\\Images\\"+alias+"\\"+imagetype+"\\"+filename;
        if (fs.existsSync(saveTo)) {
            file.pipe(fs.createWriteStream(saveTo));
        }
        else{
            fs.mkdir(".\\Images\\"+alias+"\\"+imagetype,function(err){
                 saveTo=".\\Images\\"+alias+"\\"+imagetype;
                 file.pipe(fs.createWriteStream(saveTo));
            });
        }   
    });
    busboy.on('finish', function() {
      res.writeHead(200, { 'Connection': 'close' });
      res.status(200).end();
    });
    return req.pipe(busboy);
});

I am trying to make request using POSTMAN REST CLIENT.

Is this a problem from client or do I have to make chnages in the code. Please note that I've mentioned Content-Type: image/png on the client(postman).

Side question: Also, I there a way I can store the image as thumbs ??


Source: (StackOverflow)

Is it possible to forward a stream from one function to another?

Please have a look at the following sample code.

As you can see, it uses busboy to parse incoming form data and write incoming files to disc. Let's assume these are just image files because my sample code makes use of imgur.com. (a content-length header doesn't need to be sent) The imgurUpload() function makes use of node-form-data

Is it somehow possible to stream the image files additionally, without the need to buffer them complete, to imgur.com? (to the imgurUpload() function and use it within node-form-data?)

Server / listener:

var http = require('http'),
  Busboy = require('busboy'),
  FormData = require('form-data'),
  fs = require('fs')

http.createServer(function(req, res) {
  if (req.method === 'POST') {
    var busboy = new Busboy({
      headers: req.headers
    })
    busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
      //pipe the stream to disc
      file.pipe(fs.createWriteStream('1st-' + filename))
      //pipe the stream a 2nd time
      file.pipe(fs.createWriteStream('2nd-' + filename))

      /* how to connect things together? */
    })
    busboy.on('finish', function() {
      res.writeHead(200, {
        'Connection': 'close'
      })
      res.end("upload complete")
    })
    return req.pipe(busboy)
  } else if (req.method === 'GET') {
    var stream = fs.createReadStream(__dirname + '/index.html')
    stream.pipe(res)
  }
}).listen(80, function() {
  console.log('listening for requests')
})

HTML test form (index.html)

<!doctype html>
<head></head>
<body>
  <form action="/upload" method="post" enctype="multipart/form-data">
    <input type="file" name="file">
    <input type="submit" value="submit">
  </form>
</body>
</html>

Sample function that submits an image file to imgur.com:

function imgurUpload(stream) {

  var form = new FormData()
  //form.append('Filedata', fs.createReadStream('test.jpg'))

  form.append('Filedata', /* how to connect things together? */X )
  form.submit('http://imgur.com/upload', function(err, res) {
    if (err) throw err

    var body = ''
    res.on('data', function(chunk) { body += chunk })
    res.on('end', function() { console.log('http://imgur.com/' + JSON.parse(body).data.hash) })
  })
}

Update (regarding mscdex answer)

_stream_readable.js:748
    throw new Error('Cannot switch to old mode now.');
          ^
Error: Cannot switch to old mode now.
    at emitDataEvents (_stream_readable.js:748:11)
    at FileStream.Readable.pause (_stream_readable.js:739:3)
    at Function.DelayedStream.create (\path\node_modules\form-data\node_modules\combined-stream\node_modules\delayed-stream\lib\delayed_stream.js:35:12)
    at FormData.CombinedStream.append (\path\node_modules\form-data\node_modules\combined-stream\lib\combined_stream.js:45:30)
    at FormData.append (\path\node_modules\form-data\lib\form_data.js:43:3)
    at imgurUpload (\path\app.js:54:8)
    at Busboy.<anonymous> (\path\app.js:21:4)
    at Busboy.emit (events.js:106:17)
    at Busboy.emit (\path\node_modules\busboy\lib\main.js:31:35)
    at PartStream.<anonymous> (\path\node_modules\busboy\lib\types\multipart.js:205:13)

Source: (StackOverflow)

Node: Stream data from busboy to Google Drive

I want to upload a file and then pass that file to google drive! I am using Busboy and Node Google Drive client!

I want to pass the file stream from busboy to the google drive API!

I dont want to create a temporary file and then create a fs.createReadStream to read that temporary file, I want it to be done purely using the memory, without any IO operation,

Any idea how to do it?

busboy.on('file', function(fieldname, file, filename, encoding, mimetype){
    console.log('File [' + fieldname + ']: filename: ' + filename + ', encoding: ' + encoding + ', mimetype: ' + mimetype);

    file.on('data', function(data){
        //Need to store all the data here and pass it back at file.on('end')            
    });

    file.on('end', function(){
        drive.files.insert({
            resource: {
                title: '123.jpg',
                mimeType: 'image/jpeg',
                parents: [{
                    kind: "drive#fileLink",
                    id: "0B0qG802x7G4bM3gyUll6MmVpR0k"
                }]
            },
            media: {
                mimeType: 'image/jpeg',
                body: //how to pass stream from busboy to here???
            }
        }, function(err, data){

        });
    })
})

Source: (StackOverflow)

Parse file content during file upload

I was wondering if someone knows how to extract the file content from an uploaded file when using express/nodejs

I have the following code and it's clear how to pipe the input to a filestream, but how do I deserialize the upload to a plain javascript object? The purpose is to extract information from the uploaded file and use it somewhere else. Ideally I don't want to go via a temporary file on disk. The format of the file is json.

app.post("/upload", function(req, res){

    req.pipe(req.busboy);

    req.busboy.on('file', function (fieldname, file, filename) {

        console.log("Uploading: " + filename);
        console.log(file);
        console.log(fieldname);

        // I don't want to go via a file, but straight to a JS object


        //fstream = fs.createWriteStream('/files/' + filename);
        //
        //file.pipe(fstream);
        //
        //fstream.on('close', function () {
        //
        //    res.redirect('back');
        //
        //});
    });
});

The file upload is triggered like this:

var formData = new FormData($('form')[0]);

        e.preventDefault();

        $.ajax({
            url: 'upload',
            type: 'POST',
            data: formData,
            cache: false,
            dataType:'json',
            contentType: false,
            enctype: 'multipart/form-data',
            processData: false,
            success: function (response) {
            }
        });

Source: (StackOverflow)

CRC32 checksum is not getting calculated in node.js

I'm writing a node.js server where I accept a file along with a CRC32 checksum in a multipart request. I am using busboy and crc node modules to handle multipart requests and CRC operations in node.

In the busboy's finish event, I am attempting to calculate the CRC32 checksum of the saved file and validating it against the received checksum.

My problem is that in the finish event, the checksum is always calculated as 0. If I manually run the CRC32 checksum against the same file, the checksum gets calculated properly.

Here's the code snippet I use to handle the multipart request with crc32 calculation:

var busboy = new Busboy({ headers : request.headers});
var saveTo;
var crc32;
busboy.on('file', function (fieldname, file, filename, encoding, mimetype) {
    saveTo = path.join('files', '/', filename);
    file.pipe(fs.createWriteStream(saveTo));
});

busboy.on('field', function(fieldname, val, fieldnameTruncated, valTruncated) {
    if(fieldname == 'checksum') {
        crc32 = val;
    }
});

busboy.on('finish', function() {
    var savedFileCrc32 = crc.crc32(fs.readFileSync(saveTo)).toString(16);
    console.log("CRC32 of saved file: " + savedFileCrc32 + " file: " + saveTo);
});
request.pipe(busboy);

My console always prints CRC32 of saved file: 0 file: files/image.jpg

However, if I run a node program to calculate the CRC32 checksum of the file that was just created, it works perfectly and prints the checksum.

The image is also getting saved properly. In the finish event, if I open a read stream onsaveTo and read out the bytes, the image is getting read, so the file already exists.

Any idea what the problem could be?


Source: (StackOverflow)