/** * 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= 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=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 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: [""]}, ["blocking"] );