richardgirges / express-fileupload

Simple express file upload middleware that wraps around busboy
MIT License
1.52k stars 261 forks source link

req.files is null when code is deployed to a GCP Cloud Function (works fine locally) #224

Closed emirhosseini closed 4 years ago

emirhosseini commented 4 years ago

Deploying a simple piece of code using this package to a GCP Cloud Function results in the 'req.files' variable coming back as null. Haven't been able to determine why this is happening.

Here's a relevant GCP doc that describes doing this directly with busboy so I'm assuming there must be something in this particular implementation that's different than what the article is doing that is causing this issue.

https://cloud.google.com/functions/docs/writing/http#multipart_data

Edit: Here's the stacktrace. The error is on the line of code that tries to access 'req.files.file'. And 'file' being the name of the parameter being passed in which all works correctly locally. Also added the GCP article above that using busboy directly which works.

TypeError: Cannot read property 'file' of null at exports.query (/workspace/src/products.js:23:26) at Layer.handle [as handle_request] (/workspace/node_modules/express/lib/router/layer.js:95:5) at next (/workspace/node_modules/express/lib/router/route.js:137:13) at Route.dispatch (/workspace/node_modules/express/lib/router/route.js:112:3) at Layer.handle [as handle_request] (/workspace/node_modules/express/lib/router/layer.js:95:5)

RomanBurunkov commented 4 years ago

Any examples or logs?

emirhosseini commented 4 years ago

@RomanBurunkov I updated the description and included the GCP article as well that uses busboy directly which works properly.

emirhosseini commented 4 years ago

Could be related to the usage of temp folder in the cloud function not behaving as expected.

RomanBurunkov commented 4 years ago

Provided trace is not enough. Try to set option debug to 'true' and share the output along with full list of middleware options and code snippet.

req.files null usually says that busboy didn't get any multipart data in request. You should always check that in your code, before accessing to the res.files properties.

RomanBurunkov commented 4 years ago

I've deployed test application with Google app engine and couldn't reproduce this issue.

My example app: https://github.com/RomanBurunkov/express-fileupload-example

Log output:

roman@cloudshell:~/express-fileupload-example (causal-port-278608)$ npm start
> express-fileupload-example@0.0.1 start /home/roman/express-fileupload-example
> node index.js
Server listening on port  8000
Express-file-upload: Temporary file path is /home/roman/express-fileupload-example/temp/tmp-1-1591698935963
Express-file-upload: New upload started inpFile->testfile.txt, bytes:0
Express-file-upload: Opening write stream for inpFile->testfile.txt...
Express-file-upload: Uploading inpFile->testfile.txt, bytes:20...
Express-file-upload: Upload finished inpFile->testfile.txt, bytes:20
Express-file-upload: Upload inpFile->testfile.txt completed, bytes:20.
req.files >>> { inpFile:
   { name: 'testfile.txt',
     data: <Buffer >,
     size: 20,
     encoding: '7bit',
     tempFilePath:
      '/home/roman/express-fileupload-example/temp/tmp-1-1591698935963',
     truncated: false,
     mimetype: 'text/plain',
     md5: '7985aa0e35af1f1aa61f3478a058b4dc',
     mv: [Function: mv] } }
Express-file-upload: Moving temporary file /home/roman/express-fileupload-example/temp/tmp-1-1591698935963 to /home/roman/express-fileupload-example/uploads/testfile.txt
RomanBurunkov commented 4 years ago

Closing this issue, since I couldn't reproduce it and haven't gotten any updates from topic starter.

edison0xyz commented 3 years ago

Have faced the same issue with google cloud functions (not app engine).

It will work fine for app engine. However, from some digging around, it seems like cloud functions do process the request differently from a usual express server, hence resulting in res.files being undefined.

The solution that fixes this for me is to us busboy directly as written in this response: https://stackoverflow.com/a/47319614/2837332

cc @RomanBurunkov

AndreasKl commented 1 year ago

The cause for this is according to google:

Cloud Functions provides request and response objects that are compatible with ExpressJS to make consuming HTTP requests simple. Cloud Functions automatically reads the request body, so you will always receive the body of a request independent of the content type. This means that HTTP requests should be considered to have been fully read by the time your code is executed. The nesting of ExpressJS apps should be used with this caveat—specifically, middleware that expects the body of a request to be unread may not behave as expected.