capacitor
capacitor copied to clipboard
Android range requests
This PR addresses issue #2978, which seems to be a problem carried over from the cordova plugin: ionic-team/cordova-plugin-ionic-webview/issues/453
The issue is with PathHandler, where the responseHeaders map is shared between threads, causing simultaneous requests to return the same Content-Length to the browser in case of range requests. See the illustration in ionic-team/cordova-plugin-ionic-webview/issues/453 (the same issue is present Capacitor).
This PR proposes to return a copy of the map on each invocation.
Furhermore, it introduces skipping of the initial part of the file in case of a range request not starting from zero. This brings the Android implementation better in line with its iOS counterpart, see https://github.com/ionic-team/capacitor/blob/3d4433b505252d263784ec0fafc72a9b7cd8591e/ios/Capacitor/Capacitor/WebViewAssetHandler.swift#L51
I am currently experiencing a similar issue: https://github.com/ionic-team/capacitor/issues/6021#issuecomment-1470121335
Are there any updates on this PR?
Furhermore, it introduces skipping of the initial part of the file in case of a range request not starting from zero
@steinjak This does sound interesting, maybe it is even enough to do this? I am just wondering if it would break anything else? I would imagine for streaming you would still want to have the option to get a different start byte, but maybe it does not matter in this part of capacitor.
@visuallization I think the skipping part is unrelated here, as it's the Content-Length header that ends up with the wrong value due to a race condition. If I remember correctly, capacitor tries to serve the whole file at once, so I suspect the skipping part is mostly redundant (a long time since I looked at the code).
Sadly, there doesn't seem to be much interest in this PR.
For the next person facing this: We circumvent the issue by downloading the media file without streaming (using Angular HTTP service, fetch() would probably also work) and map it to a resource URL (URL.createObjectURL(blob)) that we point our media elements to.
are there updates?
@visuallization I think the skipping part is unrelated here, as it's the
Content-Lengthheader that ends up with the wrong value due to a race condition. If I remember correctly, capacitor tries to serve the whole file at once, so I suspect the skipping part is mostly redundant (a long time since I looked at the code).Sadly, there doesn't seem to be much interest in this PR.
For the next person facing this: We circumvent the issue by downloading the media file without streaming (using Angular
HTTPservice,fetch()would probably also work) and map it to a resource URL (URL.createObjectURL(blob)) that we point our media elements to.
@steinjak I patched capacitor in our project with your fix and it turns out the skipping part is actually an issue as some audio will just stop un mid sentence. So I removed the skipping part and now everything works as intended! Thanks for the fix, it helped a lot!
Having the same issue with Range requests. This bug is easy to reproduce by putting multiple <audio> tags on a page. The concurrent request the browser makes leads to the threading issues and the range headers response corruption. Right now i'm, having to patch the Java file during the build to disable the Range requests completely which is a terrible solution.
I've tested the PR and it solves our issue. It's also a lot better than the current status quo. Let me know if I can help do something to have the PR merged. Thanks
How can we help with this PR? This seems like a fairly critical issue when loading anything larger and in parallel (a reasonable requirement) from the filesystem in Android.