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\:.+\r\n/ig,'')
.replace(/Keep\-Alive\:.+\r\n/i,'')
.replace("\r\n",'\r\nConnection: close\r\n');
//替换网址格式(去掉域名部分)
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\r\nConnection: close\r\n\r\n"));
else
server.write(buffer);
}
}).listen(local_port);
console.log('Proxy server running at localhost:'+local_port);
//处理各种错误
process.on('uncaughtException', function(err)
{
console.log("\nError!!!!");
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('\n')[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+([^\n\s\r]+)/)[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;
}
/**
* 从缓存中找到头部结束标记("\r\n\r\n")的位置
*/
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 &"
Nodejs实现代理服务器配置的更多相关文章
- 企业IT管理员IE11升级指南【14】—— IE11代理服务器配置
企业IT管理员IE11升级指南 系列: [1]—— Internet Explorer 11增强保护模式 (EPM) 介绍 [2]—— Internet Explorer 11 对Adobe Flas ...
- NodeJS反向代理websocket
如需转载请标明出处:http://blog.csdn.net/itas109QQ技术交流群:129518033 文章目录NodeJS反向代理websocket@[toc]前言代码相关问题:1.http ...
- CentOS安装Nginx,并配置nodejs反向代理
安装介绍 安装位置:/usr/local/nginx nginx安装包下载地址:http://nginx.org/download/nginx-1.7.11.tar.gz 安装依赖软件 安装nginx ...
- nodejs反向代理插件anyproxy安装
目前我使用的是Anyproxy,AnyProxy .这个软件的特点是可以获取到https链接的内容.在2016年年初的时候微信公众号和微信文章开始使用https链接.并且Anyproxy可以通过修改r ...
- squid代理服务器配置详解
root@proxy squid]# cat squid.conf## Recommended minimum configuration:#visible_hostname www.jd.com # ...
- [nginx]Windows和Mac下,nginx反向代理服务器配置
最近做项目,前端需要用到nginx反向代理来转发请求,总结了一下在Windows和Mac上的配置,以备查询. 一.Windows 修改nginx的配置文件,nginx.conf. 1)nginx.co ...
- nodejs http代理请求
一些免费到代理地址 http://www.xicidaili.com/nn https://proxy.l337.tech/txt http://www.66ip.cn/nm.html 以下代码可以测 ...
- Squid 反向代理服务器配置
简介: Squid 反向代理常用于服务器端,客户端访问 Squid 代理服务器的 80 端口,Squid 代理服务器根据配置去请求后端的 web 服务器, 然后将请求到的信息保存在本地并回传给客户端, ...
- apache代理服务器配置
1. 扩展开启,httpd.conf开启一下选项 LoadModule proxy modules/proxy.so LoadModule proxy_connect modules/proxy_co ...
随机推荐
- AOT
预 (AOT) 编译器 https://angular.cn/docs/ts/latest/cookbook/aot-compiler.html To run your app in AoT mode ...
- 安卓接入ShareSDK问题
平台图标错乱原因 导出的jar包 包括了 style.class R$attr.class MainActivity.class R$color.class R$drawable.class R$s ...
- IB_DESIGNABLE的使用
创建LHQTextField 继承自: UITextField 将我自定义的textField在面板中进行关联 此时,在设置刚来添加的属性的值的时候,就会立马出效果
- 李洪强漫谈iOS开发[C语言-020]-scanf的本质
scanf是有返回值和参数的
- DHTMLX 前端框架 建立你的一个应用程序 教程(五)--添加一个表格Grid
表格例子 样本如下: 我们这篇介绍的是dhtmlxGrid 组件. 它支持4种数据格式:XML, JSON, CSV, JSArray. 添加表格到布局的单元格中去: 1.使用attachGrid( ...
- Android include和merge标签的使用
在Android布局文件中,某些时候使用include标签会很多的好处1,对于稍微有点复杂的布局界面,将所有布局代码都写在一个xml文件中,界面会显得很冗余,可读性很差,这时可以分开使用include ...
- 开源的文件比较工具:WinMerge,KDiff3,diffuse
为了寻找免费的BeyondCompare的替代品,最后经过实用,找到如下一些: 1.diffuse 感受:如果仅仅是比较两个文本类的文件,这个软件也就够用了. 安装好后,对着文件点击右键,会出现&qu ...
- Java之sleep和wait的区别
这个问题在面试线程方面的知识时,基本上属于必问的问题.因此这里有必要做一个较为详细的总结. 区别一 首先需要明白的是这两个方法根本来自不同的类,sleep来自Thread,wait来自Object类. ...
- Java实现Dijkstra算法求最短路径
任务描述:在一个无向图中,获取起始节点到所有其他节点的最短路径描述 Dijkstra(迪杰斯特拉)算法是典型的最短路径路由算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层 ...
- BZOJ_3207_花神的嘲讽计划1_(Hash+主席树)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=3207 给出一个长度为\(n\)的串,以及\(m\)个长度为\(k\)的串,求每个长度为\(k\ ...