1. var net = require('net');
  2. var local_port = 8893;
  3.  
  4. //在本地创建一个server监听本地local_port端口
  5. net.createServer(function (client)
  6. {
  7.  
  8. //首先监听浏览器的数据发送事件,直到收到的数据包含完整的http请求头
  9. var buffer = new Buffer(0);
  10. client.on('data',function(data)
  11. {
  12. buffer = buffer_add(buffer,data);
  13. if (buffer_find_body(buffer) == -1) return;
  14. var req = parse_request(buffer);
  15. if (req === false) return;
  16. client.removeAllListeners('data');
  17. relay_connection(req);
  18. });
  19.  
  20. //从http请求头部取得请求信息后,继续监听浏览器发送数据,同时连接目标服务器,并把目标服务器的数据传给浏览器
  21. function relay_connection(req)
  22. {
  23. console.log(req.method+' '+req.host+':'+req.port);
  24.  
  25. //如果请求不是CONNECT方法(GET, POST),那么替换掉头部的一些东西
  26. if (req.method != 'CONNECT')
  27. {
  28. //先从buffer中取出头部
  29. var _body_pos = buffer_find_body(buffer);
  30. if (_body_pos < 0) _body_pos = buffer.length;
  31. var header = buffer.slice(0,_body_pos).toString('utf8');
  32. //替换connection头
  33. header = header.replace(/(proxy\-)?connection\:.+\r\n/ig,'')
  34. .replace(/Keep\-Alive\:.+\r\n/i,'')
  35. .replace("\r\n",'\r\nConnection: close\r\n');
  36. //替换网址格式(去掉域名部分)
  37. if (req.httpVersion == '1.1')
  38. {
  39. var url = req.path.replace(/http\:\/\/[^\/]+/,'');
  40. if (url.path != url) header = header.replace(req.path,url);
  41. }
  42. buffer = buffer_add(new Buffer(header,'utf8'),buffer.slice(_body_pos));
  43. }
  44.  
  45. //建立到目标服务器的连接
  46. var server = net.createConnection(req.port,req.host);
  47. //交换服务器与浏览器的数据
  48. client.on("data", function(data){ server.write(data); });
  49. server.on("data", function(data){ client.write(data); });
  50.  
  51. if (req.method == 'CONNECT')
  52. client.write(new Buffer("HTTP/1.1 200 Connection established\r\nConnection: close\r\n\r\n"));
  53. else
  54. server.write(buffer);
  55. }
  56. }).listen(local_port);
  57.  
  58. console.log('Proxy server running at localhost:'+local_port);
  59.  
  60. //处理各种错误
  61. process.on('uncaughtException', function(err)
  62. {
  63. console.log("\nError!!!!");
  64. console.log(err);
  65. });
  66.  
  67. /**
  68. * 从请求头部取得请求详细信息
  69. * 如果是 CONNECT 方法,那么会返回 { method,host,port,httpVersion}
  70. * 如果是 GET/POST 方法,那么返回 { metod,host,port,path,httpVersion}
  71. */
  72. function parse_request(buffer)
  73. {
  74. var s = buffer.toString('utf8');
  75. var method = s.split('\n')[0].match(/^([A-Z]+)\s/)[1];
  76. if (method == 'CONNECT')
  77. {
  78. var arr = s.match(/^([A-Z]+)\s([^\:\s]+)\:(\d+)\sHTTP\/(\d\.\d)/);
  79. if (arr && arr[1] && arr[2] && arr[3] && arr[4])
  80. return { method: arr[1], host:arr[2], port:arr[3],httpVersion:arr[4] };
  81. }
  82. else
  83. {
  84. var arr = s.match(/^([A-Z]+)\s([^\s]+)\sHTTP\/(\d\.\d)/);
  85. if (arr && arr[1] && arr[2] && arr[3])
  86. {
  87. var host = s.match(/Host\:\s+([^\n\s\r]+)/)[1];
  88. if (host)
  89. {
  90. var _p = host.split(':',2);
  91. return { method: arr[1], host:_p[0], port:_p[1]?_p[1]:80, path: arr[2],httpVersion:arr[3] };
  92. }
  93. }
  94. }
  95. return false;
  96. }
  97.  
  98. /**
  99. * 两个buffer对象加起来
  100. */
  101. function buffer_add(buf1,buf2)
  102. {
  103. var re = new Buffer(buf1.length + buf2.length);
  104. buf1.copy(re);
  105. buf2.copy(re,buf1.length);
  106. return re;
  107. }
  108.  
  109. /**
  110. * 从缓存中找到头部结束标记("\r\n\r\n")的位置
  111. */
  112. function buffer_find_body(b)
  113. {
  114. for(var i=0,len=b.length-3;i<len;i++)
  115. {
  116. if (b[i] == 0x0d && b[i+1] == 0x0a && b[i+2] == 0x0d && b[i+3] == 0x0a)
  117. {
  118. return i+4;
  119. }
  120. }
  121. return -1;
  122. }

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

