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.

Cordova 10 on android, disabled AndroidInsecureFileModeEnabled and local Files/cdvfiles

See original GitHub issue

Bug Report

Problem

We are creating local Image files, that should be displayed in an <img src="LOCAL" /> Until cordova 9, that worked with “file:///…” (and CSP including file:, filesystem: and cdvfile:)

What is expected to happen?

Images should load the local File - with “file:///” URL or at least with cdvfile:// URL.

What does actually happen?

Now, “file:” does not work at all (not allowed to load) - after converting the local ULR to a cdvfile though, the Request dies with “net::ERR_UNKNOWN_URL_SCHEME”

If I set “AndroidInsecureFileModeEnabled” to TRUE, everything is working again fine. But I would really prefer to not use this Setting for other reasons. These Images are the only time, the WebView comes in contact with local Files.

Environment, Platform, Device

all devices

Version information

Cordova 10 on android 11, android 12 Beta 4.

Checklist

  • I searched for existing GitHub issues
  • I updated all Cordova tooling to most recent version
  • I included all the necessary information above

I was able to solve this by a very annoying hack - i use Cordova Filesystem Methods to create a data: String out of the File. But thats very time-consuming, ugly and complicated to handle with a lot of Files. Do I missed some kind of Setting or anything similar, that stops this Functionality from working?

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:3
  • Comments:11 (2 by maintainers)

github_iconTop GitHub Comments

3reactions
jackyseecommented, Nov 25, 2021

My workaround is convert those file:// to __file__ in js. And create a pathHandler in plugin. In my case I just clone cdv photo plugin and modify the source. One thing to notice that you cannot get query parameter in path, so in the case of cdvphotolibrary I need to specially handle them. Only url that needs DOM access should be converted. file:// url can work fine when using e.g. fs.getFile


  @Override   
  public CordovaPluginPathHandler getPathHandler() {
      return new CordovaPluginPathHandler(new WebViewAssetLoader.PathHandler() {
            @Nullable
            @Override
            public WebResourceResponse handle(@NonNull String path) {
                Log.d(TAG, "Path Handler " + path);
                //e.g. cdvphotolibrary/thumbnail/photoId=3112&width=512&height=384&quality=0.8
                if(path.startsWith(PHOTO_LIBRARY_PROTOCOL)) {
                    path = path.replaceAll("^cdvphotolibrary/", "cdvphotolibrary://");
                    path = path.replaceAll("thumbnail/", "thumbnail?");
                    path = path.replaceAll("photo/", "photo?");
                    Uri uri = Uri.parse(path);
                    Log.d(TAG, "URI " + uri);
                    Uri remappedUri = remapUri(uri);
                    Log.d(TAG, "RemappedUri " + uri);
                    if(remappedUri != null) {
                        try {
                            CordovaResourceApi.OpenForReadResult result = handleOpenForRead(remappedUri);
                            Log.d(TAG, "Result " + result.inputStream.available());
                            return new WebResourceResponse(result.mimeType, "utf-8", result.inputStream);
                        } catch (IOException e) {
                            LOG.e(TAG, "error open cdvphotolibrary resource "+ e);
                        }
                    }
                }

                if(path.startsWith("__file__/")) {
                    File file = new File(path.replaceAll("^__file__/", "/"));
                    Uri fileUri = Uri.fromFile(file);
                    Log.d(TAG, "fileUri " + fileUri);
                    String mimeType = webView.getResourceApi().getMimeType(fileUri);
                    Log.d(TAG, "mimeType " + mimeType);
                    try {
                        InputStream is = getContext().getContentResolver().openInputStream(fileUri);
                        Log.d(TAG, "Result " + is.available());
                        return new WebResourceResponse(mimeType, "utf-8", is);
                    } catch(Exception e) {
                        LOG.e(TAG, "error open file resource "+ e);
                    }
                }
                return null;
            }
        });
  }

2reactions
plexoramacommented, Jul 2, 2022

cordova-android@10 : overriden remapUri in plugin is not being called in plugin even if “AndroidInsecureFileModeEnabled” is enabled. still using cordova-android@9

I’ve encountered the same issue with cordova-android@10, remapUri is never called. The reason is for this is, the deprecated shouldInterceptRequest(WebView view, String url) method - implement in the cordova SystemWebViewClient-class - is never called by the WebView. As a consequence, the remapUri-method is never invoked. However, there are two versions of the shouldInterceptRequest-method. The ‘new’ version of shouldInterceptRequest is called by WebView, which then invokes assetLoader.shouldInterceptRequest - that however is wrong in my opinion. It should call the old shouldInterceptRequest-method first and if that returns null, the assetLoader.shouldInterceptRequest-method should be invoked as a fallback.

if you want to re-enable the remapUri-invocation, change the new shouldInterceptRequest-method CordovaLib/src/org/apache/cordova/engine/SystemWebViewClient.java as follows:

replace this method:

public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {

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

with the following code:

public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {

        Log.d(TAG, String.format("shouldInterceptRequest(): request=%s",request.getUrl()));
        WebResourceResponse response = shouldInterceptRequest(view,request.getUrl().toString());
        if (response != null){
            return response;
        }
        return this.assetLoader.shouldInterceptRequest(request.getUrl());
}

This will re-enable the old remapUri-behaviour.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Cordova Android 10.0.0 Released!
We are happy to announce that we have just released Cordova Android 10.0.0! This is one of Cordova's supported platforms for building ...
Read more >
[GitHub] [cordova-android] breautek commented on issue #1361 ...
[GitHub] [cordova-android] breautek commented on issue #1361: Cordova 10 on android, disabled AndroidInsecureFileModeEnabled and local Files/cdvfiles.
Read more >
cordova 10 has CORS issue with allowList - Stack Overflow
I just migrated my project from Cordova 9 to Cordova 10.1.1, now targeting Android 12 (API 31), along with Firebase for OAuth (per...
Read more >
Upgrading Cordova-Android Version to Meet Required ... - Ionic
Upgrading Cordova-Android Version to Meet Required Android API Levels. Avatar. Kimberly McIntyre. 10 months ago; Updated.
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