Skip to content

Commit

Permalink
Merge branch 'master' of github.com:hellolwq/nproxy
Browse files Browse the repository at this point in the history
  • Loading branch information
Áθç committed May 30, 2012
2 parents 6087518 + 48728bf commit e796a6d
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 37 deletions.
12 changes: 11 additions & 1 deletion README
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
nproxy基于node.js开发,用于实现http协议级别的Web代理。
目前支持简单的的HTML代理,完整的HTML、JS等重写正在完成中,问题会比较多,如果有发现,请反馈到hellolwq@gmail.com

一、安装步骤
一、特性
1、支持HTML重写,可重写静态URL链接。
2、...

二、待支持特性
1、支持服务端javascript重写。
2、支持客户端javascript、html等脚本重写。
3、支持css脚本重写。
4、支持cookie保存。

三、安装步骤
1、安装node.js环境 http://nodejs.org/#download
2、下载nproxy文件 https://github.com/hellolwq/nproxy/downloads
3、修改nproxy.js配置监听端口。(之后会统一放到配置文件)
Expand Down
108 changes: 77 additions & 31 deletions lib/htmlparser.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,64 @@
* });
*
* // or to get an XML string:
* HTMLtoXML(htmlString);
* RewriteHtml(htmlString);
*
*/
exports.parseHTML = HTMLtoXML
exports.RewriteHtml = function( html ,request,tran_url_fun) {
//RewriteHtml = function( html ,request,tran_url_fun) {
var results = "";

HTMLParser(html, {
start: function( tag, attrs, unary ) {
results += "<" + tag;

for ( var i = 0; i < attrs.length; i++ )
{
if(g_html_rules[tag] && g_html_rules[tag][attrs[i].name])
{
if(tag.toLowerCase() == "meta" && attrs[i].name.toLowerCase() == 'content')
{
var isRefresh = false;
for(var j=0;j<attrs.length;j++)
{
if(attrs[j].name.toLowerCase() == 'http-equiv' && attrs[j].escaped.toLowerCase() == 'refresh')
{
isRefresh = true;
break;
}

}

if(isRefresh)
{
attrs[i].escaped = attrs[i].escaped.replace(/(url=)(.+)$/i, function($0,$1,$2){return ($1+tran_url_fun($2,request));});
results += " " + attrs[i].name + '="' + attrs[i].escaped + '"';
continue;
}
}
attrs[i].escaped = tran_url_fun(attrs[i].escaped,request);
}

results += " " + attrs[i].name + '="' + attrs[i].escaped + '"';
}

results += (unary ? "/" : "") + ">";
},
end: function( tag ) {
results += "</" + tag + ">";
},
chars: function( text ) {
results += text;
},
comment: function( text ) {
results += "<!--" + text + "-->";
}
});

return results;
};
// Regular Expressions for parsing tags and attributes
var startTag = /^<([-A-Za-z0-9_]+)((?:\s+\w+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/,
var startTag = /^<([-A-Za-z0-9_]+)((?:\s+[-\w]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/,
endTag = /^<\/([-A-Za-z0-9_]+)[^>]*>/,
attr = /([-A-Za-z0-9_]+)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g;

Expand All @@ -40,6 +92,12 @@ var fillAttrs = makeMap("checked,compact,declare,defer,disabled,ismap,multiple,n
// Special Elements (can contain anything)
var special = makeMap("script,style");

var g_html_rules = {
img:{src:1},
href:{href:1},
meta:{content:1}
}

var HTMLParser = this.HTMLParser = function( html, handler ) {
var index, chars, match, stack = [], last = html;
stack.last = function(){
Expand Down Expand Up @@ -75,9 +133,22 @@ var HTMLParser = this.HTMLParser = function( html, handler ) {

// start tag
} else if ( html.indexOf("<") == 0 ) {
match = html.match( startTag );

if ( match ) {
var docTypeTag = "<!DOCTYPE "
if(html.substr(0,docTypeTag.length).toLowerCase() == docTypeTag.toLowerCase()){
index = html.indexOf('>')
if(index < 0)
throw "Parse Error:doctype invalid!";

++index;
var text = html.substring( 0, index );

if ( handler.chars )
handler.chars( text );

html = html.substr( index );
chars = false;
}
else if ( match = html.match( startTag )) {
html = html.substring( match[0].length );
match[0].replace( startTag, parseStartTag );
chars = false;
Expand Down Expand Up @@ -178,31 +249,6 @@ var HTMLParser = this.HTMLParser = function( html, handler ) {
}
};

this.HTMLtoXML = function( html ) {
var results = "";

HTMLParser(html, {
start: function( tag, attrs, unary ) {
results += "<" + tag;

for ( var i = 0; i < attrs.length; i++ )
results += " " + attrs[i].name + '="' + attrs[i].escaped + '"';

results += (unary ? "/" : "") + ">";
},
end: function( tag ) {
results += "</" + tag + ">";
},
chars: function( text ) {
results += text;
},
comment: function( text ) {
results += "<!--" + text + "-->";
}
});

return results;
};

function makeMap(str){
var obj = {}, items = str.split(",");
Expand Down
17 changes: 12 additions & 5 deletions nproxy.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
var HTTP = require('http');
var FS = require('fs');
var URL = require('url');
var HtmlParser = require('./lib/htmlparser.js');

var SVR_PORT = 8080;
var LOG_DIR = "./logs/";
Expand Down Expand Up @@ -155,12 +156,18 @@ function proxy_request(urlObj,callback)
function proxy_rewrite(data,request)
{
//log(LOG_DBG,"typeof(data):",typeof(data));
//print_r(data);
//log(LOG_DBG,"proxy_rewrite:" + data);
//log(LOG_DBG,"proxy_rewrite request.orig_url" + request.orig_url);
return data.replace(/(\s(src|href)=['"])([^'"]*)(['"])/g, function() {
log(LOG_DBG,"proxy_rewrite before:" + data);
var ret = data;
// try{
ret = HtmlParser.RewriteHtml(data,request,helper_trans_url);
//}catch(e){
// ret = data;
//}
log(LOG_DBG,"proxy_rewrite after:" + ret);
return ret;
/*return data.replace(/(\s(src|href)=['"])([^'"]*)(['"])/g, function() {
return (arguments[1]+helper_trans_url(arguments[3],request)+arguments[4]);
});
});*/
}

function helper_trans_url(url,request)
Expand Down
25 changes: 25 additions & 0 deletions tset.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<html>
<head>
<script src="lib/htmlparser.js"> </script>
</head>
<body>
<textarea id="input" rows="20" style="width:100%">
</textarea>
<button onClick="onRewrite()" style="width:200px;">ok</button>
<textarea id="output" rows="20" style="width:100%">
</textarea>
<script>
function onRewrite()
{
var input = document.getElementById("input").innerText;
var output = RewriteHtml(input,null,tran_url);
document.getElementById("output").innerText = output;
}

function tran_url(url)
{
return url+"##";
}
</script>
</body>
</html>

0 comments on commit e796a6d

Please sign in to comment.