cordova-plugin-ionic-webview
cordova-plugin-ionic-webview copied to clipboard
Range requests returning corrupt information
After trying to fix issue #205 someone introduced an even bigger bug, that broke the video player sporadically. This was very hard to debug since it doesn't always manifest. https://github.com/ionic-team/cordova-plugin-ionic-webview/blob/ab7dfc06a7f8780f75800dae4f4217d1956aa7b6/src/android/com/ionicframework/cordova/webview/WebViewLocalServer.java#L251 available does not always return the size of the file (at least on android 27), result of a content-Range smaller the the reality and stopping the video in the middle. This is not the only problem, when a Range is specified that client would expect to receive only the requested part, but in this case the InputStream is returned in full, a fix would be to create a wrapping stream that skip on initialization/reset and return -1 once the end is reached (if the end is specified). For now, I have the following script that patches the code by dropping support for large requests, clearly not ideal.
afterPrepare.js:
const fs = require('fs');
const path = require('path');
module.exports = function(ctx) {
// Make sure android platform is part of build
if (!ctx.opts.platforms.includes('android')) return;
const platformRoot = path.join(ctx.opts.projectRoot, 'platforms/android');
// disable range requests
const webViewLocalServerFile = path.join(platformRoot, 'app/src/main/java/com/ionicframework/cordova/webview/WebViewLocalServer.java');
const webViewLocalServerContent = fs.readFileSync(webViewLocalServerFile, 'utf-8');
const webViewLocalServerContentEdited = webViewLocalServerContent.replace('request.getRequestHeaders().get("Range") != null)', 'request.getRequestHeaders().get("Range") != null && false) /* disabling range because of bug: https://github.com/ionic-team/cordova-plugin-ionic-webview/issues/632 */');
fs.writeFileSync(webViewLocalServerFile, webViewLocalServerContentEdited, 'utf-8');
};
Thanks @yelhouti for your snippet, it helped me patch my build using Vite.
Faced a similar issue related to this (unresolved bug) https://github.com/ionic-team/capacitor/issues/2978 and the PR related to it https://github.com/ionic-team/capacitor/pull/5956
Until this is fixed I'm using this Vite build fix vite.config.ts
:
// disabling range request in Java server because of bug: https://github.com/ionic-team/cordova-plugin-ionic-webview/issues/632
function capacitorBugFix() {
return {
name: 'range-request-bugfix',
buildEnd(error) {
if (error) return;
// no build errors disable range requests
const webViewLocalServerFile = path.resolve(__dirname, 'node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/WebViewLocalServer.java');
const webViewLocalServerContent = readFileSync(webViewLocalServerFile, 'utf-8');
const SEARCH = 'request.getRequestHeaders().get("Range") != null)';
const REPLACE = 'request.getRequestHeaders().get("Range") != null && false) /* disabling range because of bug: https://github.com/ionic-team/cordova-plugin-ionic-webview/issues/632 */';
// check and make sure it's replaced or fail the build
if (webViewLocalServerContent.indexOf(REPLACE) < 0 && webViewLocalServerContent.indexOf(SEARCH) < 0) {
throw new Error("Cannot find BUG FIX in file: " + webViewLocalServerFile)
}
const webViewLocalServerContentEdited = webViewLocalServerContent.replace(SEARCH, REPLACE);
writeFileSync(webViewLocalServerFile, webViewLocalServerContentEdited, 'utf-8');
console.log("\n[BUG FIX] disabled range requests in " + webViewLocalServerFile + "\n");
},
}
}
export default async () => {
return {
plugins: [
capacitorBugFix(),
...]