iosWebViewFix/ios/Classes/PluginScriptsJS/InterceptFetchRequestJS.swift

203 lines
7.5 KiB
Swift

//
// 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);
"""