Search code examples
node.jsasp.netmultipartform-datanpm-request

NodeJS `request` library fails to post files via multipart-form-data to dotnet server


I am using the [officially deprecated] request library [1], which uses the form-data library [2] to post the file data. For various reasons, switching to an active and maintained http request library is not in the cards at present.

After upgrading from NodeJS v14 -> v16, I am seeing consistent failures to post file data to only dotnet servers. I have observed this with both endpoints we own and can confirm have not changed between the upgrade, as well as other deprecated libraries that make requests in similar fashion, like the [also deprecated] azure-storage [3].

The error manifests as a timeout, as if the server received everything the client sent but thinks there is more to receive.

I am still working through trying to figure out what exactly changed, but am curious if any one else has encountered issues of a similar type, and if there was any workaround that could be made as a band-aid when making requests to avoid the issue.

[1] https://www.npmjs.com/package/request

[2] https://www.npmjs.com/package/form-data

[3] https://www.npmjs.com/package/azure-storage


Solution

  • After much debugging, the problem appears to be related to fs streams' state being corrupted when passed through request -> form-data -> combined-stream -> delayed-stream. That is, 100% unrelated to dotnet. This likely surfaced in a Node v15 commit [1] that had subtle effects on the state machine of a fs stream, and only manifested because of the arcane magicks that CombinedStream and DelayedStream use to try and achieve their desired effects.

    What is currently working for me is to wait for the fs createReadStream open event to be emitted before sending the request, as that was the event I saw that caused issues if it was emitted after delayed-stream tried to pause/freeze it and propagate events on its behalf.

    Even better would be to migrate away from request/form-data altogether.

    [1] https://github.com/nodejs/node/commit/54b36e401d