/** * 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; // 是否开启mis更新映射表 var misEnableState=true; // 获取兴趣包前缀 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) { // if (area == "local") { 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 onData(interest, data) { // printLine("Got data packet with name " + data.getName().toUri()); // printLine(data.getContent().buf().toString('binary')); } function onTimeout(interest) { // printLine("Time out for interest " + interest.getName().toUri()); } // 增加映射表项时,判断该表项是否重复 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; // 判断某个字符串是否是一个搜索url function isSearchUrl(urlString){ 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" ]; 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; } } // 对小于0的数取0 function getPositiveNum(num) { if(num>0){ return num; }else{ return 0; } } // 传入一个搜索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{} return content.replace(/%2F/g,'/'); } // 判断某个字符串是否包含映射表中的表项 function isIncludedRules(urlString) { var flag=0; for (var i=0; i=0)||(urlString.indexOf(afterDecodeOrigin)>=0)) { flag=1; break; } } if(flag===0){ // alert("it do not includes rules"); return false; }else{ // alert("it includes rules"); // console.log("it includes rules"); return true; } } // 模糊判断一个string是否是一个合法前缀 function isRightfulPrefix(urlString){ if(urlString===''){ return false; } if(urlString.indexOf('.')>=0){ return false; } if((urlString.indexOf('/')!==0)&&(urlString.indexOf('%2F')!==0)){ // alert("没/"); return false; } return true; } // 判断某个字符串是否是映射表的一个前缀表项 // 判断某个字符串是否包含映射表中的表项 function isRulesPrefix(urlString) { // alert("要判断的urlString: "+urlString); // 先进行模糊判断 // if(urlString===''){ // return false; // } // if(urlString.indexOf('.')>=0){ // return false; // } // if((urlString.indexOf('/')!==0)&&(urlString.indexOf('%2F')!==0)){ // // alert("没/"); // return false; // } if(!isRightfulPrefix(urlString)){ return false; } // 再遍历本地映射表 var flag=0; for (var i=0; i=0)||(urlString.indexOf(afterDecodeOrigin)>=0)) { flag=1; originString=rule.origin; break; } } return originString; } // 剪切不包含.这个字符的URI的http头 function cutHttpHead(uri) { // 判断是http:还是https: var startIndex=0; if(uri.indexOf("https:")>=0){ startIndex=8; }else if(uri.indexOf("http:")>=0){ startIndex=7; } // 判断uri中是否含有.这个字符 if(uri.indexOf('.')>=0){ return ""; }else{ var uritmp=uri.substr(startIndex); if(uritmp.indexOf(0)==='/'){ return uritmp; }else{ return '/'+uritmp; } } } // 根据传入的uri获取前缀,从而更新本地映射表 function updateStorageBasedUri(uri) { // alert("begin upgrate"); var uriCut=cutHttpHead(uri); // alert("uricut: "+uriCut); if(uriCut===""){ }else{ express(uriCut); } } // 根据传入的前缀,更新本地映射表 function updateStorageBasedPrefix(prefix) { express(prefix); } /* Handle redirect */ function handleRedirect(details) { // 判断url是否是一个搜索url,并根据搜索内容,判断是否直接命中本地映射表 var searchContent=getSearchContent(details.url); // alert("sc: "+searchContent); // 判断url去掉头部之后是否直接命中本地映射表 var cutHeadString=cutHttpHead(details.url); // 如果该搜索内容或网址命中了缓存中的映射表前缀,则重定向 if(isRulesPrefix(searchContent)||isRulesPrefix(cutHeadString)){ // alert("sc: "+searchContent+" isRules: "+isRulesPrefix(searchContent)); // alert("cut: "+cutHeadString+" isRules: "+isRulesPrefix(cutHeadString)); var prefixTemp=""; if(searchContent!==""){ prefixTemp=searchContent; }else{ prefixTemp=cutHeadString; } details.url = "http://" + prefixTemp; // alert("detail-url: "+details.url); if (_redirect_promise_supported) { var promise = new Promise(function (resolve, reject) { var blockingResponse = redirect(details); return resolve(blockingResponse); }); return promise; } else { // alert("redirect: "+details.url); return redirect(details); } } // 如果没有命中缓存映射表,但是它是一个检索内容的网址, // 则根据该内容更新本地缓存之后,进行重定向 if(searchContent!==""){ // alert("检索内容了呢:"+searchContent); if ((misEnableState === true)&&isRightfulPrefix(searchContent)) { // 如果检索内容模糊判断是一个前缀,且mis同步是开着的 // alert("成功加载mis的IP: "+misHost+"; misPrefix: "+misPrefix); var host = misHost; // Connect to the forwarder with a WebSocket. var face = new Face({host: host}); var name = new Name(getInterestPrefix()); var interest=new Interest(name); interest.setMustBeFresh(true); var jsonPrefix=getJsonString(searchContent); interest.setApplicationParameters(new Blob(jsonPrefix)); interest.setInterestLifetimeMilliseconds(2000); // alert("express Interest"); 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; // alert("code: "+StatusCode+", "+targetUri); if((StatusCode===200)&&(targetUri!=="")) { var editingRule = new Rule(); editingRule.enable = true; editingRule.description = "initial based on MIS"; editingRule.origin = searchContent; 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); // alert("已经重新更新了本地映射表"); // 缓存映射表更新之后,执行重定向操作 details.url = "http://" + searchContent; } // alert("根据本地缓存要重定向了哦"); if (_redirect_promise_supported) { var promise = new Promise(function (resolve, reject) { var blockingResponse = redirect(details); return resolve(blockingResponse); }); return promise; } else { // alert("deurl: "+details.url); return redirect(details); } }, function (interest) { // alert("time out..."); // mis系统崩溃,没有给任何应答,直接执行重定向操作 if (_redirect_promise_supported) { var promise = new Promise(function (resolve, reject) { var blockingResponse = redirect(details); return resolve(blockingResponse); }); return promise; } else { return redirect(details); } }); }else{ // 直接尝试重定向 if (_redirect_promise_supported) { var promise = new Promise(function (resolve, reject) { var blockingResponse = redirect(details); return resolve(blockingResponse); }); return promise; } else { return redirect(details); } } }else{ // 如果不是进行搜索,且本地没有命中映射表,则异步请求mis更新映射表 if((misEnableState===true)&&isRightfulPrefix(cutHeadString)){ updateStorageBasedUri(details.url); } // 并进行重定向 if (_redirect_promise_supported) { var promise = new Promise(function (resolve, reject) { var blockingResponse = redirect(details); return resolve(blockingResponse); }); return promise; } else { return redirect(details); } } } // /* Handle redirect */ // function handleRedirect(details) { // // alert("misEnableState: " + misEnableState); // // alert("detail-url: "+details.url); // if(isSearchUrl(details.url)){ // if (misEnableState === true) { // updateStorageBasedUri(details.url); // } // } // // 判断是否是搜索映射表表项,如果是,直接跳转到映射界面 // if(isSearchForRules(details.url)){ // // alert("捕获到了一个前缀搜索: "+details.url); // details.url="http://"+getIncludedRules(details.url); // // alert("B-url: "+details.url); // }else{ // if (misEnableState === true) { // updateStorageBasedUri(details.url); // } // } // // if (_redirect_promise_supported) { // var promise = new Promise(function (resolve, reject) { // var blockingResponse = redirect(details); // return resolve(blockingResponse); // }); // // alert("修改后的details.url-0: "+details.url); // // history.pushState({},"Wow Title","/my/awesome/url"); // return promise; // } else { // // history.pushState({},"Wow Title","/my/awesome/url"); // // alert("修改后的details.url-1: "+details.url); // 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"] );