• nodejs下载器,通过chrome代理下载http资源


    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)
            })
    
        }
    
    
    })
    

      

  • 相关阅读:
    slot的使用实例
    vue slot插槽的使用方法
    ES6必知必会 (九)—— Module
    MVC3 项目总结
    项目总结,
    oa项目总结
    项目总结。。。
    Delphi 项目总结
    Ubuntu常用命令大全
    linux系统文件目录解析
  • 原文地址:https://www.cnblogs.com/caoke/p/6047614.html
Copyright © 2020-2023  润新知