var config={ //不想访问的东西,节约流量 "404":[ "http://qidian.qpic.cn/qdbimg" ], //奇数为需要下载的,偶数为不需要下载的 needLoad:[ //匹配需要下载的 [ "/*.js", "/*.css", "/*.png" ], //匹配不需要下载的 [ "/a.js" ] ], //修改文件保存的地方,默认按照url来的 saveFiles:[ //防止太深文件夹 ["(//*/*/*/*/*/)**/","$1"], //过滤无效文件夹字符 [/(/w*)?+(w*/)/gi,"$1$2"] ], //代理的端口号 port:100 } function regDir(str){ var reg=str if(typeof reg=="string"){ reg=reg.replace(/[[]\^:.?+]/g,function(m){ return "\"+m; }) reg=reg.replace(/**|*/g,function(m){ if(m=="**"){ return "[\w\W]*"; }else{ return "[^\/]*"; } }) reg=new RegExp(reg,"gi") } return reg } String.prototype.Test=function(regStr){ var reg=regDir(regStr) return reg.test(this) } String.prototype.Replace=function(regStr,fn){ var reg=regDir(regStr) return this.replace(reg,fn); } var fs=require("fs") function mkdir(filepath){ var path=require("path") if(!fs.existsSync(path.dirname(filepath))){ mkdir(path.dirname(filepath)) } if(!fs.existsSync(filepath)){ fs.mkdirSync(filepath) } } function eachHeader (obj, fn) { if (Array.isArray(obj.rawHeaders)) { // ideal scenario... >= node v0.11.x // every even entry is a "key", every odd entry is a "value" var key = null; obj.rawHeaders.forEach(function (v) { if (key === null) { key = v; } else { fn(key, v); key = null; } }); } else { // otherwise we can *only* proxy the header names as lowercase'd var headers = obj.headers; if (!headers) return; Object.keys(headers).forEach(function (key) { var value = headers[key]; if (Array.isArray(value)) { // set-cookie value.forEach(function (val) { fn(key, val); }); } else { fn(key, value); } }); } } var hopByHopHeaders = [ 'Connection', 'Keep-Alive', 'Proxy-Authenticate', 'Proxy-Authorization', 'TE', 'Trailers', 'Transfer-Encoding', 'Upgrade' ]; // create a case-insensitive RegExp to match "hop by hop" headers var isHopByHop = new RegExp('^(' + hopByHopHeaders.join('|') + ')$', 'i'); //伪造http function parse (req, server) { var parsed = require("url").parse(req.url); var socket = req.socket; parsed.uri=parsed.href; parsed.gzip=true; // proxy the request HTTP method parsed.method = req.method; // setup outbound proxy request HTTP headers var headers = {}; var hasXForwardedFor = false; parsed.headers = headers; eachHeader(req, function (key, value) { var keyLower = key.toLowerCase(); if (!hasXForwardedFor && 'x-forwarded-for' === keyLower) { // append to existing "X-Forwarded-For" header // http://en.wikipedia.org/wiki/X-Forwarded-For hasXForwardedFor = true; value += ', ' + socket.remoteAddress; } if (isHopByHop.test(key)) { } else { var v = headers[key]; if (Array.isArray(v)) { v.push(value); } else if (null != v) { headers[key] = [ v, value ]; } else { headers[key] = value; } } }); if (!hasXForwardedFor) { headers['X-Forwarded-For'] = socket.remoteAddress; } if (null == parsed.port) { // default the port number if not specified, for >= node v0.11.6... // https://github.com/joyent/node/issues/6199 parsed.port = 80; } return parsed } function getPath(url){ var filename=url.Replace("(**)?*","$1").Replace("http://(**/*)","$1") var dirname=filename.Replace("(**)/*","$1") mkdir("www/"+dirname) return "www/"+filename } var api={ parse:parse, mkdir:mkdir, getPath:getPath } /************************************/ var http = require('http'); var fs=require("fs") var request = require('request'); var server = http.createServer(); server.listen(config.port||100, function () { var port = server.address().port; console.log('HTTP(s) proxy server listening on port %d', port); }); server.on('request', function (req, res) { var url=req.url var arr404=config["404"] var is404=false arr404.forEach(function(v,k){ if(url.Test(v)){ is404=true } }) if(is404){ res.end() return } var parsed=api.parse(req,this) //是否下载 var isLoaded=false; //是否下载的列表 var regArr=config.needLoad var back=false regArr.forEach(function(v,k){ back=!back v.forEach(function(v2,k2){ if(url.Test(v2)){ isLoaded=back } }) }) //修改保存文件路径 /* * 匹配规则 * 修改后 */ var saveFiles=config.saveFiles // isLoaded=false if(isLoaded){ saveFiles.forEach(function(v,k){ url=url.Replace(v[0],v[1]) }) console.log(url) var path=api.getPath(url) console.log(path) //下载 var reque=request(parsed,function(err,resp,body){ if(err){ return } if(path.Test("/*.css")){ res.writeHead(200,{ "content-type":"text/css" }) } fs.createReadStream(path).pipe(res) }) reque.pipe(fs.createWriteStream(path)) reque.on("error",function(){ console.error(url) }) }else{ //不下载 var reque=request(parsed) reque.pipe(res) reque.on("error",function(){ console.error(url) }) } })