Files
MINResolveV2/background.js
T
2020-10-09 20:26:55 +08:00

646 lines
21 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* The background script to handle url redirection.
*/
var storage = null;
var downloading = false;
var downloadTimer = null;
// 存储MIS的IP
var misHost="121.15.171.92";
// 请求映射表项时兴趣包使用的前缀
var misPrefix="/mis/resolve";
// 兴趣包前缀序号
var misPrefixNum=0;
// 兴趣包过期时间:默认两秒
var interestLifetimeMilliseconds=2000;
// 是否开启mis更新映射表
var misEnableState=true;
// 全局变量,用于设置是否刷新当前active的界面
// var myInterval=null;
// min协议的URI协议头
var minProtocolHeader="min/";
// 适配的其它浏览器默认协议:
// 插件将自动拦截该头部,以做协议转换
var httpProtocolHeader="http://";
var httpsProtocolHeader="https://";
// 适配的搜索引擎
var searchLibs=[
// 百度
"https://www.baidu.com",
"http://www.baidu.com",
// 谷歌
"https://www.google.com",
"http://www.google.com",
// 搜狗
"https://www.sogou.com",
"http://www.sogou.com",
// 360
"https://www.so.com",
"http://www.so.com",
// bing
"https://cn.bing.com",
"http://cn.bing.com",
// bing
"https://www.bing.com",
"http://www.bing.com"
];
// 获取兴趣包前缀
function getInterestPrefix() {
misPrefixNum++;
browser.storage.local.set({'misPrefixNum':misPrefixNum});
return misPrefix+'/'+misPrefixNum;
}
// 加载mis的IP
function loadMisHost() {
browser.storage.local.get('misHostIP',function (result) {
if($.isEmptyObject(result)){
// alert("hostIP: null");
browser.storage.local.set({'misHostIP':misHost});
}else{
// alert("hostIP: "+result.misHostIP);
misHost=result.misHostIP;
}
});
browser.storage.local.get('misPrefix',function (result) {
if($.isEmptyObject(result)){
// alert("misPrefix: null");
browser.storage.local.set({'misPrefix':misPrefix});
}else{
// alert("misPrefix: "+result.misPrefix);
misPrefix=result.misPrefix;
}
});
browser.storage.local.get('misPrefixNum',function (result) {
if($.isEmptyObject(result)){
// alert("misPrefix: null");
browser.storage.local.set({'misPrefixNum':misPrefixNum});
}else{
// alert("misPrefix: "+result.misPrefix);
misPrefixNum=result.misPrefixNum;
}
});
browser.storage.local.get('misEnableState',function (result) {
if($.isEmptyObject(result)){
// alert("misPrefix: null");
browser.storage.local.set({'misEnableState':misEnableState});
}else{
// alert("misPrefix: "+result.misPrefix);
misEnableState=result.misEnableState;
// alert("48641");
}
});
}
/* Reload callback */
function reload(result) {
storage = new Storage();
if (result && result.storage) {
storage.fromObject(result.storage);
// resetDownloadTimer();
}
}
/* Auto reload */
browser.storage.onChanged.addListener(function (changes, area) {
load("storage", reload);
loadMisHost();
});
/* The first time of loading storage */
load("storage", reload);
loadMisHost();
// alert("成功加载mis的IP: "+misHost+"; misPrefix: "+misPrefix);
function getJsonString(u_identifier){
var jsonObj={
"Type":"user-act",
"Command":"Resolve",
"QueryCode":2,
"U_identifier":u_identifier
};
// return jsonObj;
return JSON.stringify(jsonObj);
}
function onTimeout(interest)
{
console.log("time out...");
}
// 增加映射表项时,判断该表项是否重复
function addCustomRule(editingRule) {
var flag=0;
for (var i=0; i<storage.customRules.length; i++) {
var rule = storage.customRules[i];
if ((rule.origin === editingRule.origin) && (rule.target === editingRule.target)) {
flag=1;
}
}
if(flag===0){
storage.customRules.push(editingRule);
}
}
// 刷新正在浏览的浏览器界面
function refreshActiveTab () {
chrome.tabs.query({active: true}, function(tabs) {
var tabIndex = tabs[0].index;
chrome.tabs.query({}, function(tabs) {
chrome.tabs.reload(tabs[tabIndex].id);
// var o;
// o.url="https://www.csdn.net/";
// chrome.tabs.create(o,function () {
// console.log("test");
// });
})
});
console.log("refresh########");
}
function express(prefixUri) {
// alert("成功加载mis的IP: "+misHost+"; misPrefix: "+misPrefix);
// Connect to the forwarder with a WebSocket.
var face = new Face({host: misHost});
var name = new Name(getInterestPrefix());
var jsonPrefix=getJsonString(prefixUri);
var interest=new Interest(name);
interest.setMustBeFresh(true);
interest.setApplicationParameters(new Blob(jsonPrefix));
interest.setInterestLifetimeMilliseconds(interestLifetimeMilliseconds);
// alert("express Interest: "+jsonPrefix+" ; "+interest.name.toString());
face.expressInterest(interest, function(interest,data){
var targetJsonString=data.getContent().buf().toString('binary');
// alert("targetJsonString: "+targetJsonString);
var targetJson=JSON.parse(targetJsonString);
// 将targetJson解析成targetUri
var StatusCode=targetJson.StatusCode;
var targetUri=targetJson.Message;
if((StatusCode===200)&&(targetUri!=="")) {
var editingRule = new Rule();
editingRule.enable = true;
editingRule.description = "initial based on MIS";
editingRule.origin = prefixUri;
editingRule.target = targetUri;
editingRule.exclude = "";
editingRule.example = "";
editingRule.process = "";
editingRule.methods = [];
editingRule.types = [];
// storage.customRules.push(editingRule);
addCustomRule(editingRule);
/* save */
save({"storage": storage});
load("storage", reload);
// setTimeout(refreshActiveTab(),2000);
}else{
// mis没有该前缀对应的映射
}
}, onTimeout);
}
// /* Download online rules */
// function downloadOnlineURLs() {
// /* Still downloading */
// if (!storage.onlineURLs || storage.onlineURLs.length <=0 || downloading) {
// return;
// }
// downloading = true;
// var toDownload = []; // URLs that need to be downloaded
// for (var i = 0; i < storage.onlineURLs.length; i++) {
// var onlineURL = storage.onlineURLs[i];
// if (onlineURL.auto && onlineURL.enable && onlineURL.url !== "") {
// toDownload.push(onlineURL.url);
// }
// }
// if (toDownload.length === 0) {
// sendMessage("downloaded");
// }
// var downloadErrors = [];
// var parseErrors = [];
// for (var i = 0; i<toDownload.length; i++) {
// download(toDownload[i], function (url, content) {
// toDownload.remove(url);
// if (content) {
// try {
// var json;
// // content may be a string or json object
// if (typeof content === "string") {
// json = JSON.parse(content);
// } else {
// json = content;
// }
// json.url = url;
// json.enable = true;
// json.downloadAt = new Date();
// /* To compact with gooreplacer */
// /* version < 1.0, version >= 1.0 doesn't change */
// if (!json.version || json.version < "1.0") {
// var rules = [];
// for (var key in json.rules) {
// var rule = json.rules[key];
// rules.push({
// origin: key,
// target: rule.dstURL,
// enable: rule.enable === undefined ? true : rule.enable,
// kind: rule.kind
// });
// }
// json.rules = rules;
// }
// /* replace the onlineURL */
// for (var j = 0; j < storage.onlineURLs.length; j++){
// if (storage.onlineURLs[j].url == url){
// storage.onlineURLs[j] = new OnlineURL();
// storage.onlineURLs[j].fromObject(json);
// break;
// }
// }
// } catch (err) {
// parseErrors.push(url);
// console.error(err);
// }
// }
// else {
// downloadErrors.push(url);
// }
// if (toDownload.length <= 0) {
// downloading = false;
// sendMessage("downloaded");
// if (downloadErrors.length > 0) {
// sendMessage("downloadError", downloadErrors);
// }
// if (parseErrors.length > 0) {
// sendMessage("parseError", parseErrors);
// }
// storage.updatedAt = (new Date()).toISOString();
// save({"storage": storage});
// }
// });
// }
// }
//
// /* Reset download timer to download online urls */
// /* Setup a listener if alarm api supported */
// if (browser.alarms) {
// browser.alarms.onAlarm.addListener(function (alarm) {
// if (alarm.name == "download") {
// downloadOnlineURLs();
// }
// })
// }
//
// /* Reset the download timer */
// function resetDownloadTimer() {
// var interval = 900; // Default 15min
// if (storage.updateInterval) {
// interval = parseInt(storage.updateInterval);
// }
// /* If the browser support alarms api */
// if (browser.alarms) {
// browser.alarms.create("download", {
// periodInMinutes: Math.ceil(interval / 60)
// });
// }
// else {
// /* With setInterval */
// if (downloadTimer != null) {
// clearInterval(downloadTimer);
// }
// interval = interval * 1000; // In milli-seconds
// downloadTimer = setInterval(function () {
// if (storage.enable) {
// downloadOnlineURLs();
// }
// }, interval);
// }
// }
/* Handle runtime messages */
// browser.runtime.onMessage.addListener(function (message, sender, sendResponse) {
// if (message.method == "download" && !downloading) {
// // downloadOnlineURLs();
// }
// else if (message.method == "isDownloading") {
// // sendResponse(downloading);
// }
// else {
// // console.error("Unknown method");
// }
// });
function redirect(details) {
if (storage.enable && details.url) {
var newURL = storage.redirect(details.url, details.method, details.type);
if (newURL){
return {
redirectUrl: newURL
}
}
}
return {};
}
// var _redirect_promise_supported = false;
// 对小于0的数取0
function getPositiveNum(num) {
if(num>0){
return num;
}else{
return 0;
}
}
// 判断某个字符串是否是一个搜索url:搜索某个内容的URI
function isSearchUrl(urlString){
var flag=0;
for(var i=0;i<searchLibs.length;i++){
if(urlString.indexOf(searchLibs[i])>=0){
flag=1;
break;
}
}
var haveSearchString=getPositiveNum(urlString.indexOf("?wd="))
+getPositiveNum(urlString.indexOf("&wd="))
+getPositiveNum(urlString.indexOf("?q="))
+getPositiveNum(urlString.indexOf("&q="))
+getPositiveNum(urlString.indexOf("?query="))
+getPositiveNum(urlString.indexOf("&query="));
if((flag>0)&&(haveSearchString>0)){
// alert("it is a searchUrl: "+urlString);
return true;
}else{
return false;
}
}
// 传入一个搜索uri,获取其中的搜索数值;
// 传入一个非搜索uri,返回空字符串
function getSearchContent(uriString) {
if(!isSearchUrl(uriString)){
return "";
}
var content="";
if(uriString.indexOf("//www.baidu.com")>=0){
// &wd= [end] 或 &wd= &
var startIndex=getPositiveNum(uriString.indexOf("?wd="))
+getPositiveNum(uriString.indexOf("&wd="))+4;
var lastString=uriString.substring(startIndex);
var endIndex=lastString.indexOf('&');
if(endIndex>=0){
content=lastString.substring(0,endIndex);
}else{
content=lastString;
}
}else if(uriString.indexOf("//www.google.com")>=0){
// ?q= &
var startIndex=getPositiveNum(uriString.indexOf("?q="))
+getPositiveNum(uriString.indexOf("&q="))+3;
var lastString=uriString.substring(startIndex);
var endIndex=lastString.indexOf('&');
if(endIndex>=0){
content=lastString.substring(0,endIndex);
}else{
content=lastString;
}
}else if(uriString.indexOf("//www.sogou.com")>=0){
// &query= [end]
var startIndex=getPositiveNum(uriString.indexOf("?query="))
+getPositiveNum(uriString.indexOf("&query="))+7;
var lastString=uriString.substring(startIndex);
var endIndex=lastString.indexOf('&');
if(endIndex>=0){
content=lastString.substring(0,endIndex);
}else{
content=lastString;
}
}else if(uriString.indexOf("//www.so.com")>=0){
// &q= [end]
var startIndex=getPositiveNum(uriString.indexOf("?q="))
+getPositiveNum(uriString.indexOf("&q="))+3;
var lastString=uriString.substring(startIndex);
var endIndex=lastString.indexOf('&');
if(endIndex>=0){
content=lastString.substring(0,endIndex);
}else{
content=lastString;
}
}else if(uriString.indexOf("//cn.bing.com")>=0){
// q= &
var startIndex=getPositiveNum(uriString.indexOf("?q="))
+getPositiveNum(uriString.indexOf("&q="))+3;
var lastString=uriString.substring(startIndex);
var endIndex=lastString.indexOf('&');
if(endIndex>=0){
content=lastString.substring(0,endIndex);
}else{
content=lastString;
}
}else if(uriString.indexOf("//www.bing.com")>=0){
// q= &
var startIndex=getPositiveNum(uriString.indexOf("?q="))
+getPositiveNum(uriString.indexOf("&q="))+3;
var lastString=uriString.substring(startIndex);
var endIndex=lastString.indexOf('&');
if(endIndex>=0){
content=lastString.substring(0,endIndex);
}else{
content=lastString;
}
}else{}
return decodeURIComponent(content);
}
// 模糊判断一个string是否是一个合法前缀/合法标识
function isRightfulPrefix(string){
// 不能为空
if(string===''){
return false;
}
// 不能包含.
if(string.indexOf('.')>=0){
return false;
}
// 第一个字符必须是/
var stringDecoded=decodeURIComponent(string);
if(stringDecoded.indexOf('/')!==0){
return false;
}
return true;
}
// 判断一个url是否是一个min协议的合法URI
function isRightfulMinURI(urlString){
var urlStringDecoded=decodeURIComponent(urlString);
// 长度要大于min协议头的长度
if(urlStringDecoded.length<=minProtocolHeader.length){
return false;
}
// 前几个字符必须是min协议头
if(urlStringDecoded.indexOf(minProtocolHeader)!==0){
return false;
}
// 协议头后面跟的是一个合法前缀/合法标识
var prefix=urlStringDecoded.substring(minProtocolHeader.length);
if(!isRightfulPrefix(prefix)){
return false;
}
return true;
}
// 从一个合法minUri提取出前缀
function getPrefixFromMinURI(minURI){
if(isRightfulMinURI(minURI)){
var urlStringDecoded=decodeURIComponent(minURI);
return urlStringDecoded.substring(minProtocolHeader.length);
}else{
return "";
}
}
// 判断某个没使用url编码的string是否是映射表的一个表项
function isCustomRulesItemString(string) {
// 遍历本地映射表
var flag=0;
for (var i=0; i<storage.customRules.length; i++) {
var rule = storage.customRules[i];
if (string===rule.origin) {
flag=1;
break;
}
}
if(flag===0){
// alert("it is not rules: "+string);
return false;
}else{
// alert("it is rules: "+string);
// console.log("it includes rules");
return true;
}
}
// 判断某个minUrl中的前缀是否是映射表的一个表项
function isCustomRulesItemMinURI(minURI) {
// 如果不是min协议URI,返回false
var prefix=getPrefixFromMinURI(minURI);
if(prefix===""){
return false;
}
// alert("是minuri");
return isCustomRulesItemString(prefix);
}
// 根据传入的前缀/标识,更新本地映射表
function updateStorageBasedPrefix(prefix) {
if(isRightfulPrefix(prefix)){
express(prefix);
}
}
// 根据传入的MINuri获取前缀,从而更新本地映射表
function updateStorageBasedMinURI(minURI) {
// alert("begin upgrate");
var prefix=getPrefixFromMinURI(minURI);
if(!(prefix==="")){
express(prefix);
}
}
function sleep(numberMillis) {
// alert("开始卡死cpu");
var now = new Date();
var exitTime = now.getTime() + numberMillis;
while (true) {
now = new Date();
if (now.getTime() > exitTime)
// alert("释放cpu");
return true;
}
}
// 将一个http或https请求的协议头去掉
function getCutHttpHeader(urlString){
var urlString=decodeURIComponent(urlString);
if(urlString.indexOf(httpProtocolHeader)===0){
return urlString.substring(httpProtocolHeader.length);
}else if(urlString.indexOf(httpsProtocolHeader)===0){
return urlString.substring(httpsProtocolHeader.length);
}else{
return "";
}
}
/* Handle redirect */
function handleRedirect(details) {
// alert(details.url);
// 判断url是否是一个搜索url,并根据搜索内容,判断是否直接命中本地映射表
var searchContent=getSearchContent(details.url); // 已解码
var minUri=getCutHttpHeader(details.url); //已解码
// alert("?s: "+searchContent+" ; ?u: "+minUri);
// 如果该搜索内容或网址命中了缓存中的映射表前缀,则重定向
if(isCustomRulesItemMinURI(searchContent)||isCustomRulesItemMinURI(minUri)){
// alert("s: "+searchContent+" ; u: "+minUri);
var prefixTemp="";
if(searchContent!==""){
prefixTemp=getPrefixFromMinURI(searchContent);
}else{
prefixTemp=getPrefixFromMinURI(minUri);
}
details.url = httpProtocolHeader+prefixTemp; //如果映射表中加了http协议头,这里就不要加了
return redirect(details);
}
// 如果没有命中缓存映射表,但是它是一个检索内容的网络请求
if(searchContent!==""){
// alert("检索内容了呢:"+searchContent);
if ((misEnableState === true)&&isRightfulMinURI(searchContent)) {
details.url = httpProtocolHeader + searchContent;
// 如果检索内容模糊判断是一个前缀,且mis同步是开着的
// alert("成功加载mis的IP: "+misHost+"; misPrefix: "+misPrefix+", searchContent: "+searchContent);
updateStorageBasedMinURI(searchContent);
// alert("重定向url:"+details.url);
return {
redirectUrl: details.url
};
}else{
// 如果是搜索了一个内容,该内容没命中缓存,
// 且mis没开,或该内容不符合前缀标识符表示规则,
// 则该内容一定是不会命中一个映射表项的
return {};
}
}else{
// 如果本地没有命中映射表,且没有检索内容,是一个正常的网页
if((misEnableState===true)&&isRightfulMinURI(minUri)){
updateStorageBasedMinURI(minUri);
}
return redirect(details);
}
}
/* Since firefox 52, could return a promise to handles asynchronously */
// if (browser.runtime.getBrowserInfo) {
// function checkRedirectPromise(info) {
// if (info.name == "Firefox") {
// if (parseInt(info.version.split('.')[0]) >= 52) {
// _redirect_promise_supported = true;
// }
// }
// }
// var gettingInfo = browser.runtime.getBrowserInfo();
// gettingInfo.then(checkRedirectPromise)
// }
/* Add listener */
browser.webRequest.onBeforeRequest.addListener(
handleRedirect,
{urls: ["<all_urls>"]},
["blocking"]
);