zoukankan      html  css  js  c++  java
  • Nodejs实现代理服务器配置

    var net = require('net');
    var local_port = 8893;
    
    //在本地创建一个server监听本地local_port端口
    net.createServer(function (client)
    {
        
        //首先监听浏览器的数据发送事件,直到收到的数据包含完整的http请求头
        var buffer = new Buffer(0);
        client.on('data',function(data)
        {
            buffer = buffer_add(buffer,data);
            if (buffer_find_body(buffer) == -1) return;
            var req = parse_request(buffer);
            if (req === false) return;
            client.removeAllListeners('data');
            relay_connection(req);
        });
    
        //从http请求头部取得请求信息后,继续监听浏览器发送数据,同时连接目标服务器,并把目标服务器的数据传给浏览器
        function relay_connection(req)
        {
            console.log(req.method+' '+req.host+':'+req.port);
            
            //如果请求不是CONNECT方法(GET, POST),那么替换掉头部的一些东西
            if (req.method != 'CONNECT')
            {
                //先从buffer中取出头部
                var _body_pos = buffer_find_body(buffer);
                if (_body_pos < 0) _body_pos = buffer.length;
                var header = buffer.slice(0,_body_pos).toString('utf8');
                //替换connection头
                header = header.replace(/(proxy-)?connection:.+
    /ig,'')
                        .replace(/Keep-Alive:.+
    /i,'')
                        .replace("
    ",'
    Connection: close
    ');
                //替换网址格式(去掉域名部分)
                if (req.httpVersion == '1.1')
                {
                    var url = req.path.replace(/http://[^/]+/,'');
                    if (url.path != url) header = header.replace(req.path,url);
                }
                buffer = buffer_add(new Buffer(header,'utf8'),buffer.slice(_body_pos));
            }
            
            //建立到目标服务器的连接
            var server = net.createConnection(req.port,req.host);
            //交换服务器与浏览器的数据
            client.on("data", function(data){ server.write(data); });
            server.on("data", function(data){ client.write(data); });
    
            if (req.method == 'CONNECT')
                client.write(new Buffer("HTTP/1.1 200 Connection established
    Connection: close
    
    "));
            else
                server.write(buffer);
        }
    }).listen(local_port);
    
    console.log('Proxy server running at localhost:'+local_port);
    
    
    //处理各种错误
    process.on('uncaughtException', function(err)
    {
        console.log("
    Error!!!!");
        console.log(err);
    });
    
    
    
    /**
    * 从请求头部取得请求详细信息
    * 如果是 CONNECT 方法,那么会返回 { method,host,port,httpVersion}
    * 如果是 GET/POST 方法,那么返回 { metod,host,port,path,httpVersion}
    */
    function parse_request(buffer)
    {
        var s = buffer.toString('utf8');
        var method = s.split('
    ')[0].match(/^([A-Z]+)s/)[1];
        if (method == 'CONNECT')
        {
            var arr = s.match(/^([A-Z]+)s([^:s]+):(d+)sHTTP/(d.d)/);
            if (arr && arr[1] && arr[2] && arr[3] && arr[4])
                return { method: arr[1], host:arr[2], port:arr[3],httpVersion:arr[4] };
        }
        else
        {
            var arr = s.match(/^([A-Z]+)s([^s]+)sHTTP/(d.d)/);
            if (arr && arr[1] && arr[2] && arr[3])
            {
                var host = s.match(/Host:s+([^
    s
    ]+)/)[1];
                if (host)
                {
                    var _p = host.split(':',2);
                    return { method: arr[1], host:_p[0], port:_p[1]?_p[1]:80, path: arr[2],httpVersion:arr[3] };
                }
            }
        }
        return false;
    }
    
    
    
    
    /**
    * 两个buffer对象加起来
    */
    function buffer_add(buf1,buf2)
    {
        var re = new Buffer(buf1.length + buf2.length);
        buf1.copy(re);
        buf2.copy(re,buf1.length);
        return re;
    }
    
    /**
    * 从缓存中找到头部结束标记("
    
    ")的位置
    */
    function buffer_find_body(b)
    {
        for(var i=0,len=b.length-3;i<len;i++)
        {
            if (b[i] == 0x0d && b[i+1] == 0x0a && b[i+2] == 0x0d && b[i+3] == 0x0a)
            {
                return i+4;
            }
        }
        return -1;
    }
    

      使用 nohup 让nodejs进程在后台运行。 比如运行"nohup node yourjsfile.js > /dev/null &"

  • 相关阅读:
    Android Studio打开非本机项目比较慢的问题。
    Servlet实现重定向的两种方式
    Servlet实现定时刷新到另外一个页面response.setHeader("refresh", "3;url=/...")
    Servlet实现自动刷新功能
    自己实现一个验证码功能
    使用Servlet实现图片下载
    数据库备份的几种方法
    servlet实现的三种方式对比(servlet 和GenericServlet和HttpServlet)
    java中this的用法如:this.name=name
    步骤一:下载jdk并安装和配置java环境变量
  • 原文地址:https://www.cnblogs.com/fangyuan303687320/p/5647781.html
Copyright © 2011-2022 走看看