apache / cordova-plugin-file

Apache Cordova File Plugin
https://cordova.apache.org/
Apache License 2.0
741 stars 756 forks source link

feat(android): add WebViewAssetLoader proxy handler for cdvfile #513

Closed erisu closed 2 years ago

erisu commented 2 years ago

Motivation and Context

Fetching files from the persistent and temporary file systen while using custom scheme+hostname.

Description

This PR adds a proxy handler for the WebViewAssetLoader.

Since cdvfile://localhost no longer works, this PR implements a new URL pattern that works with custom scheme+hostname. It will fetch and return a WebResponse of the file located in the native file system.

E.g.:

Old cdvfile URL:

cdvfile://localhost/persistent/image.png

will become:

https://localhost/__cdvfile_persistent__/image.png

and continue to map to the native file:

file:///data/user/0/<APP ID>/files/files/image.png

If you configure the app to use http or with a different hostname, other then localhost, it will change as such.

Resolves:

Need confirmation:

Depending on use case and app configuration, it appears that many the file url was being used when the app is served though the custom scheme+hostname setup. Only with AndroidInsecureFileModeEnabled will the file path work. This PR will introduce changes which will make it possible to load files with the custom scheme+hostname setup but with a different URL structure.

Usage:

Use toURL, NOT toInternalURL.

The toURL method will call the toInternalURL when necessary.

What happens if toInternalURL is called directly?

Testing

Checklist

JustTestCode commented 2 years ago

helpful

skmbr commented 2 years ago

Sorry if this is the wrong place to ask, but as the current latest version is from 2019, once this gets merged how long is it likely to be for a new release to be available?

Or will I need to build the plugin myself somehow rather than using cordova plugin add... ?

erisu commented 2 years ago

Sorry if this is the wrong place to ask, but as the current latest version is from 2019, once this gets merged how long is it likely to be for a new release to be available?

Or will I need to build the plugin myself somehow rather than using cordova plugin add... ?

@skmbr I can not give you an exact answer, but hoping to prepare a release shortly after.

This PR fixes a lot of the issues but I am trying to investigate one alternative solution. (This explains why I have the PR in draft.)

I am hoping with the alternative solution I will not need to introduce new front-end JS code (E.g. getCdvURL()). I am hoping to reuse the toInternalURL() method instead.

My vision of the alternative solution's use cases is:

  1. If AndroidInsecureFileModeEnabled = true, toInternalURL()/toURL() will continue to return the file:// URL.
  2. If AndroidInsecureFileModeEnabled is not defined (false), toInternalURL() will return the scheme + hostname combination URL. This URL is created from the native side.

Because toURL already calls toInternalURL, this alternative change would mean that app developers do not need to update or change their front-end code. Simply updating the plugin would be all that is needed.

As a side note, the alternative solution would still use all of the native changes I made in this PR.

skmbr commented 2 years ago

I can not give you an exact answer, but hoping to prepare a release shortly after.

@erisu That's good to hear! Thank you!

That alternative solution sounds great too.

If AndroidInsecureFileModeEnabled = true, toInternalURL()/toURL() will continue to return the file:// URL.

One thing I will say is that toInternalURL was returning a cdvfile url for me after enabling AndroidInsecureFileModeEnabled so I had to switch to toURL to get a file:// url.

Looking forward to this being solved so I can do a proper release of my app again. Luckily I have codepush so have still been able to get fixes and small updates out, but getting to the point where I need a full release targeting > SDK 30 to keep up with new features in the iOS version.

Thanks again for all your work on this!

xtof974 commented 2 years ago

Facing the same issue. Any updates about this PR ? Thx for your work !

LongTimeNoTea commented 2 years ago

Thanks for your work! I'm waiting for this to update my app!

erisu commented 2 years ago

I updated the PR description to reflect the latest changes. Read the sections Usage: and What happens if toInternalURL is called directly? to understand about the use case and changes.

NiklasMerz commented 2 years ago

We could add the Usage part to the README of this plugin.

skmbr commented 2 years ago

@erisu Great that this is merged in now. Thanks for all your hard work!

Any news on when there might be a release? Or is the only option to install it via the github url?

kalandher commented 2 years ago

> Task :app:compileDebugJavaWithJavac FAILED platforms\android\app\src\main\java\com\silkimen\cordovahttp\CordovaHttpDownload.java:12: error: package org.apache.cordova.file does not exist import org.apache.cordova.file.FileUtils; ^ platforms\android\app\src\main\java\com\silkimen\cordovahttp\CordovaHttpDownload.java:33: error: cannot find symbol JSONObject fileEntry = FileUtils.getFilePlugin().getEntryForFile(file); ^ symbol: variable FileUtils location: class CordovaHttpDownload Note: Some input files use or override a deprecated API. Note: Recompile with -Xlint:deprecation for details. Note: Some input files use unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details. 2 errors FAILURE: Build failed with an exception. * What went wrong: Execution failed for task ':app:compileDebugJavaWithJavac'. > Compilation failed; see the compiler error output for details. * Try: Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights. * Get more help at https://help.gradle.org Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0. Use '--warning-mode all' to show the individual deprecation warnings. See https://docs.gradle.org/6.5/userguide/command_line_interface.html#sec:command_line_warnings

@erisu Its working fine when i'm installing latest plugin for the the first time, when i uninstall and try to reinstall its throwing me error in 'cordova-plugin-advanced-http' code

terryjiang2020 commented 1 year ago

Hi there, this one is creating the URL that my Android app is not able to recognize. The URL constantly returns "not found" on the device, although it exists when I check file system. Can anyone help on this?

mirko77 commented 1 year ago

So while this URL was resolved correctly with version 6.0.2

content://com.android.providers.downloads.documents/document/raw%3A%2Fstorage%2Femulated%2F0%2FDownload%2F00052123047880195188.pdf

on 7.0.0 I get error 1 (not found)