Skip to content
This repository was archived by the owner on Mar 16, 2019. It is now read-only.
This repository was archived by the owner on Mar 16, 2019. It is now read-only.

Possible Inefficiency/issues with uploading document provider provided documents #525

Open
@dantman

Description

@dantman

I've been reviewing the code to see if RNFB is viable for my use case, I've got a document picker on Android (some native code that uses Intent.ACTION_GET_CONTENT to let the user select a file and then returns the content:// URI provided by the document provider) and I need to upload that document to our API.

From what I see in PathResolver.java, RNFetchBlobBody.java, and RNFetchBlobReq.java it looks like what RNFB does to handle a document provided by a document provider is hacky/inefficient.

The PathResolver. getRealPathFromURI is called through normalizePath by a bunch of methods that just want to get an InputStream (readFile to read it, various parts of the upload code to upload the data from that stream). To deal with document providers it first skips the standard way of doing things on Android and hardcodes patterns of a few different document providers manipulating the Uris returned by document providers like external stores, file content, google photos, and media provider in order to return something closer to a Filesystem path. If it's not one of them then it uses openInputStream and getCacheDir to copy the document provided by the document provider to a temporary file (which may involve a network download that doesn't have its progress tracked and blocks the upload; I'm not certain but it almost looks like it might block one of the threads to do this; and may be padding the size of the file to an incorrect length) and it returns the path to that file.

The upload code calling that method then uses the path to open an InputStream to that file and uploads from the stream.

So in short:

  • If your document is a file on external storage or somewhere else on the filesystem, the lib will use non-standard methods of getting a file path and interact with it using the File file API. Which I believe may possibly bypass standard permissions granted for something returned by an intent and require extra permissions that aren't actually necessary or possibly not work at all at some point (because it's an entirely non-standard way of getting an InputStream from a document provider Uri). (possibly related to the problem "...exposed beyond app through Intent.getData() " at Android N #358)
  • If your document comes from any other document provider (say Drive, Dropbox, a custom photo app, ...) the lib will open an InputStream for it, download the whole file to local temporary storage (ending up duplicating data if the file is actually already stored on the filesystem but is just in the private storage of another app), blocking a thread while doing this and not reporting upload progress, open another InputStream for the temp file and upload that, and then leave the temp file for the system to clean up at its leisure instead of cleaning it up.

I think it would be more reasonable to have a different method to PathResolver.getRealPathFromURI that instead returns an InputStream directly and doesn't use the path hacks. Methods like readFile and the upload body code would call that directly instead of trying to get a path.

Then filesystem files would come from the document provider provided stream and if its from a custom or remote document provider that data would stream into the upload as it is being generated or downloaded and be directly reflected in the upload progress provided by RNFS.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions