diff --git a/4.x/cn.html b/4.x/cn.html new file mode 100644 index 0000000..28cea0b --- /dev/null +++ b/4.x/cn.html @@ -0,0 +1,825 @@ + + + + + + + AnyProxy + + + + + + + + + + + + + Fork me on GitHub + + +
+
+ +
+

AnyProxy

+
+

本文档的适用范围是AnyProxy 4.0,此版本当前正在beta中,欢迎提供反馈

+
+

Ref: English Doc

+

AnyProxy是一个开放式的HTTP代理服务器。

+

Github主页:https://github.com/alibaba/anyproxy/tree/4.x

+

主要特性包括:

+ +

相比3.x版本,AnyProxy 4.0的主要变化:

+ +

+

快速上手

+

安装

+
npm install -g anyproxy@beta #本文档对应的AnyProxy为4.0Beta版

启动

+ +
anyproxy
+

其他命令

+ +
anyproxy --port 1080

代理https请求

+ +
+

解析https请求的原理是中间人攻击(man-in-the-middle),用户必须信任AnyProxy生成的CA证书,才能进行后续流程

+
+ +
anyproxy-ca #生成rootCA证书,生成后需要手动信任
+anyproxy --intercept #启动AnyProxy,并解析所有https请求
+

规则模块(Rule)

+

AnyProxy提供了二次开发的能力,你可以用js编写自己的规则模块(rule),来自定义网络请求的处理逻辑。

+
+

注意:引用规则前,请务必确保文件来源可靠,以免发生安全问题

+
+

规则模块的能力范围包括:

+ +

开发示例

+ +

处理流程

+ +

+ +

如何引用

+

如下几种方案都可以用来引用规则模块:

+ +

规则接口文档

+

规则模块应该符合cmd规范,一个典型的规则模块代码结构如下。模块中所有方法都是可选的,只需实现业务感兴趣的部分即可。

+
module.exports = {
+  // 模块介绍
+  summary: 'my customized rule for AnyProxy', 
+  // 发送请求前拦截处理
+  *beforeSendRequest(requestDetail) { /* ... */ }, 
+  // 发送响应前处理
+  *beforeSendResponse(requestDetail, responseDetail) { /* ... */ }, 
+  // 是否处理https请求
+  *beforeDealHttpsRequest(requestDetail) { /* ... */ }, 
+  // 请求出错的事件
+  *onError(requestDetail, error) { /* ... */ }, 
+  // https连接服务器出错
+  *onConnectError(requestDetail, error) { /* ... */ } 
+};
+

规则文件中,除了summary,都是由 co 驱动的,函数需要满足yieldable。可以返回promise或使用generator函数。

+
+

summary

+

summary

+ +

beforeSendRequest

+

beforeSendRequest(requestDetail)

+ +

beforeSendResponse

+

beforeSendResponse(requestDetail, responseDetail)

+ +

beforeDealHttpsRequest

+

beforeDealHttpsRequest(requestDetail)

+ +

onError

+

onError(requestDetail, error)

+ +

onConnectError

+

onConnectError(requestDetail, error)

+ +

FAQ

+ +

规则模块样例

+ +

使用本地数据

+ +
anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_use_local_response.js
/* 
+  sample: 
+    intercept all requests toward httpbin.org, use a local response
+  test:
+    curl http://httpbin.org/user-agent --proxy http://127.0.0.1:8001
+*/
+module.exports = {
+  *beforeSendRequest(requestDetail) {
+    const localResponse = {
+      statusCode: 200,
+      header: { 'Content-Type': 'application/json' },
+      body: '{"hello": "this is local response"}'
+    };
+    if (requestDetail.url.indexOf('http://httpbin.org') === 0) {
+      return {
+        response: localResponse
+      };
+    }
+  },
+};

修改请求头

