Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebViewAssetLoader: Application private path Raw File access at JavaScript using XMLHttpRequest fails. #1329

Open
NitzDKoder opened this issue Aug 26, 2021 · 2 comments
Labels

Comments

@NitzDKoder
Copy link

NitzDKoder commented Aug 26, 2021

1) Image residing in Application private path.
lFileUrl =data/user/0/com.company.stub/files/myfolder/IMG-20210826-204423558thumb.jpg

2)XMLHttpRequest request done from javascript level in cordova based android app.

var xhr = new XMLHttpRequest();
xhr.open("GET", lFileUrl, true);
xhr.responseType = "blob";
xhr.onload = function(e) {
try {
}

3)WebResourceResponse shouldInterceptRequest called.
2021-08-26 20:44:34.534 32333-4065/com.company.stub D/SystemWebViewClient: shouldInterceptRequest request.getUrl(): https://localhost/data/user/0/com.company.stub/files/myfolder/IMG-20210826-204423558thumb.jpg

return this.assetLoader.shouldInterceptRequest(request.getUrl());

4)File not found exception seen as its searching in "www/"

2021-08-26 20:44:34.537 32333-4065/com.company.stub E/SystemWebViewClient: www/data/user/0/com.company.stub/files/myfolder/IMG-20210826-204423558thumb.jpg

### What is expected to happen?
1)private File access should be pass.
https://developer.android.com/reference/androidx/webkit/WebViewAssetLoader.InternalStoragePathHandler

### What does actually happen?

File not found exception seen as WebViewAssetLoader.InternalStoragePathHandler is not handled. Suggest how to handle raw file access.

## Information

https://bugs.chromium.org/p/chromium/issues/detail?id=1101250
Below change works.

InputStream is = parentEngine.webView.getContext().getAssets().open("www/" + path, AssetManager.ACCESS_STREAMING);

if(filecaseboolean){ is = new FileInputStream(new File(path));//Imagecase
 }else{
      is = parentEngine.webView.getContext().getAssets().open("www/" + path, AssetManager.ACCESS_STREAMING);
 }

### Version information

Cordova: Android 10.1.0
device : android 11
app targetsdk : 30 .

Note: if <preference name="AndroidInsecureFileModeEnabled" value="true" /> everything works fine.

  • [ ✓] I searched for existing GitHub issues
  • [ ✓] I updated all Cordova tooling to most recent version
  • [✓ ] I included all the necessary information above
@breautek breautek added the bug label Aug 31, 2021
@regnete
Copy link

regnete commented Sep 22, 2021

Facing similiar issue when using an absolute file url:

lFileUrl = 'file:///data/user/0/com.company.stub/files/myfolder/IMG-20210826-204423558thumb.jpg'
xhr.open("GET", lFileUrl, true);
xhr.onload = function() {
   console.log('loaded');
}
try {
    xhr.send();
} catch (e) {
    console.error(e);
}

Error message on console:

Not allowed to load local resource: file:///data/user/0/com.company.stub/files/myfolder/IMG-20210826-204423558thumb.jpg

Solution could be to provide something similar to window.WkWebView.convertFilePath('your/file/path'); from cordova-ios.
see https://github.com/apache/cordova-ios/blob/715c2dbfb273fb33721e8cf3f989ce7b20892d32/cordova-js-src/plugin/ios/wkwebkit.js#L28

Prototype Implementation:

async function resolveLocalFileSystemURL(uri){
        return new Promise(function (resolve, reject) {
            window.resolveLocalFileSystemURL(uri, resolve, (cause) => {
                if (cause.code == FileError.NOT_FOUND_ERR)
                    resolve(null);
                else reject({cause, uri, message: "cannot resolve local file system url"})
            });
        });
}

async function convertFilePath(uri){
   if(uri.startsWith('file://'){
      const resolved = await this.utils.resolveLocalFileSystemURL(uri);
       uri = resolved.toInternalURL().replace("cdvfile://localhost/", "https://" + location.host + "/");
   }
   return uri;
}

lFileUrl = await convertFilePath('file:///data/user/0/com.company.stub/files/myfolder/IMG-20210826-204423558thumb.jpg');
xhr.open("GET", lFileUrl, true);
xhr.onload = function() {
   console.log('loaded');
}
try {
    xhr.send();
} catch (e) {
    console.error(e);
}

Error message in chrome debugger network panel: net::ERR_CONNECTION_REFUSED

Looks like https://github.com/apache/cordova-android/blob/015db819aed3f35892d2b6035781ea4bd752149d/framework/src/org/apache/cordova/engine/SystemWebViewClient.java is missing a https://developer.android.com/reference/androidx/webkit/WebViewAssetLoader.InternalStoragePathHandler to make file:///data/user/0/com.company.stub/files available at https://localhost/files/..... The solution should be able to provide access to all locations mentioned here: https://github.com/apache/cordova-plugin-file#android-file-system-layout

@bobobobo
Copy link

bobobobo commented Feb 8, 2022

Is there any workaround for this or do we need to set AndroidInsecureFileModeEnabled to true? I can't get regular <img> or fetch working throuh WebViewAssetLoader with data in applications private data, i.e. /data/user/0/com.company.stub/files/. With AndroidInsecureFileModeEnabled it works using file:/// protocol.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants