nodejs入门-做一个代理服务器

看到node.js的httpServer和http.request,第一个想法居然是可以用它做一个代理服务器
下面代码,实现了代理的基本功能,通过网络的代理设置将你的浏览器的请求转到这个httpServer上,其接收到浏览器的http请求,转发到目的服务器,再将收到的数据转移到浏览器~~~就一二道贩子。

var _http = require('http'),
    _util = require('util'),
    //记录当前是第几个请求
    number = 0;
 
_http.createServer(function(req, res){
	number++;
	res.number = number;
	var headers = req.headers,
		post = '',
		url = req.url;	//_url.parse(req.url, true)--解析url
	console.log('\n======\n[' + number + ']--http--start--[' + req.method + ']' + url);
	if(req.method == 'POST'){
		//接收post
		req.on('data', function(chunk){
			post += chunk;
		});
		req.on('end', function(){
			post = _querystring.parse(post);
			httpRequest(res, headers, url, post);
		});
	}else{
		httpRequest(res, headers, url);
	}
}).listen(3333);
 
console.log('http server start at parth 3333\n\n\n');
 
/*
 * 发送请求
 */
function httpRequest(mainRes, headers, url, post){
	var host = headers.host;
	host = host.split(':');
	var options = {
		host : host[0],
		port : (host[1] ? host[1] : '80'),
		path : url,
		method : (post ? 'POST' : 'GET'),
		headers : headers
	};
	//去掉gzip
	delete options.headers['accept-encoding'];
	console.log('[' + mainRes.number + ']----start http.request-- options:\n%s\n', _util.inspect(options));
 
	var req_ = _http.request(options, function(res_){
		var status_ = res_.statusCode,
			headers_ = res_.headers,
			data = '';
		console.log('[' + mainRes.number + ']----export http.request-(' + status_ + ')-headers:%s', 
				_util.inspect(headers_));
 
		//写header
		mainRes.writeHead(status_, headers_);
 
		var encoding = 'utf8';
		//根据数据类型确定编码方式
		if(headers_['content-type'] && (headers_['content-type'].indexOf('image') >= 0 
				|| headers_['content-type'].indexOf('application') >= 0 
				|| headers_['content-type'].indexOf('audio') >= 0 
				|| headers_['content-type'].indexOf('video') >= 0)){
			encoding = 'binary';
		}
		res_.setEncoding(encoding);
		//接收数据,转给原请求
		res_.on('data', function(d){
			console.log('data-------' + d.length);
			var b = new Buffer(d, encoding);
			mainRes.write(b, encoding);
		});
		res_.on('end', function(){
			//请求结束
			mainRes.end();
			console.log('[' + mainRes.number + ']--------http.request---end----');
		});
	});
	req_.on('error', function(e){
		console.log([' + mainRes.number + '] + '----ERROR----problem with request: ' + e.message);
	});
	//发送post
	if(post){
		req_.write(_querystring.stringify(post));
	}
	req_.end();
}

当然,这段代码仅仅是学习目的的,并没有什么实际意义,https、gzip的问题都没解决,如果网站是gbk的,拿它访问也会乱码
如果要拿它FQ,需要部署两个类似的服务,比如墙外A墙内B,将浏览器代理到B,由B将host隐藏起来,再转到A,A将隐藏的目的host恢复过来,再去访问最终的目的网站

用上面的目的试了试非死不可,不稳定,时不时的会出错~~等完善的再分享给大家

posted on 2013-11-19 16:13  刀锋诚心  阅读(896)  评论(0编辑  收藏  举报