+ +
anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_request_header.js
/* 
+  sample: 
+    modify the user-agent in requests toward httpbin.org
+  test:
+    curl http://httpbin.org/user-agent --proxy http://127.0.0.1:8001
+*/
+module.exports = {
+  *beforeSendRequest(requestDetail) {
+    if (requestDetail.url.indexOf('http://httpbin.org') === 0) {
+      const newRequestOptions = requestDetail.requestOptions;
+      newRequestOptions.headers['User-Agent'] = 'AnyProxy/0.0.0';
+      return {
+        requestOptions: newRequestOptions
+      };
+    }
+  },
+};

修改请求数据

+ +
anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_request_data.js
/* 
+  sample: 
+    modify the post data towards http://httpbin.org/post
+  test:
+    curl -H "Content-Type: text/plain" -X POST -d 'original post data' http://httpbin.org/post --proxy http://127.0.0.1:8001
+  expected response:
+    { "data": "i-am-anyproxy-modified-post-data" }
+*/
+module.exports = {
+  *beforeSendRequest(requestDetail) {
+    if (requestDetail.url.indexOf('http://httpbin.org/post') === 0) {
+      return {
+        requestData: 'i-am-anyproxy-modified-post-data'
+      };
+    }
+  },
+};

修改请求的目标地址

+ +
anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_request_path.js
/* 
+  sample: 
+    redirect all httpbin.org requests to http://httpbin.org/user-agent
+  test:
+    curl http://httpbin.org/any-path --proxy http://127.0.0.1:8001
+  expected response:
+    { "user-agent": "curl/7.43.0" }
+*/
+module.exports = {
+  *beforeSendRequest(requestDetail) {
+    if (requestDetail.url.indexOf('http://httpbin.org') === 0) {
+      const newRequestOptions = requestDetail.requestOptions;
+      newRequestOptions.path = '/user-agent';
+      newRequestOptions.method = 'GET';
+      return {
+        requestOptions: newRequestOptions
+      };
+    }
+  },
+};

修改请求协议

+ +
anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_request_protocol.js
/* 
+  sample: 
+    redirect all http requests of httpbin.org to https
+  test:
+    curl 'http://httpbin.org/get?show_env=1' --proxy http://127.0.0.1:8001
+  expected response:
+    { "X-Forwarded-Protocol": "https" }
+*/
+module.exports = {
+  *beforeSendRequest(requestDetail) {
+    if (requestDetail.url.indexOf('http://httpbin.org') === 0) {
+      const newOption = requestDetail.requestOptions;
+      newOption.port = 443;
+      return {
+        protocol: 'https',
+        requestOptions: newOption
+      };
+    }
+  }
+};

修改返回状态码

+ +
anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_response_statuscode.js
/* 
+  sample: 
+    modify all status code of http://httpbin.org/ to 404
+  test:
+    curl -I 'http://httpbin.org/user-agent' --proxy http://127.0.0.1:8001
+  expected response:
+    HTTP/1.1 404 Not Found
+*/
+module.exports = {
+  *beforeSendResponse(requestDetail, responseDetail) {
+    if (requestDetail.url.indexOf('http://httpbin.org') === 0) {
+      const newResponse = responseDetail.response;
+      newResponse.statusCode = 404;
+      return {
+        response: newResponse
+      };
+    }
+  }
+};

修改返回头

+ +
anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_response_header.js
/* 
+  sample: 
+    modify response header of http://httpbin.org/user-agent
+  test:
+    curl -I 'http://httpbin.org/user-agent' --proxy http://127.0.0.1:8001
+  expected response:
+    X-Proxy-By: AnyProxy
+*/
+module.exports = {
+  *beforeSendResponse(requestDetail, responseDetail) {
+    if (requestDetail.url.indexOf('http://httpbin.org/user-agent') === 0) {
+      const newResponse = responseDetail.response;
+      newResponse.header['X-Proxy-By'] = 'AnyProxy';
+      return {
+        response: newResponse
+      };
+    }
+  }
+};

修改返回内容并延迟

