Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

$http.post: Large files do not work

I am trying to upload files through my web app using the following code.

View:

  <form name="uploadForm" class="form-horizontal col-sm-12">
    <div class="col-sm-4">
      <input type="file" ng-model="rsdCtrl.viewData.file" name="file"/>
    </div>
    <div class="col-sm-4">
      <button class="btn btn-success" type="submit" ng-click="uploadFile()">Upload</button>
    </div>
  </form>

Controller:

function uploadFile(){
  if (uploadForm.file.$valid && file) {
    return uploadService.upload(vd.file, "Convictions Calculator", "PCCS").then(function(response){
      /* Some stuff */
    }).catch(handleServiceError);
  }
}

uploadService:

(function (){
'use strict';
angular.module('cica.common').service('uploadService', ['$http', '$routeParams', uploadService]);

function uploadService($http, $routeParams) {

    this.upload = function (file, name, type) {
        const fd = new FormData();
        fd.append('document', file);
        fd.append('jobId', $routeParams.jobId);
        fd.append('documentRename', name);
        fd.append('documentType', type);

        return $http.post('/document/upload', fd, {
            transformRequest: angular.identity,
            headers: {'Content-Type': undefined}
        }).catch(function(err){
            handleHttpError('Unable to upload document.', err);
        });
    };
  }
})();

routes.js:

    'POST /document/upload': {controller: 'DocumentController', action: 'uploadDocument'},

DocumentController:

"use strict";
const fs = require('fs');

module.exports = {
  uploadDocument: function (req, res) {
    console.log(req.allParams());   //Inserted as part of debugging
    const params = req.allParams();
    req.file('document').upload({
        // don't allow the total upload size to exceed ~100MB
        maxBytes: 100000000
    }, function whenDone(err, uploadedFiles) {
        if (err) {
            return res.serverError(err);
        }
        // If no files were uploaded, respond with an error.
        else if (uploadedFiles.length === 0) {
            return res.serverError('No file was uploaded');
        } else {
            const filePath = uploadedFiles[0].fd;
            const filename = uploadedFiles[0].filename;
            return fs.readFile(filePath, function (err, data) {
                if (err) {
                    return res.serverError(err);
                } else {
                    const jobId = params.jobId;
                    const jobVars =
                        {
                            filePath: results.filePath,
                            fileName: params.documentRename,
                            fileType: params.documentType
                        };
                    return DocumentService.uploadConvictions(req.session.sessionId, jobId, jobVars).then(function (response) {
                        return res.send("Document uploaded.");
                    }).catch(function (err) {
                        return res.serverError(err);
                    });
                }
            });
        }
    });
},

If I upload a .jpeg (around 11kB) the upload works exactly as expected, however, if I try to upload a larger .jpeg (around 170kB) it falls over. There is no immediate error thrown/caught though, what happens is the formData object created in the upload service seems to lose its data. If I breakpoint on its value, it returns empty for the larger file, which eventually causes an error when the function tries to use these variables further on. Is there some kind of limit set to the size of a file you can upload via this method, or have I configured this incorrectly?

like image 368
Barry Piccinni Avatar asked Jan 27 '23 18:01

Barry Piccinni


1 Answers

I take the chance and assume you are using bodyParser as middleware. bodyParser has a default limit of 100kb. Look at node_modules/body-parser/lib/types/urlencoded.js :

var limit = typeof options.limit !== 'number'
    ? bytes(options.limit || '100kb')
    : options.limit

You can change the limit in your app.js by

var bodyParser = require('body-parser');
...
app.use(bodyParser.urlencoded( { limit: 1048576 } )); //1mb
like image 185
davidkonrad Avatar answered Jan 30 '23 08:01

davidkonrad