1.fix record issue with https 2.rewrite rule scheme

This commit is contained in:
加里
2014-09-01 16:38:43 +08:00
parent 0f4c1ac017
commit 48fb1cbe40
20 changed files with 633 additions and 373 deletions

12
rule_sample/README.md Normal file
View File

@@ -0,0 +1,12 @@
## rule files sample
* **rule__blank.js**, blank rule file with some comments. You may read this before writing your own rule file.
* **rule_adjust_response_time.js**, delay all the response for 1500ms
* **rule_allow_CORS.js**, add CORS headers to allow cross-domain ajax request
* **rule_intercept_some_https_requests.js**, intercept https requests toward github.com
* **rule_remove_cache_header.js**, remove all cache-related headers from server
* **rule_replace_request_option.js**, replace request parameters before sending to the server
* **rule_replace_response_data.js**, modify response data
* **rule_replace_response_status_code.js**, replace server's status code
* **rule_use_local_data.js**, map some requests to local file

View File

@@ -0,0 +1,66 @@
module.exports = {
/*
thess functions are required
you may leave their bodies blank if necessary
*/
//whether to intercept this request by local logic
//if the return value is true, anyproxy will call dealLocalResponse to get response data and will not send request to remote server anymore
shouldUseLocalResponse : function(req){
return false;
},
//response to user via local logic, be called when shouldUseLocalResponse returns true
//callback(statusCode,resHeader,responseData)
//e.g. callback(200,{"content-type":"text/html"},"hello world")
dealLocalResponse : function(req,callback){
//callback(statusCode,resHeader,responseData)
},
//req is user's request sent to the proxy server
// option is how the proxy server will send request to the real server. i.e. require("http").request(option,function(){...})
//you may return a customized option to replace the original option
replaceRequestOption : function(req,option){
var newOption = option;
return newOption;
},
//replace the request protocol when sending to the real server
//protocol : "http" or "https"
replaceRequestProtocol:function(req,protocol){
var newProtocol = protocol;
return newProtocol;
},
//replace the statusCode before it's sent to the user
replaceResponseStatusCode: function(req,res,statusCode){
var newStatusCode = statusCode;
return newStatusCode;
},
//replace the httpHeader before it's sent to the user
//Here header == res.headers
replaceResponseHeader: function(req,res,header){
var newHeader = header;
return newHeader;
},
//replace the response from the server before it's sent to the user
//you may return either a Buffer or a string
//serverResData is a Buffer, you may get its content by calling serverResData.toString()
replaceServerResData: function(req,res,serverResData){
return serverResData;
},
//add a pause before sending response to user
pauseBeforeSendingResponse : function(req,res){
var timeInMS = 1; //delay all requests for 1ms
return timeInMS;
},
//should intercept https request, or it will be forwarded to real server
shouldInterceptHttpsReq :function(req){
return false;
}
};

View File

@@ -0,0 +1,34 @@
//rule scheme :
module.exports = {
shouldUseLocalResponse : function(req){
},
dealLocalResponse : function(req,callback){
},
replaceRequestOption : function(req,option){
},
replaceRequestProtocol:function(req,protocol){
},
replaceResponseStatusCode: function(req,res,statusCode){
},
replaceResponseHeader: function(req,res,header){
},
replaceServerResData: function(req,res,serverResData){
},
pauseBeforeSendingResponse : function(req,res){
//delay all the response for 1500ms
return 1500;
},
shouldInterceptHttpsReq :function(req){
}
};

View File

@@ -0,0 +1,57 @@
//rule scheme :
// Ref: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
module.exports = {
shouldUseLocalResponse : function(req){
//intercept all options request
if(req.method == "OPTIONS"){
return true;
}else{
return false;
}
},
dealLocalResponse : function(req,callback){
if(req.method == "OPTIONS"){
callback(200,mergeCORSHeader(req.headers),"");
}
},
replaceRequestOption : function(req,option){
},
replaceRequestProtocol:function(req,protocol){
},
replaceResponseStatusCode: function(req,res,statusCode){
},
replaceResponseHeader: function(req,res,header){
return mergeCORSHeader(req.headers, header);
},
replaceServerResData: function(req,res,serverResData){
},
pauseBeforeSendingResponse : function(req,res){
},
shouldInterceptHttpsReq :function(req){
}
};
function mergeCORSHeader(reqHeader,originHeader){
var targetObj = originHeader || {};
delete targetObj["Access-Control-Allow-Credentials"];
delete targetObj["Access-Control-Allow-Origin"];
delete targetObj["Access-Control-Allow-Methods"];
delete targetObj["Access-Control-Allow-Headers"];
targetObj["access-control-allow-credentials"] = "true";
targetObj["access-control-allow-origin"] = reqHeader['origin'] || "-___-||";
targetObj["access-control-allow-methods"] = "GET, POST, PUT";
targetObj["access-control-allow-headers"] = reqHeader['access-control-request-headers'] || "-___-||";
return targetObj;
}

View File

@@ -0,0 +1,44 @@
//rule scheme :
module.exports = {
shouldUseLocalResponse : function(req){
},
dealLocalResponse : function(req,callback){
},
replaceRequestOption : function(req,option){
},
replaceRequestProtocol:function(req,protocol){
},
replaceResponseStatusCode: function(req,res,statusCode){
},
replaceResponseHeader: function(req,res,header){
},
replaceServerResData: function(req,res,serverResData){
//add "hello github" to all github pages
if(req.headers.host == "github.com"){
serverResData += "hello github";
}
return serverResData;
},
pauseBeforeSendingResponse : function(req,res){
},
shouldInterceptHttpsReq :function(req){
//intercept https://github.com/
//otherwise, all the https traffic will not go through this proxy
if(req.headers.host == "github.com"){
return true;
}else{
return false;
}
}
};

