tunnckoCore / opensource

Delivering delightful digital solutions. Monorepo of monorepos of Open Source packages with combined ~100M/month downloads, semantically versioned following @conventional-commits. Fully powered ES Modules, @Airbnb @ESLint + @Prettier, independent & fixed versioning. Quality with @Actions, CodeQL, & Dependabot.
https://tunnckocore.com/opensource
481 stars 18 forks source link

Shared Formidable IncomingForm instance fails on concurrent uploads #44

Open robharper opened 7 years ago

robharper commented 7 years ago

Version: 3.0.2

Description: Providing a custom Formidable IncomingForm instance via the IncomingForm option on create causes concurrent uploads to put that instance in a bad state. The concurrent uploads usually fail with the following error message. Any further uploads after this failure will not complete until the connection times out.

  Error: MultipartParser.end(): stream ended unexpectedly: state = START_BOUNDARY
      at MultipartParser.end (/Users/rob/code/influent3/docker-rhel-fail/node_modules/formidable/lib/multipart_parser.js:326:12)
      at IncomingMessage.<anonymous> (/Users/rob/code/influent3/docker-rhel-fail/node_modules/formidable/lib/incoming_form.js:130:30)
      at emitNone (events.js:86:13)
      at IncomingMessage.emit (events.js:188:7)
      at endReadableNT (_stream_readable.js:975:12)
      at _combinedTickCallback (internal/process/next_tick.js:80:11)
      at process._tickCallback (internal/process/next_tick.js:104:9)

My understanding of Formidable is that the IncomingForm instance should not be reused across requests. The problematic lines in koa-better-body appear to be here.

Steps to reproduce: Use the example code from the Formidable recipe here: https://github.com/tunnckoCore/koa-better-body/tree/master/recipes/formidable

Use the following to get the server into a failed state:

curl -i http://localhost:4290/ -F "foo=@path_to_some_reasonable_sized_file" & curl -i http://localhost:4290/ -F "foo=@path_to_some_reasonable_sized_file"

where path_to_some_reasonable_sized_file should supply something large enough to ensure the uploads are concurrent. In my case it was a file ~ 500kb.

After the above command, any further upload will lock until the connection times out. E.g. use the recipe's example curl:

curl -i http://localhost:4290/ -F "foo=@%s/README.md" -F user=test
tunnckoCore commented 7 years ago

Hey thanks, brilliant report!

Sorry for the late answer, I was traveling around my country. I will look what I can do but PRs & ideas are welcome.

tunnckoCore commented 7 years ago

I'll try it and will see what i can do, otherwise i'll switch to busboy under the hood and see if it's okey.

What you think about switching to busboy instead of formidable? Formidable has lot of problems and I and few other folks are the new maintainers, but i don't see we can get it better soon.

tunnckoCore commented 4 years ago

Hey @robharper, any response to above question? :)