Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

file.size undefined with multiple files #1246

Closed
djcaesar9114 opened this issue Mar 2, 2024 · 2 comments
Closed

file.size undefined with multiple files #1246

djcaesar9114 opened this issue Mar 2, 2024 · 2 comments

Comments

@djcaesar9114
Copy link

djcaesar9114 commented Mar 2, 2024

I'm using multer to handle a multi-file upload, and the middleware "filename", like this:

  filename: async (req, file, cb) => {
    console.log(Object.keys(file));
    ({ rows } = await db.query(`
    INSERT INTO public.files(
      uuid,
      nom,
      type,
      size
    )
    VALUES
    ($1, $2, $3, $4)
    RETURNING *`, [
      req.uuid,
      file.originalname,
      file.mimetype,
      file.size,
      // +req.headers["content-length"],
    ]));
    cb(null, uuid);
  },

The problem is that file.size remains undefined. I control that the size exists before sending the files to the API. When I check which properties are available (see the console.log), I only have 'fieldname', 'originalname', 'encoding', 'mimetype'.

If I use +req.headers["content-length"] it takes into account the size of all the request (all the files), and not only the current file.

Why can't I have the file size? Is it impossible or should I edit some setting I haven't found in the documentation?

I think it's because multer is base on busboy, and there could be a way from here:

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

Either busboy gives the size (I opened an issue here: mscdex/busboy#354), or multer can estimate the size with the filestream. That would be a good solution, in my opinion.

@Doc999tor
Copy link

Doc999tor commented Mar 4, 2024

Why the file.size is undefined:

  1. storage.filename callback arguments are based on request content disposition header: filename, content-type etc. In multer().single() middleware the file is already being uploaded and you can have more detailed file stats

https://github.com/expressjs/multer/blob/master/lib/make-middleware.js#L106

      var file = { // initial content disposition header reading
        fieldname: fieldname,
        originalname: filename,
        encoding: encoding,
        mimetype: mimetype
      }

https://github.com/expressjs/multer/blob/master/storage/disk.js#L47

      outStream.on('finish', function () {
        cb(null, {
          destination: destination,
          filename: filename,
          path: finalPath,
          size: outStream.bytesWritten // actual filesize stat from the finished stream
        })
      })

https://github.com/expressjs/multer/blob/master/lib/make-middleware.js#L158

     var fileInfo = extend(file, info) // extending the initial file object with actual file stats
  1. For your use case, you can move the db population to later middleware, when the files will already be uploaded and written to disk

@jonchurch jonchurch removed the bug label Mar 5, 2024
@djcaesar9114
Copy link
Author

Thanks!

@LinusU LinusU closed this as completed Mar 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants