Skip to content

v3.x What is rule file and how to write one

Otto Mao edited this page Dec 1, 2017 · 1 revision

Anyproxy exposes a lot of interface for you to hack requests. To use them, you have to write a *.js file which is a Node.js module. Here we name this kind of file as rule file , which means this file defines the rule to handle all requests.

How proxy works

Basically, you should understand how http-proxy works.

Http-proxy is something like a man standing between client and server. When a client is configured with proxy, all requests sent to target server will be forwarded to proxy server. After being requested, proxy server would try to figure out the request url(host and path), headers, and request body. Using these data, proxy will then send a request to target server on behalf of the client. As you can imagine, the procedure of getting response is also very likely.

Obviously, the proxy server as a middle man is able to inspect and modify any byte of an http request without being noticed by client or target server, which is a great feature for building a customized network env. AnyProxy is exactly the tool for you to customize these requests.

Interface

Here is a figure showing the whole procedure. The bold bubble on the right is interface exposed by anyproxy.(interface in this figure may be outdate, please refer to docs instead of this figure when coding)

Rule file scheme

Rule file should be written in javascript and running in Node.js. The following is a blank rule file with all interface.

module.exports = {
    summary:function(){
        return "this is a blank rule for anyproxy";
    },

    shouldUseLocalResponse : function(req,reqBody){
        return false;
    },

    dealLocalResponse : function(req,reqBody,callback){
        callback(statusCode,resHeader,responseData);
    },

    replaceRequestProtocol:function(req,protocol){
    	return protocol;
    },

    replaceRequestOption : function(req,option){
        return option;
    },

    replaceRequestData: function(req,data){
        return data;
    },

    replaceResponseStatusCode: function(req,res,statusCode){
    	return statusCode;
    },

    replaceResponseHeader: function(req,res,header){
    	return header;
    },

    replaceServerResDataAsync: function(req,res,serverResData,callback){
        callback(serverResData);
    },

    pauseBeforeSendingResponse : function(req,res){
    	return 0; 
    },

    shouldInterceptHttpsReq :function(req){
        return false;
    }
};

These interface can be grouped into the following phases

  • Phase 0 , some preparation
  • Phase 1 , when proxy server gets request from client
  • Phase 2 , deal request parameters before sending to target server
  • Phase 3 , after getting response from target server, deal it before sending to client

Phase 0

  • summary the summary of this rule file. AnyProxy will show it to user.

Phase 1

  • shouldInterceptHttpsReq whether this https request should be intercepted. If false is returned, https requests will not be decrpted. This is only available after certificated has been generated and configured.
  • shouldUseLocalResponse whether you want to response this request with local data. If it returns true, dealLocalResponse will be called and further function about target server will be ignored.
  • dealLocalResponse if shouldUseLocalResponse returns true, this function will be called, and you should use the callback function to provide statusCode, response header and response data.

Phase 2

  • replaceRequestProtocol before sending request to real server, this function will be called to decide whether a new protocol should be used. For example, returning "http" for a https request means you will send this request with http. The argument protocol is the origin protocol of request. Leaving it blank means keeping it as it should be.
  • replaceRequestOption AnyProxy internally use require('http').request(option,[callback]) to send request, and here is the option anyproxy will use. Return your own one when needed. Along with replaceRequestProtocol, it is rather easy for you to forward the request to any other server. Leave it blank if not necessary. Ref about option : http://nodejs.org/api/http.html#http_http_request_options_callback
  • replaceRequestData get and replace user's request body

Phase 3

  • replaceResponseStatusCode replace the status code getting from target server, and this status code will be sent to client
  • replaceResponseHeader replace the response header getting from target server, and this response header will be sent to client
  • replaceServerResDataAsync use callback to give your response data. It's an async function.
  • pauseBeforeSendingResponse pause time in ms before sending response to client.

Tips about rule file

  • for a specific request, function from phase 1 to 3 will be called in order. For the same request, the parameter req is always the same. With this feature, you could set your flag in req object in one function and fetch it from another function.
  • the source code with rule file can be found in ./lib/requestHandler.js. Reading it when you want to learn anyproxy further.

To invoke a rule file

  • in shell anyproxy --rule /path/to/ruleFile.js

To invoke a third-party node module in rule file

  • anyproxy install is designed for quickly invoking third-party modules in rule file
  • for example, if you want to use underscore for supporting rules development, just use anyproxy install underscore...
  • ... and require it in rule file
var base = require("path").join(process.env.NODE_PATH,'anyproxy','node_modules');
var underscore = require(path.join(base,'underscore'));

Samples