Nodejs实现代理服务器配置的更多相关文章

  1. 企业IT管理员IE11升级指南【14】—— IE11代理服务器配置

    企业IT管理员IE11升级指南 系列: [1]—— Internet Explorer 11增强保护模式 (EPM) 介绍 [2]—— Internet Explorer 11 对Adobe Flas ...

  2. NodeJS反向代理websocket

    如需转载请标明出处:http://blog.csdn.net/itas109QQ技术交流群:129518033 文章目录NodeJS反向代理websocket@[toc]前言代码相关问题:1.http ...

  3. CentOS安装Nginx,并配置nodejs反向代理

    安装介绍 安装位置:/usr/local/nginx nginx安装包下载地址:http://nginx.org/download/nginx-1.7.11.tar.gz 安装依赖软件 安装nginx ...

  4. nodejs反向代理插件anyproxy安装

    目前我使用的是Anyproxy,AnyProxy .这个软件的特点是可以获取到https链接的内容.在2016年年初的时候微信公众号和微信文章开始使用https链接.并且Anyproxy可以通过修改r ...

  5. squid代理服务器配置详解

    root@proxy squid]# cat squid.conf## Recommended minimum configuration:#visible_hostname www.jd.com # ...

  6. [nginx]Windows和Mac下,nginx反向代理服务器配置

    最近做项目,前端需要用到nginx反向代理来转发请求,总结了一下在Windows和Mac上的配置,以备查询. 一.Windows 修改nginx的配置文件,nginx.conf. 1)nginx.co ...

  7. nodejs http代理请求

    一些免费到代理地址 http://www.xicidaili.com/nn https://proxy.l337.tech/txt http://www.66ip.cn/nm.html 以下代码可以测 ...

  8. Squid 反向代理服务器配置

    简介: Squid 反向代理常用于服务器端,客户端访问 Squid 代理服务器的 80 端口,Squid 代理服务器根据配置去请求后端的 web 服务器, 然后将请求到的信息保存在本地并回传给客户端, ...

  9. apache代理服务器配置

    1. 扩展开启,httpd.conf开启一下选项 LoadModule proxy modules/proxy.so LoadModule proxy_connect modules/proxy_co ...

随机推荐

  1. Handlebars 介绍

    最新项目用到了Ember.js前端框架,第一次使用这样的框架,准备国庆节花2天时间,研究一下它的用法. Ember框架的模板引擎用到了handlebars, 先看国外的一篇介绍文章:An Introd ...

  2. 优化函数式编程:向 PHP 移植 Clojure 函数

    许多通用程序设计语言试图兼容大多数编程范式,PHP 就属于其中之一.不论你想要成熟的面向对象的程序设计,还是程序式或函数式编程,PHP 都可以做到.但我们不禁要问,PHP 擅长函数式编程吗?本文系国内 ...

  3. Java 应用发布后,需要关注的7个性能指标

    在某个重大发布之后,都需要记录相应的指标,本文介绍了最重要的几个 Java 性能指标,包括响应时间和平均负载等.为理解应用程序在生产环境中如何运行,就需要遵循一些 Java 性能指标. 在以前,当软件 ...

  4. vs2012+opencv2.4.7 实现单张人脸识别

    参考:http://blog.sina.com.cn/s/blog_593c85f20100ncnj.html OpenCV的库中带有检测正面人脸的 Haar迭代算法Haar Cascade Face ...

  5. Layout Resource官方教程(3)在layout中用include嵌入其它layout

    简介 <include>Includes a layout file into this layout. 类似 #include ,把layout展开在include处 attribute ...

  6. 强制IE浏览器或WebBrowser控件使用指定版本显示网页2

    一.问题的提出 偶然发现,Winform里的WebBrowser和IE实际安装的版本似乎并不同步,很有趣! 下面有张图,里面一个窗口是用IE9打开某网站,另一个窗口是用Winform+WebBrows ...

  7. Android开发UI之布局文件LinearLayout

    LinearLayout-线性布局,该布局中的控件按照水平方向排列或者竖直方向排列. 通过属性android:orientation=""决定的,可选值:vertical和hori ...

  8. Innodb加载数据字典 && flush tables

    测试了两个case,属于之前blog的遗留问题: innodb如何加载数据字典 flush tables都做了什么操作 先来看下innodb加载数据字典: 首次使用:select * from tt; ...

  9. bzoj3626

    百度空间马上要下架的说,赶快把最后一点题解补完,然后搬家这是一道不错的题,首先注意询问是满足区间减法的,我们把他变成前缀和表示设我们询问[1,r]中的点和z的LCA深度和,假设我们确定一个根,不难发现 ...

  10. MVC中的@Html.DisplayFor等方法如何控制日期的显示格式(转)

    http://www.tuicool.com/articles/BNVBR3 在Sql Server2005中,如果将某字段定义成日期 时间 类型DateTime,那么在视图中会默认显示成年月日时分秒 ...