+ +
anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_response_data.js
/* 
+  sample: 
+    modify response data of http://httpbin.org/user-agent
+  test:
+    curl 'http://httpbin.org/user-agent' --proxy http://127.0.0.1:8001
+  expected response:
+    { "user-agent": "curl/7.43.0" } -- AnyProxy Hacked! --
+*/
+
+module.exports = {
+  *beforeSendResponse(requestDetail, responseDetail) {
+    if (requestDetail.url === 'http://httpbin.org/user-agent') {
+      const newResponse = responseDetail.response;
+      newResponse.body += '-- AnyProxy Hacked! --';
+      return new Promise((resolve, reject) => {
+        setTimeout(() => { // delay the response for 5s
+          resolve({ response: newResponse });
+        }, 5000);
+      });
+    }
+  },
+};

作为npm模块使用

+

AnyProxy可以作为一个npm模块使用,整合进其他工具。

+
+

如要启用https解析,请在代理服务器启动前自行调用AnyProxy.utils.certMgr相关方法生成证书,并引导用户信任安装。或引导用户使用anyproxy-ca方法。

+
+ +
npm i anyproxy@beta --save # 4.0版正在beta中
+
const AnyProxy = require('anyproxy');
+const options = {
+  port: 8001,
+  rule: require('myRuleModule'),
+  webInterface: {
+    enable: true,
+    webPort: 8002,
+    wsPort: 8003,
+  },
+  throttle: 10000,
+  forceProxyHttps: false,
+  silent: false
+};
+const proxyServer = new AnyProxy.ProxyServer(options);
+
+proxyServer.on('ready', () => { /* */ });
+proxyServer.on('error', (e) => { /* */ });
+proxyServer.start();
+
+//when finished
+proxyServer.close();
+

关于AnyProxy

+ +

配置帮助

+

OSX系统信任CA证书

+ +

+
+

警告:CA证书和系统安全息息相关,建议亲自生成,并妥善保管

+
+

安装CA:

+ +

+ +

+

Windows系统信任CA证书

+

+

配置OSX系统代理

+ +

+

配置浏览器HTTP代理

+ +

+

配置iOS/Android系统代理

+ +

+ +

+
+
+ + + + + + \ No newline at end of file diff --git a/4.x/en.html b/4.x/en.html new file mode 100644 index 0000000..fee6b10 --- /dev/null +++ b/4.x/en.html @@ -0,0 +1,820 @@ + + + + + + + AnyProxy + + + + + + + + + + + + + Fork me on GitHub + + +
+
+ +
+

AnyProxy

+

AnyProxy is a fully configurable http/https proxy in NodeJS. Version 4.0 is in beta now.

+

Ref: Chinese Doc 中文文档

+

Github:

+ +

Features:

+ +

Change Logs since 3.x:

+ +

+

Quick start

+

install

+
npm install -g anyproxy@beta # 4.x is in beta now

launch

+ +
anyproxy
+

other commands

+ +
anyproxy --port 1080

Proxy https request

+ +
+

Under the hood, AnyProxy decryptes https requests by man-in-the-middle attack. Users have to trust the CA cert in advance. Otherwise, client side will issue errors about unsecure network.

+
+ +
anyproxy-ca #generate root CA. manually trust it after that.
+anyproxy --intercept #launch anyproxy and intercept all https traffic
+

Use rule module

+

AnyProxy provides the ability to load your own rules written in javascript. With rule module, you could customize the logic to handle requests.

+
+

Make sure your rule file is got from a trusted source. Otherwise, you may face some unknown security risk.

+
+

Rule module could do the following stuff:

+ +

sample

+ +

the entire process

+ +

+ +

how to load rule module

+ +

Rule module interface

+

A typical rule module is as follows. All the functions are optional, just write the part you are interested in.

+
module.exports = {
+  // introduction
+  summary: 'my customized rule for AnyProxy', 
+  // intercept before send request to server
+  *beforeSendRequest(requestDetail) { /* ... */ }, 
+  // deal response before send to client 
+  *beforeSendResponse(requestDetail, responseDetail) { /* ... */ }, 
+  // if deal https request
+  *beforeDealHttpsRequest(requestDetail) { /* ... */ }, 
+  // error happened when dealing requests
+  *onError(requestDetail, error) { /* ... */ }, 
+  // error happened when connect to https server
+  *onConnectError(requestDetail, error) { /* ... */ } 
+};
+

All functions in your rule file, except summary, are all driven by co . They should be yieldable, i.e. return a promise or be a generator function.

+
+

summary

+

summary

+ +

beforeSendRequest

+

beforeSendRequest(requestDetail)

+ +

beforeSendResponse

+

beforeSendResponse(requestDetail, responseDetail)

+ +

beforeDealHttpsRequest

+

beforeDealHttpsRequest(requestDetail)

+ +

onError

+

onError(requestDetail, error)

+ +

onConnectError

+

onConnectError(requestDetail, error)

+ +

FAQ

+ +

Rule Samples

+ +

use local response

+ +
anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_use_local_response.js
/* 
+  sample: 
+    intercept all requests toward httpbin.org, use a local response
+  test:
+    curl http://httpbin.org/user-agent --proxy http://127.0.0.1:8001
+*/
+module.exports = {
+  *beforeSendRequest(requestDetail) {
+    const localResponse = {
+      statusCode: 200,
+      header: { 'Content-Type': 'application/json' },
+      body: '{"hello": "this is local response"}'
+    };
+    if (requestDetail.url.indexOf('http://httpbin.org') === 0) {
+      return {
+        response: localResponse
+      };
+    }
+  },
+};

modify request header

+ +
anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_request_header.js
/* 
+  sample: 
+    modify the user-agent in requests toward httpbin.org
+  test:
+    curl http://httpbin.org/user-agent --proxy http://127.0.0.1:8001
+*/
+module.exports = {
+  *beforeSendRequest(requestDetail) {
+    if (requestDetail.url.indexOf('http://httpbin.org') === 0) {
+      const newRequestOptions = requestDetail.requestOptions;
+      newRequestOptions.headers['User-Agent'] = 'AnyProxy/0.0.0';
+      return {
+        requestOptions: newRequestOptions
+      };
+    }
+  },
+};

modify request body

+ +
anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_request_data.js
/* 
+  sample: 
+    modify the post data towards http://httpbin.org/post
+  test:
+    curl -H "Content-Type: text/plain" -X POST -d 'original post data' http://httpbin.org/post --proxy http://127.0.0.1:8001
+  expected response:
+    { "data": "i-am-anyproxy-modified-post-data" }
+*/
+module.exports = {
+  *beforeSendRequest(requestDetail) {
+    if (requestDetail.url.indexOf('http://httpbin.org/post') === 0) {
+      return {
+        requestData: 'i-am-anyproxy-modified-post-data'
+      };
+    }
+  },
+};

modify the request target

+ +
anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_request_path.js
/* 
+  sample: 
+    redirect all httpbin.org requests to http://httpbin.org/user-agent
+  test:
+    curl http://httpbin.org/any-path --proxy http://127.0.0.1:8001
+  expected response:
+    { "user-agent": "curl/7.43.0" }
+*/
+module.exports = {
+  *beforeSendRequest(requestDetail) {
+    if (requestDetail.url.indexOf('http://httpbin.org') === 0) {
+      const newRequestOptions = requestDetail.requestOptions;
+      newRequestOptions.path = '/user-agent';
+      newRequestOptions.method = 'GET';
+      return {
+        requestOptions: newRequestOptions
+      };
+    }
+  },
+};

modify request protocol

