question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

FileStreamDisconnectUploadError when checking file validity

See original GitHub issue

Hello,

The problem

I have a problem when checking for the validity of the files sent by multipart request from the client side.

The client sends a multipart request with maximum 5 different files, then the server loops through them to check if every file is an instance of stream.Readable. While looping through the files an error occures: FileStreamDisconnectUploadError: Request disconnected during file upload stream parsing..

The first file is checked but then the others files are never read.

This is what my loop looks like:

for (const pic of data.pictures) {
      const resolved = await pic;
      if (!(resolved.stream instanceof stream.Readable)) return new Error('Wrong file');
}

The error is raised when executing the line const resolved = await pic;. The first file fills the resolved variable but it never gets filled again with the next files.

What I tried

  • I tried to destroy the stream after the check: resolved.stream.destroy();
  • I tried to replace the for...of loop with a map

Some thoughts

Before making the requests by the client, I sent the requests using curl according to these examples. But the error still occured.

I work on a Macbook with MacOS Sierra 10.12.6 and curl 7.54.0 which uses SecureTransport, as it is the native TLS library.

What is interesting is that my coworkers, which work with the same Macbook as mine but with MacOS High Sierra and curl 7.54.0 which uses LibreSSL as TLS library, manage to get the requests work with the server. Of course we tried with the exact same requests and on a server running on my mac.

Do you have any idea why the error occures and why does the await pic never manage to complete ?

Thanks for your time.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:38 (8 by maintainers)

github_iconTop GitHub Comments

2reactions
koresarcommented, Jul 14, 2020

Apologies for my unconstructive tone.

I finally see what you mean now. The query example explains it all.

Again, I realised that talking about code but not seeing the code often leads to an unconstructive discussion.

PS: I’ve refactored the code back to it’s original state little above in this thread: https://github.com/jaydenseric/graphql-upload/issues/65#issuecomment-382922064

2reactions
mike-marcaccicommented, Jul 16, 2019

Your “less ideal” conditions is impossible. There is literally no scenarios in the world where uploading file B depends on the contents of the file A. (Btw, the great and mighty graphql-upload module has the feature called “variables” to cary any data besides the files.)

You may want to reread my post… my “less ideal” scenario has nothing to do with dependancies of files on each other, or other data. Instead, it has to do with the HTTP request, which is a linear stream of bytes that can contain uploads in a different order than you expect in your resolver. Consider this example query:

query {
  foo: findPeople(byFacePhotos: [$uploadB, $uploadX, $uploadA]) {
    name
  }
  bar: findPeople(byFacePhotos: [$uploadA, $uploadB, $uploadC]) {
    name
  }
}

This kind of request is valid GraphQL and must still be valid when using the the upload spec to do variable replacement. Therefore, the upload spec cannot constrain the order of uploads in the HTTP request such that it matches the order of appearance in every list.

It is completely possible that your upload stream will contain the contents of $uploadC first, followed by $uploadB, then $uploadA. You don’t get to decide this, because you aren’t sending the request; the client is. If your code is waiting on $uploadA before processing $uploadB, then it is inefficient.

Also, there are scenarios where business logic requires one upload to be present before another becomes useful; just because you haven’t run into one doesn’t mean they don’t exist. Your tone here is painfully hyperbolic and very much in contrast to the meticulous attention to edge cases that has made this library suitable for such a wide range of use cases. If you have good feedback, we want to hear it, and dismissive hand-waving is counterproductive to meaningful communication of an intricate subject.


The Promise.all was invented to execute several things at the same time, like saving data to 3 databases simultaneously. Suggesting Promise.all implies that we are consuming A, B, and C simultaneously. But this is very false assumption. We are confusing newbie developers with it too much.

That’s not how promises work. Promises are executed eagerly, meaning that they run as soon as they are created. Something like Promise.all does not cause them to run but instead “pauses” the current flow when using await (or waits to call any functions registered with .then()) until all its promises (which are already running) resolve.


I suspect your example does not work the way you think it works, and if it does, I don’t believe it represents a common use case. In my experience, it’s been standard practice to ensure the file is stored without error before returning a “successful” response.

Keeping in mind that the HTTP response won’t make it to the browser until the request has finished, your resolver should almost certainly be refactored to:

async function resolver(root, { files }, context) {
  try {
    await Promise.all(files.map(async (file) => {
      const { stream, filename /*, mimetype, encoding */ } = await file;
      await s3.upload({Key: filename, Body: stream}).promise();
    }))
    return {success: true};
  } catch (err) {
    log.error(err);
    return {success: false, message: err.message};
  }
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

How to check and verify file integrity - TechTarget
Attacks or accidental corruption can introduce invalid files into a content repository, and verifying file integrity can identify them.
Read more >
How to valid Restricted excel File only can upload as attach ...
Hello. The easiest option is to check file name. If the extension is .xls or xlsx, it can go. If not, warn user....
Read more >
Is the integrity of file uploads/downloads guaranteed by TCP ...
Is the integrity of file uploads/downloads guaranteed by TCP/HTTPS? In short: No. But it is better with HTTPS than with plain TCP.
Read more >
Ensure File Integrity When Uploading a File to a Remote Server
You can use this technique, in order to check the integrity of a file uploaded to your server, for other cases too. Not...
Read more >
File Upload Validation Techniques - Triaxiom Security
Your first line of defense against someone uploading dangerous files to your web application is extension filtering. This is basically where you are...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found