View File

@@ -0,0 +1,41 @@
//rule scheme :
module.exports = {
shouldUseLocalResponse : function(req){
},
dealLocalResponse : function(req,callback){
},
replaceRequestOption : function(req,option){
},
replaceRequestProtocol:function(req,protocol){
},
replaceResponseStatusCode: function(req,res,statusCode){
},
replaceResponseHeader: function(req,res,header){
header = header || {};
header["Cache-Control"] = "no-cache, no-store, must-revalidate";
header["Pragma"] = "no-cache";
header["Expires"] = 0;
return header;
},
replaceServerResData: function(req,res,serverResData){
},
pauseBeforeSendingResponse : function(req,res){
},
shouldInterceptHttpsReq :function(req){
}
};
function disableCacheHeader(header){
}

View File

@@ -0,0 +1,48 @@
//rule scheme :
module.exports = {
shouldUseLocalResponse : function(req){
},
dealLocalResponse : function(req,callback){
},
replaceRequestOption : function(req,option){
//replace request towards http://www.taobao.com
// to http://www.taobao.com/about/
/*
option scheme:
{
hostname : "www.taobao.com"
port : 80
path : "/"
method : "GET"
headers : {cookie:""}
}
*/
if(option.hostname == "www.taobao.com" && option.path == "/"){
option.path = "/about/";
}
console.log(option);
},
replaceRequestProtocol:function(req,protocol){
},
replaceResponseStatusCode: function(req,res,statusCode){
},
replaceResponseHeader: function(req,res,header){
},
replaceServerResData: function(req,res,serverResData){
},
pauseBeforeSendingResponse : function(req,res){
},
shouldInterceptHttpsReq :function(req){
}
};

View File

@@ -0,0 +1,41 @@
//rule scheme :
module.exports = {
shouldUseLocalResponse : function(req){
},
dealLocalResponse : function(req,callback){
},
replaceRequestOption : function(req,option){
},
replaceRequestProtocol:function(req,protocol){
},
replaceResponseStatusCode: function(req,res,statusCode){
},
replaceResponseHeader: function(req,res,header){
},
replaceServerResData: function(req,res,serverResData){
//append "hello world" to all web pages
if(/html/i.test(res.headers['content-type'])){
var newDataStr = serverResData.toString();
newDataStr += "hello world!";
return newDataStr;
}else{
return serverResData;
}
},
pauseBeforeSendingResponse : function(req,res){
},
shouldInterceptHttpsReq :function(req){
}
};

View File

@@ -0,0 +1,45 @@
//rule scheme :
module.exports = {
shouldUseLocalResponse : function(req){
},
dealLocalResponse : function(req,callback){
},
replaceRequestOption : function(req,option){
},
replaceRequestProtocol:function(req,protocol){
},
replaceResponseStatusCode: function(req,res,statusCode){
//redirect requests toward http://www.taobao.com/*
// to http://www.etao.com
//using 302
if(req.headers.host == "www.taobao.com"){
statusCode = 302;
}
return statusCode;
},
replaceResponseHeader: function(req,res,header){
if(req.headers.host == "www.taobao.com"){
header.location = "http://www.etao.com";
}
return header;
},
replaceServerResData: function(req,res,serverResData){
},
pauseBeforeSendingResponse : function(req,res){
},
shouldInterceptHttpsReq :function(req){
}
};

View File

@@ -0,0 +1,75 @@
//replace all the images with local one
var url = require("url"),
path = require("path"),
fs = require("fs"),
buffer = require("buffer");
var map = [
{
"host" :/./,
"path" :/\.(png|gif|jpg|jpeg)/,
"localFile" :"/Users/Stella/tmp/test.png",
"localDir" :"~/"
}
];
module.exports = {
shouldUseLocalResponse : function(req){
var host = req.headers.host,
urlPattern = url.parse(req.url),
path = urlPattern.path;
for(var index in map){
var rule = map[index];
var hostTest = new RegExp(rule.host).test(host),
pathTest = new RegExp(rule.path).test(path);
if(hostTest && pathTest && (rule.localFile || rule.localDir) ){
var targetLocalfile = rule.localFile;
//localfile not set, map to dir
if(!targetLocalfile){ //find file in dir, /a/b/file.html -> dir + b/file.html
var remotePathWithoutPrefix = path.replace(new RegExp(rule.path),""); //remove prefix
targetLocalfile = pathUtil.join(rule.localDir,remotePathWithoutPrefix);
}
if(fs.existsSync(targetLocalfile)){
console.log("==>local file: " + targetLocalfile);
req.replaceLocalFile = targetLocalfile; //add a flag to req object
return true;
}
}
}
return false;
},
dealLocalResponse : function(req,callback){
if(req.replaceLocalFile){
callback(200, {"content-type":"image/png"}, fs.readFileSync(req.replaceLocalFile) );
}
},
replaceRequestOption : function(req,option){
},
replaceRequestProtocol:function(req,protocol){
},
replaceResponseStatusCode: function(req,res,statusCode){
},
replaceResponseHeader: function(req,res,header){
},
replaceServerResData: function(req,res,serverResData){
},
pauseBeforeSendingResponse : function(req,res){
},
shouldInterceptHttpsReq :function(req){
}
};