+ +
anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_request_protocol.js
/* 
+  sample: 
+    redirect all http requests of httpbin.org to https
+  test:
+    curl 'http://httpbin.org/get?show_env=1' --proxy http://127.0.0.1:8001
+  expected response:
+    { "X-Forwarded-Protocol": "https" }
+*/
+module.exports = {
+  *beforeSendRequest(requestDetail) {
+    if (requestDetail.url.indexOf('http://httpbin.org') === 0) {
+      const newOption = requestDetail.requestOptions;
+      newOption.port = 443;
+      return {
+        protocol: 'https',
+        requestOptions: newOption
+      };
+    }
+  }
+};

modify response status code

+ +
anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_response_statuscode.js
/* 
+  sample: 
+    modify all status code of http://httpbin.org/ to 404
+  test:
+    curl -I 'http://httpbin.org/user-agent' --proxy http://127.0.0.1:8001
+  expected response:
+    HTTP/1.1 404 Not Found
+*/
+module.exports = {
+  *beforeSendResponse(requestDetail, responseDetail) {
+    if (requestDetail.url.indexOf('http://httpbin.org') === 0) {
+      const newResponse = responseDetail.response;
+      newResponse.statusCode = 404;
+      return {
+        response: newResponse
+      };
+    }
+  }
+};

modify the response header

+ +
anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_response_header.js
/* 
+  sample: 
+    modify response header of http://httpbin.org/user-agent
+  test:
+    curl -I 'http://httpbin.org/user-agent' --proxy http://127.0.0.1:8001
+  expected response:
+    X-Proxy-By: AnyProxy
+*/
+module.exports = {
+  *beforeSendResponse(requestDetail, responseDetail) {
+    if (requestDetail.url.indexOf('http://httpbin.org/user-agent') === 0) {
+      const newResponse = responseDetail.response;
+      newResponse.header['X-Proxy-By'] = 'AnyProxy';
+      return {
+        response: newResponse
+      };
+    }
+  }
+};

modify response data and delay

+ +
anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_response_data.js
/* 
+  sample: 
+    modify response data of http://httpbin.org/user-agent
+  test:
+    curl 'http://httpbin.org/user-agent' --proxy http://127.0.0.1:8001
+  expected response:
+    { "user-agent": "curl/7.43.0" } -- AnyProxy Hacked! --
+*/
+
+module.exports = {
+  *beforeSendResponse(requestDetail, responseDetail) {
+    if (requestDetail.url === 'http://httpbin.org/user-agent') {
+      const newResponse = responseDetail.response;
+      newResponse.body += '-- AnyProxy Hacked! --';
+      return new Promise((resolve, reject) => {
+        setTimeout(() => { // delay the response for 5s
+          resolve({ response: newResponse });
+        }, 5000);
+      });
+    }
+  },
+};

Use AnyProxy as an npm module

+

AnyProxy can be used as an npm module

+
+

To enable https feature, please guide users to use anyproxy-ca in cli. Or use methods under AnyProxy.utils.certMgr to generate certificates.

+
+ +
npm i anyproxy@beta --save # 4.0 is in beta now
+
const AnyProxy = require('anyproxy');
+const options = {
+  port: 8001,
+  rule: require('myRuleModule'),
+  webInterface: {
+    enable: true,
+    webPort: 8002,
+    wsPort: 8003,
+  },
+  throttle: 10000,
+  forceProxyHttps: false,
+  silent: false
+};
+const proxyServer = new AnyProxy.ProxyServer(options);
+
+proxyServer.on('ready', () => { /* */ });
+proxyServer.on('error', (e) => { /* */ });
+proxyServer.start();
+
+//when finished
+proxyServer.close();
+

About AnyProxy

+ +

Appendix

+

Config root CA in OSX

+ +

+
+

Warning: please keep your root CA safe since it may influence your system security.

+
+

install :

+ +

+ +

+

trust root CA in windows

+

+

config OSX system proxy

+ +

+

config http proxy server

+ +

+

config iOS/Android proxy server

+ +

+ +

+
+
+ + + + + + \ No newline at end of file