cordova-plugin-ionic-webview icon indicating copy to clipboard operation
cordova-plugin-ionic-webview copied to clipboard

Range requests returning corrupt information

Open yelhouti opened this issue 3 years ago • 1 comments

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');
};

yelhouti avatar Dec 19 '20 16:12 yelhouti

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(),
      ...]

biguphpc avatar Nov 14 '23 18:11 biguphpc