日期:2014-05-16 浏览次数:20426 次
function toBase64(str){ return new Buffer(str).toString('base64'); } function httpRequest(host, port){ var opts = { host: 'your-proxy.your-subdomain.jit.su', port: 80, agent: false, // 这里需要转义以避开gfw的url检测. path: '/' + querystring.escape(toBase64(JSON.stringify({ host: host, port: port }))), method: 'POST' }; return http.request(opts); } /** * 建立代理连接. * @param socket socks5端口连接到的socket * @param chunk socks5代理请求的包, 用于socks5协议响应. * @param host 请求连接的host * @param port 请求连接的port */ function proxy(socket, chunk, host, port){ var httpReq = httpRequest(host, port); // 维持长连接. httpReq.setSocketKeepAlive(1024); // 发一个无用的字符使request发出第一个数据包, 以便服务器接受并建立连接. httpReq.write('\n'); httpReq.on('response', function (httpRes){ // socks5协议部分, var resp = new Buffer(chunk.length); chunk.copy(resp); // rewrite response header resp[0] = SOCKS_VERSION; resp[1] = 0x00; resp[2] = 0x00; // 告诉socks5客户端连接建议完毕. socket.write(resp); // 忽略那个无用的"\n". httpRes.once('data', function (chunk){ if (chunk.toString() === '\n') { httpRes.pipe(socket); console.log('TUNNEL SUCCESS'); } else { console.log('TUNNEL FAIL'); } }); httpRes.on('close', function (){ socket.end(); }); }); socket.setKeepAlive(1024); socket.pipe(httpReq); socket.on('close', function (){ httpReq.abort(); }); }
var http = require('http'); var net = require('net'); var querystring = require('querystring'); function fromBase64(str){ return new Buffer(str, 'base64').toString(); } http.createServer(function (req, res){ var url = req.url; // 这里解码path为host和port var params = JSON.parse(fromBase64(querystring.unescape(url.slice(1)))); var host = params.host; var port = params.port; console.log('CONNECT: ' + host + ':' + port); var buff = []; function addChunk(chunk){ buff.push(chunk); } // 忽略第一个用来强制http发包的'\n' req.once('data', function (chunk){ if (chunk.toString() === '\n') { req.on('data', addChunk); } }); var socket = net.connect(port, host, function (){ req.removeListener('data', addChunk); res.writeHead(200); // 貌似nodejs为了优化, writeHead并不会立即响应给客户端. // 所以这里需要额外发一个没用的字符. res.write('\n'); for (var i=0; i<buff.length; i++) { socket.write(buff[i]); } req.pipe(socket); socket.pipe(res); console.log('CONNECTED: ' + host + ':' + port); }); }).listen(80);