// // InterceptFetchRequestsJS.swift // flutter_inappwebview // // Created by Lorenzo Pichilli on 16/02/21. // import Foundation let INTERCEPT_FETCH_REQUEST_JS_PLUGIN_SCRIPT_GROUP_NAME = "IN_APP_WEBVIEW_INTERCEPT_FETCH_REQUEST_JS_PLUGIN_SCRIPT" let FLAG_VARIABLE_FOR_SHOULD_INTERCEPT_FETCH_REQUEST_JS_SOURCE = "window.\(JAVASCRIPT_BRIDGE_NAME)._useShouldInterceptFetchRequest" let INTERCEPT_FETCH_REQUEST_JS_PLUGIN_SCRIPT = PluginScript( groupName: INTERCEPT_FETCH_REQUEST_JS_PLUGIN_SCRIPT_GROUP_NAME, source: INTERCEPT_FETCH_REQUEST_JS_SOURCE, injectionTime: .atDocumentStart, forMainFrameOnly: false, requiredInAllContentWorlds: true, messageHandlerNames: []) let INTERCEPT_FETCH_REQUEST_JS_SOURCE = """ \(FLAG_VARIABLE_FOR_SHOULD_INTERCEPT_FETCH_REQUEST_JS_SOURCE) = true; (function(fetch) { if (fetch == null) { return; } function convertHeadersToJson(headers) { var headersObj = {}; for (var header of headers.keys()) { var value = headers.get(header); headersObj[header] = value; } return headersObj; } function convertJsonToHeaders(headersJson) { return new Headers(headersJson); } function convertBodyToArray(body) { return new Response(body).arrayBuffer().then(function(arrayBuffer) { var arr = Array.from(new Uint8Array(arrayBuffer)); return arr; }) } function convertArrayIntBodyToUint8Array(arrayIntBody) { return new Uint8Array(arrayIntBody); } function convertCredentialsToJson(credentials) { var credentialsObj = {}; if (window.FederatedCredential != null && credentials instanceof FederatedCredential) { credentialsObj.type = credentials.type; credentialsObj.id = credentials.id; credentialsObj.name = credentials.name; credentialsObj.protocol = credentials.protocol; credentialsObj.provider = credentials.provider; credentialsObj.iconURL = credentials.iconURL; } else if (window.PasswordCredential != null && credentials instanceof PasswordCredential) { credentialsObj.type = credentials.type; credentialsObj.id = credentials.id; credentialsObj.name = credentials.name; credentialsObj.password = credentials.password; credentialsObj.iconURL = credentials.iconURL; } else { credentialsObj.type = 'default'; credentialsObj.value = credentials; } } function convertJsonToCredential(credentialsJson) { var credentials; if (window.FederatedCredential != null && credentialsJson.type === 'federated') { credentials = new FederatedCredential({ id: credentialsJson.id, name: credentialsJson.name, protocol: credentialsJson.protocol, provider: credentialsJson.provider, iconURL: credentialsJson.iconURL }); } else if (window.PasswordCredential != null && credentialsJson.type === 'password') { credentials = new PasswordCredential({ id: credentialsJson.id, name: credentialsJson.name, password: credentialsJson.password, iconURL: credentialsJson.iconURL }); } else { credentials = credentialsJson; } return credentials; } window.fetch = async function(resource, init) { if (\(FLAG_VARIABLE_FOR_SHOULD_INTERCEPT_FETCH_REQUEST_JS_SOURCE) == null || \(FLAG_VARIABLE_FOR_SHOULD_INTERCEPT_FETCH_REQUEST_JS_SOURCE) == true) { var fetchRequest = { url: null, method: null, headers: null, body: null, mode: null, credentials: null, cache: null, redirect: null, referrer: null, referrerPolicy: null, integrity: null, keepalive: null }; if (resource instanceof Request) { fetchRequest.url = resource.url; fetchRequest.method = resource.method; fetchRequest.headers = resource.headers; fetchRequest.body = resource.body; fetchRequest.mode = resource.mode; fetchRequest.credentials = resource.credentials; fetchRequest.cache = resource.cache; fetchRequest.redirect = resource.redirect; fetchRequest.referrer = resource.referrer; fetchRequest.referrerPolicy = resource.referrerPolicy; fetchRequest.integrity = resource.integrity; fetchRequest.keepalive = resource.keepalive; } else { fetchRequest.url = resource; if (init != null) { fetchRequest.method = init.method; fetchRequest.headers = init.headers; fetchRequest.body = init.body; fetchRequest.mode = init.mode; fetchRequest.credentials = init.credentials; fetchRequest.cache = init.cache; fetchRequest.redirect = init.redirect; fetchRequest.referrer = init.referrer; fetchRequest.referrerPolicy = init.referrerPolicy; fetchRequest.integrity = init.integrity; fetchRequest.keepalive = init.keepalive; } } if (fetchRequest.headers instanceof Headers) { fetchRequest.headers = convertHeadersToJson(fetchRequest.headers); } fetchRequest.credentials = convertCredentialsToJson(fetchRequest.credentials); return convertBodyToArray(fetchRequest.body).then(function(body) { fetchRequest.body = body; return window.\(JAVASCRIPT_BRIDGE_NAME).callHandler('shouldInterceptFetchRequest', fetchRequest).then(function(result) { if (result != null) { switch (result.action) { case 0: var controller = new AbortController(); if (init != null) { init.signal = controller.signal; } else { init = { signal: controller.signal }; } controller.abort(); break; } resource = (result.url != null) ? result.url : resource; if (init == null) { init = {}; } if (result.method != null && result.method.length > 0) { init.method = result.method; } if (result.headers != null && Object.keys(result.headers).length > 0) { init.headers = convertJsonToHeaders(result.headers); } if (result.body != null && result.body.length > 0) { init.body = convertArrayIntBodyToUint8Array(result.body); } if (result.mode != null && result.mode.length > 0) { init.mode = result.mode; } if (result.credentials != null) { init.credentials = convertJsonToCredential(result.credentials); } if (result.cache != null && result.cache.length > 0) { init.cache = result.cache; } if (result.redirect != null && result.redirect.length > 0) { init.redirect = result.redirect; } if (result.referrer != null && result.referrer.length > 0) { init.referrer = result.referrer; } if (result.referrerPolicy != null && result.referrerPolicy.length > 0) { init.referrerPolicy = result.referrerPolicy; } if (result.integrity != null && result.integrity.length > 0) { init.integrity = result.integrity; } if (result.keepalive != null) { init.keepalive = result.keepalive; } return fetch(resource, init); } return fetch(resource, init); }); }); } else { return fetch(resource, init); } }; })(window.fetch); """