diff --git a/.gitignore b/.gitignore
index f76f798..1b4f111 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,6 +5,7 @@
 .hg
 .lock-wscript
 .svn
+.vscode
 .wafpickle-*
 CVS
 npm-debug.log
diff --git a/4.x/cn.html b/4.x/cn.html
index 9e14363..5968c39 100644
--- a/4.x/cn.html
+++ b/4.x/cn.html
@@ -15,7 +15,7 @@
   <script>
     //redirect to Chinese version if in China
     if (new Date().getTimezoneOffset() == "-480" && !(/(cn|en)/i.test(location.href))) {
-      location.href = "./cn.html";
+      location.href = "/";
     } else {
       var _hmt = _hmt || []; (function () { var hm = document.createElement("script"); hm.src = "//hm.baidu.com/hm.js?4e51565b7d471fd6623c163a8fd79e07"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })();
     }
@@ -23,815 +23,7 @@
 </head>
 
 <body>
-  <a href="https://github.com/alibaba/anyproxy/tree/4.x" target="_blank">
-    <img style="position: fixed; top: 0; right: 0; border: 0;z-index: 1;" src="https://camo.githubusercontent.com/a6677b08c955af8400f44c6298f40e7d19cc5b2d/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f677261795f3664366436642e706e67"
-      alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_gray_6d6d6d.png">
-  </a>
 
-  <article class="markdown-body">
-    <div class="toc-container" id="j_toc">
-      <div class="toc-content"><ul class="nav nav-list">
-    <li class="sidebar-header-1"><a href="#anyproxy">AnyProxy</a></li>
-    <li class="sidebar-header-2"><a href="#快速上手">快速上手</a></li>
-    <li class="sidebar-header-3"><a href="#安装">安装</a></li>
-    <li class="sidebar-header-3"><a href="#启动">启动</a></li>
-    <li class="sidebar-header-3"><a href="#其他命令">其他命令</a></li>
-    <li class="sidebar-header-2"><a href="#代理https请求">代理https请求</a></li>
-    <li class="sidebar-header-2"><a href="#规则模块(rule)">规则模块(Rule)</a></li>
-    <li class="sidebar-header-3"><a href="#开发示例">开发示例</a></li>
-    <li class="sidebar-header-3"><a href="#处理流程">处理流程</a></li>
-    <li class="sidebar-header-3"><a href="#如何引用">如何引用</a></li>
-    <li class="sidebar-header-2"><a href="#规则接口文档">规则接口文档</a></li>
-    <li class="sidebar-header-3"><a href="#summary">summary</a></li>
-    <li class="sidebar-header-4"><a href="#summary-1">summary</a></li>
-    <li class="sidebar-header-3"><a href="#beforesendrequest">beforeSendRequest</a></li>
-    <li class="sidebar-header-4"><a href="#beforesendrequest(requestdetail)">beforeSendRequest(requestDetail)</a></li>
-    <li class="sidebar-header-3"><a href="#beforesendresponse">beforeSendResponse</a></li>
-    <li class="sidebar-header-4"><a href="#beforesendresponse(requestdetail,-responsedetail)">beforeSendResponse(requestDetail, responseDetail)</a></li>
-    <li class="sidebar-header-3"><a href="#beforedealhttpsrequest">beforeDealHttpsRequest</a></li>
-    <li class="sidebar-header-4"><a href="#beforedealhttpsrequest(requestdetail)">beforeDealHttpsRequest(requestDetail)</a></li>
-    <li class="sidebar-header-3"><a href="#onerror">onError</a></li>
-    <li class="sidebar-header-4"><a href="#onerror(requestdetail,-error)">onError(requestDetail, error)</a></li>
-    <li class="sidebar-header-3"><a href="#onconnecterror">onConnectError</a></li>
-    <li class="sidebar-header-4"><a href="#onconnecterror(requestdetail,-error)">onConnectError(requestDetail, error)</a></li>
-    <li class="sidebar-header-3"><a href="#faq">FAQ</a></li>
-    <li class="sidebar-header-2"><a href="#规则模块样例">规则模块样例</a></li>
-    <li class="sidebar-header-3"><a href="#使用本地数据">使用本地数据</a></li>
-    <li class="sidebar-header-3"><a href="#修改请求头">修改请求头</a></li>
-    <li class="sidebar-header-3"><a href="#修改请求数据">修改请求数据</a></li>
-    <li class="sidebar-header-3"><a href="#修改请求的目标地址">修改请求的目标地址</a></li>
-    <li class="sidebar-header-3"><a href="#修改请求协议">修改请求协议</a></li>
-    <li class="sidebar-header-3"><a href="#修改返回状态码">修改返回状态码</a></li>
-    <li class="sidebar-header-3"><a href="#修改返回头">修改返回头</a></li>
-    <li class="sidebar-header-3"><a href="#修改返回内容并延迟">修改返回内容并延迟</a></li>
-    <li class="sidebar-header-2"><a href="#作为npm模块使用">作为npm模块使用</a></li>
-    <li class="sidebar-header-2"><a href="#关于anyproxy">关于AnyProxy</a></li>
-    <li class="sidebar-header-2"><a href="#配置帮助">配置帮助</a></li>
-    <li class="sidebar-header-3"><a href="#osx系统信任ca证书">OSX系统信任CA证书</a></li>
-    <li class="sidebar-header-3"><a href="#windows系统信任ca证书">Windows系统信任CA证书</a></li>
-    <li class="sidebar-header-3"><a href="#配置osx系统代理">配置OSX系统代理</a></li>
-    <li class="sidebar-header-3"><a href="#配置浏览器http代理">配置浏览器HTTP代理</a></li>
-    <li class="sidebar-header-3"><a href="#ios系统信任ca证书">iOS系统信任CA证书</a></li>
-    <li class="sidebar-header-3"><a href="#ios-&gt;&#x3D;-10.3信任ca证书">iOS &gt;&#x3D; 10.3信任CA证书</a></li>
-    <li class="sidebar-header-3"><a href="#配置ios/android系统代理">配置iOS/Android系统代理</a></li>
-</ul>
-      </div>
-    </div>
-    <div class="main-content"><h1 id="anyproxy"><a class="header-link" href="#anyproxy"></a>AnyProxy</h1>
-<blockquote>
-<p>本文档的适用范围是AnyProxy 4.0,此版本当前正在beta中,欢迎提供反馈</p>
-</blockquote>
-<p>Ref: <a href="./en.html">English Doc</a></p>
-<p>AnyProxy是一个开放式的HTTP代理服务器。</p>
-<p>Github主页:<a href="https://github.com/alibaba/anyproxy/tree/4.x">https://github.com/alibaba/anyproxy/tree/4.x</a></p>
-<p>主要特性包括:</p>
-<ul class="list">
-<li>基于Node.js,开放二次开发能力,允许自定义请求处理逻辑</li>
-<li>支持Https的解析</li>
-<li>提供GUI界面,用以观察请求</li>
-</ul>
-<p>相比3.x版本,AnyProxy 4.0的主要变化:</p>
-<ul class="list">
-<li>规则文件(Rule)全面支持Promise和Generator</li>
-<li>简化了规则文件内的接口</li>
-<li>Web版界面重构</li>
-</ul>
-<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/SqVntpzmscXPbSzfcGcr.png" width="500" /></p>
-<h2 id="快速上手"><a class="header-link" href="#快速上手"></a>快速上手</h2>
-<h3 id="安装"><a class="header-link" href="#安装"></a>安装</h3>
-<pre class="hljs"><code>npm install -g anyproxy@beta <span class="hljs-comment">#本文档对应的AnyProxy为4.0Beta版</span></code></pre><h3 id="启动"><a class="header-link" href="#启动"></a>启动</h3>
-<ul class="list">
-<li>命令行启动AnyProxy,默认端口号8001</li>
-</ul>
-<pre class="hljs"><code>anyproxy</code></pre><ul class="list">
-<li>启动后将终端http代理服务器配置为127.0.0.1:8001即可</li>
-<li>访问<a href="http://127.0.0.1:8002">http://127.0.0.1:8002</a> ,web界面上能看到所有的请求信息</li>
-</ul>
-<h3 id="其他命令"><a class="header-link" href="#其他命令"></a>其他命令</h3>
-<ul class="list">
-<li>配置启动端口,如1080端口启动</li>
-</ul>
-<pre class="hljs"><code>anyproxy --port 1080</code></pre><h2 id="代理https请求"><a class="header-link" href="#代理https请求"></a>代理https请求</h2>
-<ul class="list">
-<li>AnyProxy默认不对https请求做处理,如需看到明文信息,需要配置CA证书</li>
-</ul>
-<blockquote>
-<p>解析https请求的原理是中间人攻击(man-in-the-middle),用户必须信任AnyProxy生成的CA证书,才能进行后续流程</p>
-</blockquote>
-<ul class="list">
-<li>生成证书并解析所有https请求</li>
-</ul>
-<pre class="hljs"><code>anyproxy-ca <span class="hljs-comment">#生成rootCA证书,生成后需要手动信任</span>
-anyproxy --intercept <span class="hljs-comment">#启动AnyProxy,并解析所有https请求</span></code></pre><ul class="list">
-<li><a href="#osx系统信任ca证书">附录:如何信任CA证书</a></li>
-</ul>
-<h2 id="规则模块(rule)"><a class="header-link" href="#规则模块(rule)"></a>规则模块(Rule)</h2>
-<p>AnyProxy提供了二次开发的能力,你可以用js编写自己的规则模块(rule),来自定义网络请求的处理逻辑。</p>
-<blockquote>
-<p>注意:引用规则前,请务必确保文件来源可靠,以免发生安全问题</p>
-</blockquote>
-<p>规则模块的能力范围包括:</p>
-<ul class="list">
-<li>拦截并修改正在发送的请求<ul class="list">
-<li>可修改内容包括请求头(request header),请求体(request body),甚至是请求的目标地址等</li>
-</ul>
-</li>
-<li>拦截并修改服务端响应<ul class="list">
-<li>可修改的内容包括http状态码(status code)、响应头(response header)、响应内容等</li>
-</ul>
-</li>
-<li>拦截https请求,对内容做修改<ul class="list">
-<li>本质是中间人攻击(man-in-the-middle attack),需要客户端提前信任AnyProxy生成的CA</li>
-</ul>
-</li>
-</ul>
-<h3 id="开发示例"><a class="header-link" href="#开发示例"></a>开发示例</h3>
-<ul class="list">
-<li><p>举例</p>
-<ul class="list">
-<li>需要编写一个规则模块,在 GET <a href="http://httpbin.org/user-agent">http://httpbin.org/user-agent</a> 的返回值里加上测试信息,并延迟5秒返回</li>
-</ul>
-</li>
-<li><p>Step 1,编写规则</p>
-<pre class="hljs"><code><span class="hljs-comment">// file: sample.js</span>
-<span class="hljs-built_in">module</span>.exports = {
-  <span class="hljs-attr">summary</span>: <span class="hljs-string">'a rule to modify response'</span>,
-  *beforeSendResponse(requestDetail, responseDetail) {
-    <span class="hljs-keyword">if</span> (requestDetail.url === <span class="hljs-string">'http://httpbin.org/user-agent'</span>) {
-      <span class="hljs-keyword">const</span> newResponse = responseDetail.response;
-      newResponse.body += <span class="hljs-string">'-- AnyProxy Hacked! --'</span>;
-      <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =&gt;</span> {
-        setTimeout(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> { <span class="hljs-comment">// delay</span>
-          resolve({ <span class="hljs-attr">response</span>: newResponse });
-        }, <span class="hljs-number">5000</span>);
-      });
-    }
-  },
-};</code></pre></li>
-<li><p>Step 2, 启动AnyProxy,加载规则</p>
-<ul class="list">
-<li>运行 <code>anyproxy --rule sample.js</code></li>
-</ul>
-</li>
-<li><p>Step 3, 测试规则</p>
-<ul class="list">
-<li><p>用curl测试 </p>
-<pre class="hljs"><code>curl http://httpbin.org/user-agent --proxy http://127.0.0.1:8001</code></pre></li>
-<li><p>用浏览器测试:配置浏览器http代理为 127.0.0.1:8001,访问 <a href="http://httpbin.org/user-agent">http://httpbin.org/user-agent</a> </p>
-</li>
-<li><p>经过代理服务器后,期望的返回如下</p>
-</li>
-</ul>
-<pre class="hljs"><code>{
-  <span class="hljs-string">"user-agent"</span>: <span class="hljs-string">"curl/7.43.0"</span>
-}
-- AnyProxy Hacked!</code></pre></li>
-<li><p>Step 4, 查看请求信息</p>
-<ul class="list">
-<li>浏览器访问<a href="http://127.0.0.1:8002">http://127.0.0.1:8002</a> ,界面上能看到刚才的请求信息</li>
-</ul>
-</li>
-</ul>
-<h3 id="处理流程"><a class="header-link" href="#处理流程"></a>处理流程</h3>
-<ul class="list">
-<li>处理流程图如下</li>
-</ul>
-<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/TWyNuSJtEZBdrdcOMRjE.png" width="550" /></p>
-<ul class="list">
-<li><p>当http请求经过代理服务器时,具体处理过程是:</p>
-<ul class="list">
-<li>收集请求所有请求参数,包括method, header, body等</li>
-<li>AnyProxy调用规则模块<code>beforeSendRequest</code>方法,由模块做处理,返回新的请求参数,或返回响应内容</li>
-<li>如果<code>beforeSendRequest</code>返回了响应内容,则立即把此响应返回到客户端(而不再发送到真正的服务端),流程结束。</li>
-<li>根据请求参数,向服务端发出请求,接收服务端响应。</li>
-<li>调用规则模块<code>beforeSendResponse</code>方法,由模块对响应内容进行处理</li>
-<li>把响应信息返回给客户端</li>
-</ul>
-</li>
-<li><p>当代理服务器收到https请求时,AnyProxy可以替换证书,对请求做明文解析。</p>
-<ul class="list">
-<li>调用规则模块<code>beforeDealHttpsRequest</code>方法,如果返回<code>true</code>,会明文解析这个请求,其他请求不处理</li>
-<li>被明文解析后的https请求,处理流程同http一致。未明文解析请求不会再进入规则模块做处理。</li>
-</ul>
-</li>
-</ul>
-<h3 id="如何引用"><a class="header-link" href="#如何引用"></a>如何引用</h3>
-<p>如下几种方案都可以用来引用规则模块:</p>
-<ul class="list">
-<li>使用本地路径<pre class="hljs"><code>anyproxy --rule ./rule.js</code></pre></li>
-<li><p>使用在线地址</p>
-<pre class="hljs"><code>anyproxy --rule https://sample.com/rule.js</code></pre></li>
-<li><p>使用npm包</p>
-<ul class="list">
-<li>AnyProxy使用<code>require()</code>加载本地规则,你可以在参数里传入一个本地的npm包路径,或是某个全局安装的npm包</li>
-</ul>
-<pre class="hljs"><code>anyproxy --rule ./myRulePkg/ <span class="hljs-comment">#本地包</span>
-npm i -g myRulePkg &amp;&amp; anyproxy --rule myRulePkg <span class="hljs-comment">#全局包</span></code></pre></li>
-</ul>
-<h2 id="规则接口文档"><a class="header-link" href="#规则接口文档"></a>规则接口文档</h2>
-<p>规则模块应该符合cmd规范,一个典型的规则模块代码结构如下。模块中所有方法都是可选的,只需实现业务感兴趣的部分即可。</p>
-<pre class="hljs"><code><span class="hljs-built_in">module</span>.exports = {
-  <span class="hljs-comment">// 模块介绍</span>
-  summary: <span class="hljs-string">'my customized rule for AnyProxy'</span>, 
-  <span class="hljs-comment">// 发送请求前拦截处理</span>
-  *beforeSendRequest(requestDetail) { <span class="hljs-comment">/* ... */</span> }, 
-  <span class="hljs-comment">// 发送响应前处理</span>
-  *beforeSendResponse(requestDetail, responseDetail) { <span class="hljs-comment">/* ... */</span> }, 
-  <span class="hljs-comment">// 是否处理https请求</span>
-  *beforeDealHttpsRequest(requestDetail) { <span class="hljs-comment">/* ... */</span> }, 
-  <span class="hljs-comment">// 请求出错的事件</span>
-  *onError(requestDetail, error) { <span class="hljs-comment">/* ... */</span> }, 
-  <span class="hljs-comment">// https连接服务器出错</span>
-  *onConnectError(requestDetail, error) { <span class="hljs-comment">/* ... */</span> } 
-};</code></pre><blockquote>
-<p>规则文件中,除了summary,都是由 <a href="https://www.npmjs.com/package/co">co</a> 驱动的,函数需要满足yieldable。可以返回promise或使用generator函数。</p>
-</blockquote>
-<h3 id="summary"><a class="header-link" href="#summary"></a>summary</h3>
-<h4 id="summary-1"><a class="header-link" href="#summary-1"></a>summary</h4>
-<ul class="list">
-<li>规则模块的介绍文案,用于AnyProxy提示用户</li>
-</ul>
-<h3 id="beforesendrequest"><a class="header-link" href="#beforesendrequest"></a>beforeSendRequest</h3>
-<h4 id="beforesendrequest(requestdetail)"><a class="header-link" href="#beforesendrequest(requestdetail)"></a>beforeSendRequest(requestDetail)</h4>
-<ul class="list">
-<li>AnyProxy向服务端发送请求前,会调用<code>beforeSendRequest</code>,并带上参数<code>requestDetail</code></li>
-<li><code>requestDetail</code> <ul class="list">
-<li><code>protocol</code> {string} 请求使用的协议,http或者https</li>
-<li><code>requestOptions</code> {object} 即将发送的请求配置,供require(&#39;http&#39;).request作为使用。详见:<a href="https://nodejs.org/api/http.html#http_http_request_options_callback">https://nodejs.org/api/http.html#http_http_request_options_callback</a></li>
-<li><code>requestData</code> {object} 请求Body</li>
-<li><code>url</code> {string} 请求url</li>
-<li><code>_req</code> {object} 请求的原始request</li>
-</ul>
-</li>
-<li><p>举例:请求 <em>anyproxy.io</em> 时,<code>requestDetail</code>参数内容大致如下</p>
-<pre class="hljs"><code>{
-  <span class="hljs-attr">protocol</span>: <span class="hljs-string">'http'</span>,
-  <span class="hljs-attr">url</span>: <span class="hljs-string">'http://anyproxy.io/'</span>,
-  <span class="hljs-attr">requestOptions</span>: {
-    <span class="hljs-attr">hostname</span>: <span class="hljs-string">'anyproxy.io'</span>,
-    <span class="hljs-attr">port</span>: <span class="hljs-number">80</span>,
-    <span class="hljs-attr">path</span>: <span class="hljs-string">'/'</span>,
-    <span class="hljs-attr">method</span>: <span class="hljs-string">'GET'</span>,
-    <span class="hljs-attr">headers</span>: {
-      <span class="hljs-attr">Host</span>: <span class="hljs-string">'anyproxy.io'</span>,
-      <span class="hljs-string">'Proxy-Connection'</span>: <span class="hljs-string">'keep-alive'</span>,
-      <span class="hljs-string">'User-Agent'</span>: <span class="hljs-string">'...'</span>
-    }
-  },
-  <span class="hljs-attr">requestData</span>: <span class="hljs-string">'...'</span>,
-  <span class="hljs-attr">_req</span>: { <span class="hljs-comment">/* ... */</span>}
-}</code></pre></li>
-<li><p>以下几种返回都是合法的</p>
-<ul class="list">
-<li>不做任何处理,返回null</li>
-</ul>
-<pre class="hljs"><code><span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;</code></pre><ul class="list">
-<li>修改请求协议,如强制改用https发起请求</li>
-</ul>
-<pre class="hljs"><code><span class="hljs-keyword">return</span> {
-  <span class="hljs-attr">protocol</span>: <span class="hljs-string">'https'</span>
-};</code></pre><ul class="list">
-<li>修改请求参数</li>
-</ul>
-<pre class="hljs"><code><span class="hljs-keyword">var</span> newOption = <span class="hljs-built_in">Object</span>.assign({}, requestDetail.requestOptions);
-newOption.path = <span class="hljs-string">'/redirect/to/another/path'</span>;
-<span class="hljs-keyword">return</span> {
-  <span class="hljs-attr">requestOptions</span>: newOption
-};</code></pre><ul class="list">
-<li>修改请求body</li>
-</ul>
-<pre class="hljs"><code><span class="hljs-keyword">return</span> {
-  <span class="hljs-attr">requestData</span>: <span class="hljs-string">'my new request data'</span>
-  <span class="hljs-comment">//这里也可以同时加上requestOptions</span>
-};</code></pre><ul class="list">
-<li>直接返回客户端,不再发起请求,其中<code>statusCode</code> <code>header</code> 是必选字段</li>
-</ul>
-<pre class="hljs"><code><span class="hljs-keyword">return</span> {
-  <span class="hljs-attr">response</span>: {
-    <span class="hljs-attr">statusCode</span>: <span class="hljs-number">200</span>,
-    <span class="hljs-attr">header</span>: { <span class="hljs-string">'content-type'</span>: <span class="hljs-string">'text/html'</span> },
-    <span class="hljs-attr">body</span>: <span class="hljs-string">'this could be a &lt;string&gt; or &lt;buffer&gt;'</span>
-  }
-};</code></pre></li>
-</ul>
-<h3 id="beforesendresponse"><a class="header-link" href="#beforesendresponse"></a>beforeSendResponse</h3>
-<h4 id="beforesendresponse(requestdetail,-responsedetail)"><a class="header-link" href="#beforesendresponse(requestdetail,-responsedetail)"></a>beforeSendResponse(requestDetail, responseDetail)</h4>
-<ul class="list">
-<li>AnyProxy向客户端发送请求前,会调用<code>beforeSendResponse</code>,并带上参数<code>requestDetail</code> <code>responseDetail</code></li>
-<li><code>requestDetail</code> 同<code>beforeSendRequest</code>中的参数</li>
-<li><code>responseDetail</code> <ul class="list">
-<li><code>response</code> {object} 服务端的返回信息,包括<code>statusCode</code> <code>header</code> <code>body</code>三个字段</li>
-<li><code>_res</code> {object} 原始的服务端返回对象</li>
-</ul>
-</li>
-<li><p>举例,请求 <em>anyproxy.io</em> 时,<code>responseDetail</code>参数内容大致如下</p>
-<pre class="hljs"><code>{ 
-  <span class="hljs-attr">response</span>: { 
-    <span class="hljs-attr">statusCode</span>: <span class="hljs-number">200</span>,
-    <span class="hljs-attr">header</span>: { 
-      <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'image/gif'</span>,
-      <span class="hljs-attr">Connection</span>: <span class="hljs-string">'close'</span>,
-      <span class="hljs-string">'Cache-Control'</span>: <span class="hljs-string">'...'</span>
-    },
-    <span class="hljs-attr">body</span>: <span class="hljs-string">'...'</span>
-  },
-  <span class="hljs-attr">_res</span>: { <span class="hljs-comment">/* ... */</span> }
-}</code></pre></li>
-<li><p>以下几种返回都是合法的</p>
-<ul class="list">
-<li>不做任何处理,返回null</li>
-</ul>
-<pre class="hljs"><code><span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;</code></pre><ul class="list">
-<li>修改返回的状态码</li>
-</ul>
-<pre class="hljs"><code><span class="hljs-keyword">var</span> newResponse = <span class="hljs-built_in">Object</span>.assign({}, responseDetail.reponse);
-newResponse.statusCode = <span class="hljs-number">404</span>;
-<span class="hljs-keyword">return</span> {
-  <span class="hljs-attr">response</span>: newResponse
-};</code></pre><ul class="list">
-<li>修改返回的内容</li>
-</ul>
-<pre class="hljs"><code><span class="hljs-keyword">var</span> newResponse = <span class="hljs-built_in">Object</span>.assign({}, responseDetail.reponse);
-newResponse.body += <span class="hljs-string">'--from anyproxy--'</span>;
-<span class="hljs-keyword">return</span> {
-  <span class="hljs-attr">response</span>: newResponse
-};</code></pre></li>
-</ul>
-<h3 id="beforedealhttpsrequest"><a class="header-link" href="#beforedealhttpsrequest"></a>beforeDealHttpsRequest</h3>
-<h4 id="beforedealhttpsrequest(requestdetail)"><a class="header-link" href="#beforedealhttpsrequest(requestdetail)"></a>beforeDealHttpsRequest(requestDetail)</h4>
-<ul class="list">
-<li>AnyProxy收到https请求时,会调用<code>beforeDealHttpsRequest</code>,并带上参数<code>requestDetail</code></li>
-<li>如果配置了全局解析https的参数,则AnyProxy会略过这个调用</li>
-<li>只有返回<code>true</code>时,AnyProxy才会尝试替换证书、解析https。否则只做数据流转发,无法看到明文数据。</li>
-<li>注意:https over http的代理模式中,这里的request是CONNECT请求</li>
-<li><code>requestDetail</code><ul class="list">
-<li><code>host</code> {string} 请求目标的Host,受制于协议,这里无法获取完整url</li>
-<li><code>_req</code> {object} 请求的原始request</li>
-</ul>
-</li>
-<li>返回值<ul class="list">
-<li><code>true</code>或者<code>false</code>,表示是否需要AnyProxy替换证书并解析https</li>
-</ul>
-</li>
-</ul>
-<h3 id="onerror"><a class="header-link" href="#onerror"></a>onError</h3>
-<h4 id="onerror(requestdetail,-error)"><a class="header-link" href="#onerror(requestdetail,-error)"></a>onError(requestDetail, error)</h4>
-<ul class="list">
-<li>在请求处理过程中发生错误时,AnyProxy会调用<code>onError</code>方法,并提供对应的错误信息</li>
-<li>多数场景下,错误会在请求目标服务器的时候发生,比如DNS解析失败、请求超时等</li>
-<li><code>requestDetail</code> 同<code>beforeSendRequest</code>中的参数</li>
-<li><p>以下几种返回都是合法的</p>
-<ul class="list">
-<li>不做任何处理。此时AnyProxy会返回一个默认的错误页。</li>
-</ul>
-<pre class="hljs"><code><span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;</code></pre><ul class="list">
-<li>返回自定义错误页</li>
-</ul>
-<pre class="hljs"><code><span class="hljs-keyword">return</span> {
-  <span class="hljs-attr">response</span>: {
-    <span class="hljs-attr">statusCode</span>: <span class="hljs-number">200</span>,
-    <span class="hljs-attr">header</span>: { <span class="hljs-string">'content-type'</span>: <span class="hljs-string">'text/html'</span> },
-    <span class="hljs-attr">body</span>: <span class="hljs-string">'this could be a &lt;string&gt; or &lt;buffer&gt;'</span>
-  }
-};</code></pre></li>
-</ul>
-<h3 id="onconnecterror"><a class="header-link" href="#onconnecterror"></a>onConnectError</h3>
-<h4 id="onconnecterror(requestdetail,-error)"><a class="header-link" href="#onconnecterror(requestdetail,-error)"></a>onConnectError(requestDetail, error)</h4>
-<ul class="list">
-<li>AnyProxy在与目标HTTPS服务器建立连接的过程中,如果发生错误,AnyProxy会调用这个方法</li>
-<li><code>requestDetail</code> 同<code>beforeDealHttpsRequest</code>中的参数</li>
-<li>此处无法控制向客户端的返回信息,无需返回值。</li>
-</ul>
-<h3 id="faq"><a class="header-link" href="#faq"></a>FAQ</h3>
-<ul class="list">
-<li>Q: 为什么https请求不能进入处理函数?</li>
-<li><p>A: 以下任意一项都能用来改变https的处理特性:</p>
-<ol class="list">
-<li>命令行启动AnyProxy时配置<code>--intercept</code>参数,按npm模块启动时配置<code>forceProxyHttps</code>参数,所有Https请求都会被替换证书并解析</li>
-<li>规则文件内提供<code>beforeDealHttpsRequest</code>方法,返回 <em>true</em> 的https请求会被解析</li>
-</ol>
-</li>
-<li><p>Q: 提示 <em>function is not yieldable</em></p>
-</li>
-<li>A: 规则模块是用 <a href="https://www.npmjs.com/package/co">co</a> 驱动的,函数需要满足yieldable。可以使用generator方法或是返回Promise。</li>
-</ul>
-<h2 id="规则模块样例"><a class="header-link" href="#规则模块样例"></a>规则模块样例</h2>
-<ul class="list">
-<li>这里提供一些样例,来讲解规则模块的常见用法</li>
-<li>你可以通过 <code>anyproxy --rule http://....js</code> 来加载模块并体验</li>
-<li>用curl发请求测试的方法如下<ul class="list">
-<li>直接请求服务器:<code>curl http://httpbin.org/</code></li>
-<li>通过代理服务器请求:<code>curl http://httpbin.org/ --proxy http://127.0.0.1:8001</code></li>
-</ul>
-</li>
-</ul>
-<h3 id="使用本地数据"><a class="header-link" href="#使用本地数据"></a>使用本地数据</h3>
-<ul class="list">
-<li>拦截发送到 <a href="http://httpbin.org">http://httpbin.org</a> 的请求,使用本地数据代替服务端返回</li>
-</ul>
-<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_use_local_response.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
-  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
-*/</span>
-<span class="hljs-built_in">module</span>.exports = {
-  *beforeSendRequest(requestDetail) {
-    <span class="hljs-keyword">const</span> localResponse = {
-      <span class="hljs-attr">statusCode</span>: <span class="hljs-number">200</span>,
-      <span class="hljs-attr">header</span>: { <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'application/json'</span> },
-      <span class="hljs-attr">body</span>: <span class="hljs-string">'{"hello": "this is local response"}'</span>
-    };
-    <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org'</span>) === <span class="hljs-number">0</span>) {
-      <span class="hljs-keyword">return</span> {
-        <span class="hljs-attr">response</span>: localResponse
-      };
-    }
-  },
-};</code></pre><h3 id="修改请求头"><a class="header-link" href="#修改请求头"></a>修改请求头</h3>
-<ul class="list">
-<li>修改发送到 httpbin.org 的user-agent</li>
-</ul>
-<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_request_header.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
-  sample: 
-    modify the user-agent in requests toward httpbin.org
-  test:
-    curl http://httpbin.org/user-agent --proxy http://127.0.0.1:8001
-*/</span>
-<span class="hljs-built_in">module</span>.exports = {
-  *beforeSendRequest(requestDetail) {
-    <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org'</span>) === <span class="hljs-number">0</span>) {
-      <span class="hljs-keyword">const</span> newRequestOptions = requestDetail.requestOptions;
-      newRequestOptions.headers[<span class="hljs-string">'User-Agent'</span>] = <span class="hljs-string">'AnyProxy/0.0.0'</span>;
-      <span class="hljs-keyword">return</span> {
-        <span class="hljs-attr">requestOptions</span>: newRequestOptions
-      };
-    }
-  },
-};</code></pre><h3 id="修改请求数据"><a class="header-link" href="#修改请求数据"></a>修改请求数据</h3>
-<ul class="list">
-<li>修改发送到 <a href="http://httpbin.org/post">http://httpbin.org/post</a> 的post数据</li>
-</ul>
-<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_request_data.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
-  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" }
-*/</span>
-<span class="hljs-built_in">module</span>.exports = {
-  *beforeSendRequest(requestDetail) {
-    <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org/post'</span>) === <span class="hljs-number">0</span>) {
-      <span class="hljs-keyword">return</span> {
-        <span class="hljs-attr">requestData</span>: <span class="hljs-string">'i-am-anyproxy-modified-post-data'</span>
-      };
-    }
-  },
-};</code></pre><h3 id="修改请求的目标地址"><a class="header-link" href="#修改请求的目标地址"></a>修改请求的目标地址</h3>
-<ul class="list">
-<li>把所有发送到 <a href="http://httpbin.org/">http://httpbin.org/</a> 的请求全部改到 <a href="http://httpbin.org/user-agent">http://httpbin.org/user-agent</a></li>
-</ul>
-<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_request_path.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
-  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" }
-*/</span>
-<span class="hljs-built_in">module</span>.exports = {
-  *beforeSendRequest(requestDetail) {
-    <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org'</span>) === <span class="hljs-number">0</span>) {
-      <span class="hljs-keyword">const</span> newRequestOptions = requestDetail.requestOptions;
-      newRequestOptions.path = <span class="hljs-string">'/user-agent'</span>;
-      newRequestOptions.method = <span class="hljs-string">'GET'</span>;
-      <span class="hljs-keyword">return</span> {
-        <span class="hljs-attr">requestOptions</span>: newRequestOptions
-      };
-    }
-  },
-};</code></pre><h3 id="修改请求协议"><a class="header-link" href="#修改请求协议"></a>修改请求协议</h3>
-<ul class="list">
-<li>把用http协议请求的 <a href="http://httpbin.org">http://httpbin.org</a> 改成https并发送</li>
-</ul>
-<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_request_protocol.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
-  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" }
-*/</span>
-<span class="hljs-built_in">module</span>.exports = {
-  *beforeSendRequest(requestDetail) {
-    <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org'</span>) === <span class="hljs-number">0</span>) {
-      <span class="hljs-keyword">const</span> newOption = requestDetail.requestOptions;
-      newOption.port = <span class="hljs-number">443</span>;
-      <span class="hljs-keyword">return</span> {
-        <span class="hljs-attr">protocol</span>: <span class="hljs-string">'https'</span>,
-        <span class="hljs-attr">requestOptions</span>: newOption
-      };
-    }
-  }
-};</code></pre><h3 id="修改返回状态码"><a class="header-link" href="#修改返回状态码"></a>修改返回状态码</h3>
-<ul class="list">
-<li>把 所有<a href="http://httpbin.org">http://httpbin.org</a> 的返回状态码都改成404</li>
-</ul>
-<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_response_statuscode.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
-  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
-*/</span>
-<span class="hljs-built_in">module</span>.exports = {
-  *beforeSendResponse(requestDetail, responseDetail) {
-    <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org'</span>) === <span class="hljs-number">0</span>) {
-      <span class="hljs-keyword">const</span> newResponse = responseDetail.response;
-      newResponse.statusCode = <span class="hljs-number">404</span>;
-      <span class="hljs-keyword">return</span> {
-        <span class="hljs-attr">response</span>: newResponse
-      };
-    }
-  }
-};</code></pre><h3 id="修改返回头"><a class="header-link" href="#修改返回头"></a>修改返回头</h3>
-<ul class="list">
-<li>在 <a href="http://httpbin.org/user-agent">http://httpbin.org/user-agent</a> 的返回头里加上 X-Proxy-By:AnyProxy</li>
-</ul>
-<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_response_header.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
-  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
-*/</span>
-<span class="hljs-built_in">module</span>.exports = {
-  *beforeSendResponse(requestDetail, responseDetail) {
-    <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org/user-agent'</span>) === <span class="hljs-number">0</span>) {
-      <span class="hljs-keyword">const</span> newResponse = responseDetail.response;
-      newResponse.header[<span class="hljs-string">'X-Proxy-By'</span>] = <span class="hljs-string">'AnyProxy'</span>;
-      <span class="hljs-keyword">return</span> {
-        <span class="hljs-attr">response</span>: newResponse
-      };
-    }
-  }
-};</code></pre><h3 id="修改返回内容并延迟"><a class="header-link" href="#修改返回内容并延迟"></a>修改返回内容并延迟</h3>
-<ul class="list">
-<li>在 <a href="http://httpbin.org/user-agent">http://httpbin.org/user-agent</a> 的返回最后追加AnyProxy的签名,并延迟5秒</li>
-</ul>
-<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_response_data.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
-  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! --
-*/</span>
-
-<span class="hljs-built_in">module</span>.exports = {
-  *beforeSendResponse(requestDetail, responseDetail) {
-    <span class="hljs-keyword">if</span> (requestDetail.url === <span class="hljs-string">'http://httpbin.org/user-agent'</span>) {
-      <span class="hljs-keyword">const</span> newResponse = responseDetail.response;
-      newResponse.body += <span class="hljs-string">'-- AnyProxy Hacked! --'</span>;
-      <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =&gt;</span> {
-        setTimeout(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> { <span class="hljs-comment">// delay the response for 5s</span>
-          resolve({ <span class="hljs-attr">response</span>: newResponse });
-        }, <span class="hljs-number">5000</span>);
-      });
-    }
-  },
-};</code></pre><h2 id="作为npm模块使用"><a class="header-link" href="#作为npm模块使用"></a>作为npm模块使用</h2>
-<p>AnyProxy可以作为一个npm模块使用,整合进其他工具。</p>
-<blockquote>
-<p>如要启用https解析,请在代理服务器启动前自行调用<code>AnyProxy.utils.certMgr</code>相关方法生成证书,并引导用户信任安装。或引导用户使用<code>anyproxy-ca</code>方法。</p>
-</blockquote>
-<ul class="list">
-<li>引入</li>
-</ul>
-<pre class="hljs"><code>npm i anyproxy@beta --save <span class="hljs-comment"># 4.0版正在beta中</span></code></pre><ul class="list">
-<li>使用举例</li>
-</ul>
-<pre class="hljs"><code><span class="hljs-keyword">const</span> AnyProxy = <span class="hljs-built_in">require</span>(<span class="hljs-string">'anyproxy'</span>);
-<span class="hljs-keyword">const</span> options = {
-  <span class="hljs-attr">port</span>: <span class="hljs-number">8001</span>,
-  <span class="hljs-attr">rule</span>: <span class="hljs-built_in">require</span>(<span class="hljs-string">'myRuleModule'</span>),
-  <span class="hljs-attr">webInterface</span>: {
-    <span class="hljs-attr">enable</span>: <span class="hljs-literal">true</span>,
-    <span class="hljs-attr">webPort</span>: <span class="hljs-number">8002</span>,
-    <span class="hljs-attr">wsPort</span>: <span class="hljs-number">8003</span>,
-  },
-  <span class="hljs-attr">throttle</span>: <span class="hljs-number">10000</span>,
-  <span class="hljs-attr">forceProxyHttps</span>: <span class="hljs-literal">false</span>,
-  <span class="hljs-attr">silent</span>: <span class="hljs-literal">false</span>
-};
-<span class="hljs-keyword">const</span> proxyServer = <span class="hljs-keyword">new</span> AnyProxy.ProxyServer(options);
-
-proxyServer.on(<span class="hljs-string">'ready'</span>, () =&gt; { <span class="hljs-comment">/* */</span> });
-proxyServer.on(<span class="hljs-string">'error'</span>, (e) =&gt; { <span class="hljs-comment">/* */</span> });
-proxyServer.start();
-
-<span class="hljs-comment">//when finished</span>
-proxyServer.close();</code></pre><ul class="list">
-<li><p>Class: AnyProxy.proxyServer</p>
-<ul class="list">
-<li><p>创建代理服务器</p>
-<pre class="hljs"><code><span class="hljs-keyword">const</span> proxy = <span class="hljs-keyword">new</span> AnyProxy.proxyServer(options)</code></pre></li>
-<li><p><code>options</code></p>
-<ul class="list">
-<li><code>port</code> {number} 必选,代理服务器端口</li>
-<li><code>rule</code> {object} 自定义规则模块</li>
-<li><code>throttle</code> {number} 限速值,单位kb/s,默认不限速</li>
-<li><code>forceProxyHttps</code> {boolean} 是否强制拦截所有的https,忽略规则模块的返回,默认<code>false</code></li>
-<li><code>silent</code> {boolean} 是否屏蔽所有console输出,默认<code>false</code></li>
-<li><code>dangerouslyIgnoreUnauthorized</code> {boolean} 是否忽略请求中的证书错误,默认<code>false</code></li>
-<li><code>webInterface</code> {object} web版界面配置<ul class="list">
-<li><code>enable</code> {boolean} 是否启用web版界面,默认<code>false</code></li>
-<li><code>webPort</code> {number} web版界面端口号,默认<code>8002</code></li>
-</ul>
-</li>
-</ul>
-</li>
-<li><p>Event: <code>ready</code></p>
-<ul class="list">
-<li>代理服务器启动完成</li>
-<li>示例</li>
-</ul>
-<pre class="hljs"><code>proxy.on(<span class="hljs-string">'ready'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{ })</code></pre></li>
-<li><p>Event: <code>error</code></p>
-<ul class="list">
-<li>代理服务器发生错误</li>
-<li>示例</li>
-</ul>
-<pre class="hljs"><code>proxy.on(<span class="hljs-string">'error'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{ })</code></pre></li>
-<li><p>Method: <code>start</code></p>
-<ul class="list">
-<li>启动代理服务器</li>
-<li>示例</li>
-</ul>
-<pre class="hljs"><code>proxy.start();</code></pre></li>
-<li><p>Method: <code>close</code></p>
-<ul class="list">
-<li>关闭代理服务器</li>
-<li>示例</li>
-</ul>
-<pre class="hljs"><code>proxy.close();</code></pre></li>
-</ul>
-</li>
-<li><p>AnyProxy.utils.systemProxyMgr</p>
-<ul class="list">
-<li>管理系统的全局代理配置,方法调用时可能会弹出密码框</li>
-<li>使用示例</li>
-</ul>
-<pre class="hljs"><code><span class="hljs-comment">// 配置127.0.0.1:8001为全局http代理服务器</span>
-AnyProxy.utils.systemProxyMgr.enableGlobalProxy(<span class="hljs-string">'127.0.0.1'</span>, <span class="hljs-string">'8001'</span>);    
-
-<span class="hljs-comment">// 关闭全局代理服务器</span>
-AnyProxy.utils.systemProxyMgr.disableGlobalProxy();</code></pre></li>
-<li><p>AnyProxy.utils.certMgr</p>
-<ul class="list">
-<li>管理AnyProxy的证书</li>
-<li><code>AnyProxy.utils.certMgr.ifRootCAFileExists()</code><ul class="list">
-<li>校验系统内是否存在AnyProxy的根证书</li>
-</ul>
-</li>
-<li><code>AnyProxy.utils.certMgr.generateRootCA(callback)</code><ul class="list">
-<li>生成AnyProxy的rootCA,完成后请引导用户信任.crt文件</li>
-</ul>
-</li>
-<li>样例</li>
-</ul>
-<pre class="hljs"><code>  <span class="hljs-keyword">const</span> AnyProxy = <span class="hljs-built_in">require</span>(<span class="hljs-string">'AnyProxy'</span>);
-  <span class="hljs-keyword">const</span> exec = <span class="hljs-built_in">require</span>(<span class="hljs-string">'child_process'</span>).exec;
-
-  <span class="hljs-keyword">if</span> (!AnyProxy.utils.certMgr.ifRootCAFileExists()) {
-    AnyProxy.utils.certMgr.generateRootCA(<span class="hljs-function">(<span class="hljs-params">error, keyPath</span>) =&gt;</span> {
-      <span class="hljs-comment">// let users to trust this CA before using proxy</span>
-      <span class="hljs-keyword">if</span> (!error) {
-        <span class="hljs-keyword">const</span> certDir = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>).dirname(keyPath);
-        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'The cert is generated at'</span>, certDir);
-        <span class="hljs-keyword">const</span> isWin = <span class="hljs-regexp">/^win/</span>.test(process.platform);
-        <span class="hljs-keyword">if</span> (isWin) {
-          exec(<span class="hljs-string">'start .'</span>, { <span class="hljs-attr">cwd</span>: certDir });
-        } <span class="hljs-keyword">else</span> {
-          exec(<span class="hljs-string">'open .'</span>, { <span class="hljs-attr">cwd</span>: certDir });
-        }
-      } <span class="hljs-keyword">else</span> {
-        <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'error when generating rootCA'</span>, error);
-      }
-    });
-  }</code></pre></li>
-</ul>
-<h2 id="关于anyproxy"><a class="header-link" href="#关于anyproxy"></a>关于AnyProxy</h2>
-<ul class="list">
-<li>AnyProxy是支付宝前端团队推出的开源产品</li>
-<li>Change Log: <a href="https://github.com/alibaba/anyproxy/blob/master/CHANGELOG">https://github.com/alibaba/anyproxy/blob/master/CHANGELOG</a></li>
-<li>代码库:<a href="https://github.com/alibaba/anyproxy">https://github.com/alibaba/anyproxy</a></li>
-<li>issue反馈:<a href="https://github.com/alibaba/anyproxy/issues">https://github.com/alibaba/anyproxy/issues</a></li>
-</ul>
-<h2 id="配置帮助"><a class="header-link" href="#配置帮助"></a>配置帮助</h2>
-<h3 id="osx系统信任ca证书"><a class="header-link" href="#osx系统信任ca证书"></a>OSX系统信任CA证书</h3>
-<ul class="list">
-<li>类似这种报错都是因为系统没有信任AnyProxy生成的CA所造成的</li>
-</ul>
-<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/CBkLGYgvoHAYwNVAYkpk.png" width="450" /></p>
-<blockquote>
-<p>警告:CA证书和系统安全息息相关,建议亲自生成,并妥善保管</p>
-</blockquote>
-<p>安装CA:</p>
-<ul class="list">
-<li><p>双击打开<em>rootCA.crt</em></p>
-</li>
-<li><p>确认将证书添加到login或system</p>
-</li>
-</ul>
-<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/bCwNUFFpvsmVuljQKrIk.png" width="350" /></p>
-<ul class="list">
-<li>找到刚刚导入的AnyProxy证书,配置为信任(Always Trust)</li>
-</ul>
-<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/HOmEElNGdoZEWFMLsTNT.png" width="700" /></p>
-<h3 id="windows系统信任ca证书"><a class="header-link" href="#windows系统信任ca证书"></a>Windows系统信任CA证书</h3>
-<p class="img-container"><img src="https://t.alipayobjects.com/tfscom/T1D3hfXeFtXXXXXXXX.jpg" width="700" /></p>
-<h3 id="配置osx系统代理"><a class="header-link" href="#配置osx系统代理"></a>配置OSX系统代理</h3>
-<ul class="list">
-<li>在wifi高级设置中,配置http代理即可</li>
-</ul>
-<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/vduwhobSTypTfgniBvoa.png" width="500" /></p>
-<h3 id="配置浏览器http代理"><a class="header-link" href="#配置浏览器http代理"></a>配置浏览器HTTP代理</h3>
-<ul class="list">
-<li>以Chrome的<a href="https://chrome.google.com/webstore/detail/padekgcemlokbadohgkifijomclgjgif">SwitchyOmega插件</a>为例</li>
-</ul>
-<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/jIPZrKmqXRaSledQeJUJ.png" width="500" /></p>
-<h3 id="ios系统信任ca证书"><a class="header-link" href="#ios系统信任ca证书"></a>iOS系统信任CA证书</h3>
-<ul class="list">
-<li>点击web ui中的 <em>Root CA</em>,按提示扫描二维码即可安装</li>
-</ul>
-<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/BrugmMelGVysLDOIBblj.png" width="260" /></p>
-<h3 id="ios->=-10.3信任ca证书"><a class="header-link" href="#ios->=-10.3信任ca证书"></a>iOS &gt;= 10.3信任CA证书</h3>
-<ul class="list">
-<li>除了上述证书安装过程,还需要在 <em>设置-&gt;通用-&gt;证书信任设置</em> 中把AnyProxy证书的开关打开,否则safari将报错。</li>
-</ul>
-<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/hVWkXHrzHmOKOtCKGUWx.png" width="500" /></p>
-<h3 id="配置ios/android系统代理"><a class="header-link" href="#配置ios/android系统代理"></a>配置iOS/Android系统代理</h3>
-<ul class="list">
-<li><p>代理服务器都在wifi设置中配置</p>
-</li>
-<li><p>iOS HTTP代理配置</p>
-</li>
-</ul>
-<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/tLGqIozhffTccUgPakuw.png" width="260" /></p>
-<ul class="list">
-<li>Android HTTP代理配置</li>
-</ul>
-<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/YQtbQYVNuOszZGdAOauU.png" width="260" /></p>
-    </div>
-  </article>
-
-  <script src="//cdn.bootcss.com/zepto/1.2.0/zepto.min.js"></script>
-  <script>
-  window.onload = function(){
-    var itemList = [];
-    var targetMap = {};
-    $("[id]", ".main-content").map(function (index, heading) {
-      targetMap[heading.getAttribute('id')] = heading;
-    });
-
-    $("#j_toc li").map(function (index, item) {
-      if (item.className.indexOf('sidebar-header-2') >= 0 || item.className.indexOf('sidebar-header-3') >= 0) {
-        var targetName = item.firstChild.getAttribute('href').replace('#', '');
-        var targetItem = targetMap[targetName];
-        itemList.push({ target: targetItem, tocItem: item, top: $(targetItem).position().top });
-      }
-    });
-
-    var updateTocActive = function (e) {
-      var windowHeight = window.innerHeight;
-      //find the first item to match
-      var scrollYThres = window.scrollY + 200;
-      var target;
-      if (scrollYThres < 100) {
-        target = itemList[0].tocItem;
-      } else {
-        itemList.forEach(function (item, index) {
-          if (target) return;
-          if (index > 0) {
-            if (item.top >= scrollYThres) {
-              target = itemList[index - 1].tocItem;
-            }
-          }
-        });
-      }
-
-      $('.toc-active').removeClass('toc-active');
-      $(target).addClass('toc-active');
-    };
-
-    window.onscroll = updateTocActive;
-    updateTocActive();
-  }
-  </script>
 </body>
 
 </html>
\ No newline at end of file
diff --git a/4.x/en.html b/4.x/en.html
index 3ee6ab7..2efb7d4 100644
--- a/4.x/en.html
+++ b/4.x/en.html
@@ -15,7 +15,7 @@
   <script>
     //redirect to Chinese version if in China
     if (new Date().getTimezoneOffset() == "-480" && !(/(cn|en)/i.test(location.href))) {
-      location.href = "./cn.html";
+      location.href = "/";
     } else {
       var _hmt = _hmt || []; (function () { var hm = document.createElement("script"); hm.src = "//hm.baidu.com/hm.js?4e51565b7d471fd6623c163a8fd79e07"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })();
     }
@@ -23,810 +23,7 @@
 </head>
 
 <body>
-  <a href="https://github.com/alibaba/anyproxy/tree/4.x" target="_blank">
-    <img style="position: fixed; top: 0; right: 0; border: 0;z-index: 1;" src="https://camo.githubusercontent.com/a6677b08c955af8400f44c6298f40e7d19cc5b2d/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f677261795f3664366436642e706e67"
-      alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_gray_6d6d6d.png">
-  </a>
-
-  <article class="markdown-body">
-    <div class="toc-container" id="j_toc">
-      <div class="toc-content"><ul class="nav nav-list">
-    <li class="sidebar-header-1"><a href="#anyproxy">AnyProxy</a></li>
-    <li class="sidebar-header-2"><a href="#quick-start">Quick start</a></li>
-    <li class="sidebar-header-3"><a href="#install">install</a></li>
-    <li class="sidebar-header-3"><a href="#launch">launch</a></li>
-    <li class="sidebar-header-3"><a href="#other-commands">other commands</a></li>
-    <li class="sidebar-header-2"><a href="#proxy-https-request">Proxy https request</a></li>
-    <li class="sidebar-header-2"><a href="#use-rule-module">Use rule module</a></li>
-    <li class="sidebar-header-3"><a href="#sample">sample</a></li>
-    <li class="sidebar-header-3"><a href="#the-entire-process">the entire process</a></li>
-    <li class="sidebar-header-3"><a href="#how-to-load-rule-module">how to load rule module</a></li>
-    <li class="sidebar-header-2"><a href="#rule-module-interface">Rule module interface</a></li>
-    <li class="sidebar-header-3"><a href="#summary">summary</a></li>
-    <li class="sidebar-header-4"><a href="#summary-1">summary</a></li>
-    <li class="sidebar-header-3"><a href="#beforesendrequest">beforeSendRequest</a></li>
-    <li class="sidebar-header-4"><a href="#beforesendrequest(requestdetail)">beforeSendRequest(requestDetail)</a></li>
-    <li class="sidebar-header-3"><a href="#beforesendresponse">beforeSendResponse</a></li>
-    <li class="sidebar-header-4"><a href="#beforesendresponse(requestdetail,-responsedetail)">beforeSendResponse(requestDetail, responseDetail)</a></li>
-    <li class="sidebar-header-3"><a href="#beforedealhttpsrequest">beforeDealHttpsRequest</a></li>
-    <li class="sidebar-header-4"><a href="#beforedealhttpsrequest(requestdetail)">beforeDealHttpsRequest(requestDetail)</a></li>
-    <li class="sidebar-header-3"><a href="#onerror">onError</a></li>
-    <li class="sidebar-header-4"><a href="#onerror(requestdetail,-error)">onError(requestDetail, error)</a></li>
-    <li class="sidebar-header-3"><a href="#onconnecterror">onConnectError</a></li>
-    <li class="sidebar-header-4"><a href="#onconnecterror(requestdetail,-error)">onConnectError(requestDetail, error)</a></li>
-    <li class="sidebar-header-3"><a href="#faq">FAQ</a></li>
-    <li class="sidebar-header-2"><a href="#rule-samples">Rule Samples</a></li>
-    <li class="sidebar-header-3"><a href="#use-local-response">use local response</a></li>
-    <li class="sidebar-header-3"><a href="#modify-request-header">modify request header</a></li>
-    <li class="sidebar-header-3"><a href="#modify-request-body">modify request body</a></li>
-    <li class="sidebar-header-3"><a href="#modify-the-request-target">modify the request target</a></li>
-    <li class="sidebar-header-3"><a href="#modify-request-protocol">modify request protocol</a></li>
-    <li class="sidebar-header-3"><a href="#modify-response-status-code">modify response status code</a></li>
-    <li class="sidebar-header-3"><a href="#modify-the-response-header">modify the response header</a></li>
-    <li class="sidebar-header-3"><a href="#modify-response-data-and-delay">modify response data and delay</a></li>
-    <li class="sidebar-header-2"><a href="#use-anyproxy-as-an-npm-module">Use AnyProxy as an npm module</a></li>
-    <li class="sidebar-header-2"><a href="#about-anyproxy">About AnyProxy</a></li>
-    <li class="sidebar-header-2"><a href="#appendix">Appendix</a></li>
-    <li class="sidebar-header-3"><a href="#config-root-ca-in-osx">Config root CA in OSX</a></li>
-    <li class="sidebar-header-3"><a href="#trust-root-ca-in-windows">trust root CA in windows</a></li>
-    <li class="sidebar-header-3"><a href="#config-osx-system-proxy">config OSX system proxy</a></li>
-    <li class="sidebar-header-3"><a href="#config-http-proxy-server">config http proxy server</a></li>
-    <li class="sidebar-header-3"><a href="#trust-root-ca-in-ios">trust root CA in iOS</a></li>
-    <li class="sidebar-header-3"><a href="#trust-root-ca-in-ios-&gt;&#x3D;-10.3">trust root CA in iOS &gt;&#x3D; 10.3</a></li>
-    <li class="sidebar-header-3"><a href="#config-ios/android-proxy-server">config iOS/Android proxy server</a></li>
-</ul>
-      </div>
-    </div>
-    <div class="main-content"><h1 id="anyproxy"><a class="header-link" href="#anyproxy"></a>AnyProxy</h1>
-<p>AnyProxy is a fully configurable http/https proxy in NodeJS. Version 4.0 is in beta now.</p>
-<p>Ref: <a href="./cn.html">Chinese Doc 中文文档</a></p>
-<p>Github: </p>
-<ul class="list">
-<li><a href="https://github.com/alibaba/anyproxy/tree/4.x">https://github.com/alibaba/anyproxy/tree/4.x</a></li>
-</ul>
-<p>Features:</p>
-<ul class="list">
-<li>Offer you the ablity to handle http traffic by invoking a js module</li>
-<li>Intercept https</li>
-<li>GUI webinterface</li>
-</ul>
-<p>Change Logs since 3.x:</p>
-<ul class="list">
-<li>Support Promise and Generator in rule module</li>
-<li>Simplified interface in rule module</li>
-<li>A newly designed web interface</li>
-</ul>
-<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/SqVntpzmscXPbSzfcGcr.png" width="500" /></p>
-<h2 id="quick-start"><a class="header-link" href="#quick-start"></a>Quick start</h2>
-<h3 id="install"><a class="header-link" href="#install"></a>install</h3>
-<pre class="hljs"><code>npm install -g anyproxy@beta <span class="hljs-comment"># 4.x is in beta now</span></code></pre><h3 id="launch"><a class="header-link" href="#launch"></a>launch</h3>
-<ul class="list">
-<li>start AnyProxy in command line, with default port 8001</li>
-</ul>
-<pre class="hljs"><code>anyproxy</code></pre><ul class="list">
-<li>now you can use http proxy server by 127.0.0.1:8001</li>
-<li>visit <a href="http://127.0.0.1:8002">http://127.0.0.1:8002</a> to see the http requests</li>
-</ul>
-<h3 id="other-commands"><a class="header-link" href="#other-commands"></a>other commands</h3>
-<ul class="list">
-<li>specify the port of http proxy</li>
-</ul>
-<pre class="hljs"><code>anyproxy --port 1080</code></pre><h2 id="proxy-https-request"><a class="header-link" href="#proxy-https-request"></a>Proxy https request</h2>
-<ul class="list">
-<li>AnyProxy does NOT intercept https requests by default. To view decrypted info, you have to config the CA certificate.</li>
-</ul>
-<blockquote>
-<p>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.</p>
-</blockquote>
-<ul class="list">
-<li>generate certifycates and intercept</li>
-</ul>
-<pre class="hljs"><code>anyproxy-ca <span class="hljs-comment">#generate root CA. manually trust it after that.</span>
-anyproxy --intercept <span class="hljs-comment">#launch anyproxy and intercept all https traffic</span></code></pre><ul class="list">
-<li><a href="#osx系统信任ca证书">Appendix:how to trust CA</a></li>
-</ul>
-<h2 id="use-rule-module"><a class="header-link" href="#use-rule-module"></a>Use rule module</h2>
-<p>AnyProxy provides the ability to load your own rules written in javascript. With rule module, you could customize the logic to handle requests.</p>
-<blockquote>
-<p>Make sure your rule file is got from a trusted source. Otherwise, you may face some unknown security risk.</p>
-</blockquote>
-<p>Rule module could do the following stuff:</p>
-<ul class="list">
-<li>intercept and modify the request which is being sent<ul class="list">
-<li>editable fields include request header, body, target address</li>
-</ul>
-</li>
-<li>intercept and modify the response from server<ul class="list">
-<li>editable fields include response status code, header, body</li>
-</ul>
-</li>
-<li>intercept https requests, modify request and response</li>
-</ul>
-<h3 id="sample"><a class="header-link" href="#sample"></a>sample</h3>
-<ul class="list">
-<li><p>Target</p>
-<ul class="list">
-<li>write a rule module to append some text to the response of GET <a href="http://httpbin.org/user-agent">http://httpbin.org/user-agent</a>, and delay the response for 5 seconds</li>
-</ul>
-</li>
-<li><p>Step 1,Write the rule file, save as sample.js</p>
-<pre class="hljs"><code><span class="hljs-comment">// file: sample.js</span>
-<span class="hljs-built_in">module</span>.exports = {
-  <span class="hljs-attr">summary</span>: <span class="hljs-string">'a rule to modify response'</span>,
-  *beforeSendResponse(requestDetail, responseDetail) {
-    <span class="hljs-keyword">if</span> (requestDetail.url === <span class="hljs-string">'http://httpbin.org/user-agent'</span>) {
-      <span class="hljs-keyword">const</span> newResponse = responseDetail.response;
-      newResponse.body += <span class="hljs-string">'-- AnyProxy Hacked! --'</span>;
-      <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =&gt;</span> {
-        setTimeout(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> { <span class="hljs-comment">// delay</span>
-          resolve({ <span class="hljs-attr">response</span>: newResponse });
-        }, <span class="hljs-number">5000</span>);
-      });
-    }
-  },
-};</code></pre></li>
-<li><p>Step 2, start AnyProxy and load the rule file</p>
-<ul class="list">
-<li>run <code>anyproxy --rule sample.js</code></li>
-</ul>
-</li>
-<li><p>Step 3, test</p>
-<ul class="list">
-<li><p>use curl </p>
-<pre class="hljs"><code>curl http://httpbin.org/user-agent --proxy http://127.0.0.1:8001</code></pre></li>
-<li><p>use browser. Point the http proxy of browser to 127.0.0.1:8001, then visit <a href="http://httpbin.org/user-agent">http://httpbin.org/user-agent</a> </p>
-</li>
-<li><p>the expected response from proxy is </p>
-</li>
-</ul>
-<pre class="hljs"><code>{
-  <span class="hljs-string">"user-agent"</span>: <span class="hljs-string">"curl/7.43.0"</span>
-}
-- AnyProxy Hacked!</code></pre></li>
-<li><p>Step 4, view the request log</p>
-<ul class="list">
-<li>visit <a href="http://127.0.0.1:8002">http://127.0.0.1:8002</a>, the request just sent should be listed here</li>
-</ul>
-</li>
-</ul>
-<h3 id="the-entire-process"><a class="header-link" href="#the-entire-process"></a>the entire process</h3>
-<ul class="list">
-<li>The flow chart is as follows</li>
-</ul>
-<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/TWyNuSJtEZBdrdcOMRjE.png" width="550" /></p>
-<ul class="list">
-<li><p>When got an http request, the entire process of proxy server is</p>
-<ul class="list">
-<li>AnyProxy collects all the quest info, include method, header, body</li>
-<li>AnyProxy calls <code>beforeSendRequest</code> of the rule module. Rule module deal the request, return new request param or response content</li>
-<li>If <code>beforeSendRequest</code> returns the response content, AnyProxy will send the response to client without sending to target server. The process ends here.</li>
-<li>Send request to target server, collect response</li>
-<li>Call <code>beforeSendResponse</code> of the rule module. Rule module deal the response data</li>
-<li>Send response to client</li>
-</ul>
-</li>
-<li><p>When AnyProxy get https request, it could replace the certificate and decrypt the request data</p>
-<ul class="list">
-<li>AnyProxy calls <code>beforeDealHttpsRequest</code> of the rule module</li>
-<li>If the function returns <code>true</code>, AnyProxy will do the man-in-the-middle attack to it. Otherwise, the request will not be dealed.</li>
-</ul>
-</li>
-</ul>
-<h3 id="how-to-load-rule-module"><a class="header-link" href="#how-to-load-rule-module"></a>how to load rule module</h3>
-<ul class="list">
-<li><p>use local file</p>
-<pre class="hljs"><code>anyproxy --rule ./rule.js</code></pre></li>
-<li><p>use an online rule file</p>
-<pre class="hljs"><code>anyproxy --rule https://sample.com/rule.js</code></pre></li>
-<li><p>use an npm module</p>
-<ul class="list">
-<li>AnyProxy uses <code>require()</code> to load rule module. You could either load a local npm module or a global-installed one.</li>
-</ul>
-<pre class="hljs"><code>anyproxy --rule ./myRulePkg/ <span class="hljs-comment">#local module</span>
-npm i -g myRulePkg &amp;&amp; anyproxy --rule myRulePkg <span class="hljs-comment">#global-installed module</span></code></pre></li>
-</ul>
-<h2 id="rule-module-interface"><a class="header-link" href="#rule-module-interface"></a>Rule module interface</h2>
-<p>A typical rule module is as follows. All the functions are optional, just write the part you are interested in.</p>
-<pre class="hljs"><code><span class="hljs-built_in">module</span>.exports = {
-  <span class="hljs-comment">// introduction</span>
-  summary: <span class="hljs-string">'my customized rule for AnyProxy'</span>, 
-  <span class="hljs-comment">// intercept before send request to server</span>
-  *beforeSendRequest(requestDetail) { <span class="hljs-comment">/* ... */</span> }, 
-  <span class="hljs-comment">// deal response before send to client </span>
-  *beforeSendResponse(requestDetail, responseDetail) { <span class="hljs-comment">/* ... */</span> }, 
-  <span class="hljs-comment">// if deal https request</span>
-  *beforeDealHttpsRequest(requestDetail) { <span class="hljs-comment">/* ... */</span> }, 
-  <span class="hljs-comment">// error happened when dealing requests</span>
-  *onError(requestDetail, error) { <span class="hljs-comment">/* ... */</span> }, 
-  <span class="hljs-comment">// error happened when connect to https server</span>
-  *onConnectError(requestDetail, error) { <span class="hljs-comment">/* ... */</span> } 
-};</code></pre><blockquote>
-<p>All functions in your rule file, except summary, are all driven by <a href="https://www.npmjs.com/package/co">co</a> . They should be yieldable, i.e. return a promise or be a generator function.</p>
-</blockquote>
-<h3 id="summary"><a class="header-link" href="#summary"></a>summary</h3>
-<h4 id="summary-1"><a class="header-link" href="#summary-1"></a>summary</h4>
-<ul class="list">
-<li>Introduction of this rule file. AnyProxy will read this field and give some tip to user.</li>
-</ul>
-<h3 id="beforesendrequest"><a class="header-link" href="#beforesendrequest"></a>beforeSendRequest</h3>
-<h4 id="beforesendrequest(requestdetail)"><a class="header-link" href="#beforesendrequest(requestdetail)"></a>beforeSendRequest(requestDetail)</h4>
-<ul class="list">
-<li>Before sending request to server, AnyProxy will call <code>beforeSendRequest</code> with param <code>requestDetail</code></li>
-<li><code>requestDetail</code> <ul class="list">
-<li><code>protocol</code> {string} the protocol to use, http or https</li>
-<li><code>requestOptions</code> {object} the options of the request-to-go, a param of require(&#39;http&#39;).request . ref: <a href="https://nodejs.org/api/http.html#http_http_request_options_callback">https://nodejs.org/api/http.html#http_http_request_options_callback</a></li>
-<li><code>requestData</code> {object} request body</li>
-<li><code>url</code> {string} request url</li>
-<li><code>_req</code> {object} the native node.js request object</li>
-</ul>
-</li>
-<li><p>e.g. When requesting  <em>anyproxy.io</em>, <code>requestDetail</code> is something like the following</p>
-<pre class="hljs"><code>{
-  <span class="hljs-attr">protocol</span>: <span class="hljs-string">'http'</span>,
-  <span class="hljs-attr">url</span>: <span class="hljs-string">'http://anyproxy.io/'</span>,
-  <span class="hljs-attr">requestOptions</span>: {
-    <span class="hljs-attr">hostname</span>: <span class="hljs-string">'anyproxy.io'</span>,
-    <span class="hljs-attr">port</span>: <span class="hljs-number">80</span>,
-    <span class="hljs-attr">path</span>: <span class="hljs-string">'/'</span>,
-    <span class="hljs-attr">method</span>: <span class="hljs-string">'GET'</span>,
-    <span class="hljs-attr">headers</span>: {
-      <span class="hljs-attr">Host</span>: <span class="hljs-string">'anyproxy.io'</span>,
-      <span class="hljs-string">'Proxy-Connection'</span>: <span class="hljs-string">'keep-alive'</span>,
-      <span class="hljs-string">'User-Agent'</span>: <span class="hljs-string">'...'</span>
-    }
-  },
-  <span class="hljs-attr">requestData</span>: <span class="hljs-string">'...'</span>,
-  <span class="hljs-attr">_req</span>: { <span class="hljs-comment">/* ... */</span>}
-}</code></pre></li>
-<li><p>Any of these return values are valid</p>
-<ul class="list">
-<li>do nothing, and return null</li>
-</ul>
-<pre class="hljs"><code><span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;</code></pre><ul class="list">
-<li>modify the request protocol,i.e. force use https</li>
-</ul>
-<pre class="hljs"><code><span class="hljs-keyword">return</span> {
-  <span class="hljs-attr">protocol</span>: <span class="hljs-string">'https'</span>
-};</code></pre><ul class="list">
-<li>modify request param</li>
-</ul>
-<pre class="hljs"><code><span class="hljs-keyword">var</span> newOption = <span class="hljs-built_in">Object</span>.assign({}, requestDetail.requestOptions);
-newOption.path = <span class="hljs-string">'/redirect/to/another/path'</span>;
-<span class="hljs-keyword">return</span> {
-  <span class="hljs-attr">requestOptions</span>: newOption
-};</code></pre><ul class="list">
-<li>modify request body</li>
-</ul>
-<pre class="hljs"><code><span class="hljs-keyword">return</span> {
-  <span class="hljs-attr">requestData</span>: <span class="hljs-string">'my new request data'</span>
-  <span class="hljs-comment">// requestOptions can also be used here</span>
-};</code></pre><ul class="list">
-<li>give response to the client, not sending request any longer. <code>statusCode</code> <code>headers</code>are required is this situation.</li>
-</ul>
-<pre class="hljs"><code><span class="hljs-keyword">return</span> {
-  <span class="hljs-attr">response</span>: {
-    <span class="hljs-attr">statusCode</span>: <span class="hljs-number">200</span>,
-    <span class="hljs-attr">header</span>: { <span class="hljs-string">'content-type'</span>: <span class="hljs-string">'text/html'</span> },
-    <span class="hljs-attr">body</span>: <span class="hljs-string">'this could be a &lt;string&gt; or &lt;buffer&gt;'</span>
-  }
-};</code></pre></li>
-</ul>
-<h3 id="beforesendresponse"><a class="header-link" href="#beforesendresponse"></a>beforeSendResponse</h3>
-<h4 id="beforesendresponse(requestdetail,-responsedetail)"><a class="header-link" href="#beforesendresponse(requestdetail,-responsedetail)"></a>beforeSendResponse(requestDetail, responseDetail)</h4>
-<ul class="list">
-<li>Before sending response to client, AnyProxy will call <code>beforeSendResponse</code> with param <code>requestDetail</code> <code>responseDetail</code></li>
-<li><code>requestDetail</code> is the same param as in <code>beforeSendRequest</code></li>
-<li><code>responseDetail</code> <ul class="list">
-<li><code>response</code> {object} the response from server, includes <code>statusCode</code> <code>header</code> <code>body</code></li>
-<li><code>_res</code> {object} the native node.js response object</li>
-</ul>
-</li>
-<li><p>e.g. When requesting <em>anyproxy.io</em>, <code>responseDetail</code> is something like the following</p>
-<pre class="hljs"><code>{ 
-  <span class="hljs-attr">response</span>: { 
-    <span class="hljs-attr">statusCode</span>: <span class="hljs-number">200</span>,
-    <span class="hljs-attr">header</span>: { 
-      <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'image/gif'</span>,
-      <span class="hljs-attr">Connection</span>: <span class="hljs-string">'close'</span>,
-      <span class="hljs-string">'Cache-Control'</span>: <span class="hljs-string">'...'</span>
-    },
-    <span class="hljs-attr">body</span>: <span class="hljs-string">'...'</span>
-  },
-  <span class="hljs-attr">_res</span>: { <span class="hljs-comment">/* ... */</span> }
-}</code></pre></li>
-<li><p>Any of these return values are valid</p>
-<ul class="list">
-<li>do nothing, and return null</li>
-</ul>
-<pre class="hljs"><code><span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;</code></pre><ul class="list">
-<li>modify the response status code</li>
-</ul>
-<pre class="hljs"><code><span class="hljs-keyword">var</span> newResponse = <span class="hljs-built_in">Object</span>.assign({}, responseDetail.reponse);
-newResponse.statusCode = <span class="hljs-number">404</span>;
-<span class="hljs-keyword">return</span> {
-  <span class="hljs-attr">response</span>: newResponse
-};</code></pre><ul class="list">
-<li>modify the response content</li>
-</ul>
-<pre class="hljs"><code><span class="hljs-keyword">var</span> newResponse = <span class="hljs-built_in">Object</span>.assign({}, responseDetail.reponse);
-newResponse.body += <span class="hljs-string">'--from anyproxy--'</span>;
-<span class="hljs-keyword">return</span> {
-  <span class="hljs-attr">response</span>: newResponse
-};</code></pre></li>
-</ul>
-<h3 id="beforedealhttpsrequest"><a class="header-link" href="#beforedealhttpsrequest"></a>beforeDealHttpsRequest</h3>
-<h4 id="beforedealhttpsrequest(requestdetail)"><a class="header-link" href="#beforedealhttpsrequest(requestdetail)"></a>beforeDealHttpsRequest(requestDetail)</h4>
-<ul class="list">
-<li>When receiving https request, AnyProxy will call <code>beforeDealHttpsRequest</code> with param <code>requestDetail</code></li>
-<li>If configed with <code>forceProxyHttps</code> in launching, AnyProxy will skip calling this method</li>
-<li>Only by returning true, AnyProxy will try to replace the certificate and intercept the https request.</li>
-<li><code>requestDetail</code><ul class="list">
-<li><code>host</code> {string} the target host to request. Due to the request protocol, full url couldn&#39;t be got here</li>
-<li><code>_req</code> {object} the native node.js request object. The <code>_req</code> here refers to the CONNECT request.</li>
-</ul>
-</li>
-<li>return value<ul class="list">
-<li><code>true</code> or <code>false</code>, whether AnyProxy should intercept the https request</li>
-</ul>
-</li>
-</ul>
-<h3 id="onerror"><a class="header-link" href="#onerror"></a>onError</h3>
-<h4 id="onerror(requestdetail,-error)"><a class="header-link" href="#onerror(requestdetail,-error)"></a>onError(requestDetail, error)</h4>
-<ul class="list">
-<li>AnyProxy will call this method when an error happened in request handling.</li>
-<li>Errors usually are issued during requesting, e.g. DNS failure, request timeout</li>
-<li><code>requestDetail</code> is the same one as in <code>beforeSendRequest</code></li>
-<li><p>Any of these return values are valid</p>
-<ul class="list">
-<li>do nothing, and AnyProxy will response a default error page</li>
-</ul>
-<pre class="hljs"><code><span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;</code></pre><ul class="list">
-<li>return a customized error page</li>
-</ul>
-<pre class="hljs"><code><span class="hljs-keyword">return</span> {
-  <span class="hljs-attr">response</span>: {
-    <span class="hljs-attr">statusCode</span>: <span class="hljs-number">200</span>,
-    <span class="hljs-attr">header</span>: { <span class="hljs-string">'content-type'</span>: <span class="hljs-string">'text/html'</span> },
-    <span class="hljs-attr">body</span>: <span class="hljs-string">'this could be a &lt;string&gt; or &lt;buffer&gt;'</span>
-  }
-};</code></pre></li>
-</ul>
-<h3 id="onconnecterror"><a class="header-link" href="#onconnecterror"></a>onConnectError</h3>
-<h4 id="onconnecterror(requestdetail,-error)"><a class="header-link" href="#onconnecterror(requestdetail,-error)"></a>onConnectError(requestDetail, error)</h4>
-<ul class="list">
-<li>AnyProxy will call this method when failed to connect target server in https request</li>
-<li><code>requestDetail</code> is the same one as in <code>beforeDealHttpsRequest</code></li>
-<li>no return value is required </li>
-</ul>
-<h3 id="faq"><a class="header-link" href="#faq"></a>FAQ</h3>
-<ul class="list">
-<li>Q: can not deal https request in rule module.</li>
-<li><p>A: Any of these options could be used to change the way AnyProxy deall https requests </p>
-<ol class="list">
-<li>config <code>--intercept</code> when luanching AnyProxy via cli, or use <code>forceProxyHttps</code> when using as an npm module</li>
-<li>place a <code>beforeDealHttpsRequest</code> function in your rule file and determine which request to intercept by your own.</li>
-</ol>
-</li>
-<li><p>Q: get an error says <em>function is not yieldable</em></p>
-</li>
-<li>A: Rule module is driven by <a href="https://www.npmjs.com/package/co">co</a>. The functions inside should  be yieldable, i.e. return a promise or be a generator function.</li>
-</ul>
-<h2 id="rule-samples"><a class="header-link" href="#rule-samples"></a>Rule Samples</h2>
-<ul class="list">
-<li>here are some samples about frequently used rule file</li>
-<li>try these samples by <code>anyproxy --rule http://....js</code></li>
-<li>how to test with curl:<ul class="list">
-<li>request the server directly <code>curl http://httpbin.org/</code></li>
-<li>request the server via proxy <code>curl http://httpbin.org/ --proxy http://127.0.0.1:8001</code></li>
-</ul>
-</li>
-</ul>
-<h3 id="use-local-response"><a class="header-link" href="#use-local-response"></a>use local response</h3>
-<ul class="list">
-<li>intercept the request towards <a href="http://httpbin.org">http://httpbin.org</a> , return the local-defined response</li>
-</ul>
-<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_use_local_response.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
-  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
-*/</span>
-<span class="hljs-built_in">module</span>.exports = {
-  *beforeSendRequest(requestDetail) {
-    <span class="hljs-keyword">const</span> localResponse = {
-      <span class="hljs-attr">statusCode</span>: <span class="hljs-number">200</span>,
-      <span class="hljs-attr">header</span>: { <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'application/json'</span> },
-      <span class="hljs-attr">body</span>: <span class="hljs-string">'{"hello": "this is local response"}'</span>
-    };
-    <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org'</span>) === <span class="hljs-number">0</span>) {
-      <span class="hljs-keyword">return</span> {
-        <span class="hljs-attr">response</span>: localResponse
-      };
-    }
-  },
-};</code></pre><h3 id="modify-request-header"><a class="header-link" href="#modify-request-header"></a>modify request header</h3>
-<ul class="list">
-<li>modify the user-agent sent to httpbin.org</li>
-</ul>
-<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_request_header.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
-  sample: 
-    modify the user-agent in requests toward httpbin.org
-  test:
-    curl http://httpbin.org/user-agent --proxy http://127.0.0.1:8001
-*/</span>
-<span class="hljs-built_in">module</span>.exports = {
-  *beforeSendRequest(requestDetail) {
-    <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org'</span>) === <span class="hljs-number">0</span>) {
-      <span class="hljs-keyword">const</span> newRequestOptions = requestDetail.requestOptions;
-      newRequestOptions.headers[<span class="hljs-string">'User-Agent'</span>] = <span class="hljs-string">'AnyProxy/0.0.0'</span>;
-      <span class="hljs-keyword">return</span> {
-        <span class="hljs-attr">requestOptions</span>: newRequestOptions
-      };
-    }
-  },
-};</code></pre><h3 id="modify-request-body"><a class="header-link" href="#modify-request-body"></a>modify request body</h3>
-<ul class="list">
-<li>modify the post body of <a href="http://httpbin.org/post">http://httpbin.org/post</a></li>
-</ul>
-<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_request_data.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
-  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" }
-*/</span>
-<span class="hljs-built_in">module</span>.exports = {
-  *beforeSendRequest(requestDetail) {
-    <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org/post'</span>) === <span class="hljs-number">0</span>) {
-      <span class="hljs-keyword">return</span> {
-        <span class="hljs-attr">requestData</span>: <span class="hljs-string">'i-am-anyproxy-modified-post-data'</span>
-      };
-    }
-  },
-};</code></pre><h3 id="modify-the-request-target"><a class="header-link" href="#modify-the-request-target"></a>modify the request target</h3>
-<ul class="list">
-<li>send all the request towards <a href="http://httpbin.org/">http://httpbin.org/</a> to <a href="http://httpbin.org/user-agent">http://httpbin.org/user-agent</a></li>
-</ul>
-<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_request_path.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
-  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" }
-*/</span>
-<span class="hljs-built_in">module</span>.exports = {
-  *beforeSendRequest(requestDetail) {
-    <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org'</span>) === <span class="hljs-number">0</span>) {
-      <span class="hljs-keyword">const</span> newRequestOptions = requestDetail.requestOptions;
-      newRequestOptions.path = <span class="hljs-string">'/user-agent'</span>;
-      newRequestOptions.method = <span class="hljs-string">'GET'</span>;
-      <span class="hljs-keyword">return</span> {
-        <span class="hljs-attr">requestOptions</span>: newRequestOptions
-      };
-    }
-  },
-};</code></pre><h3 id="modify-request-protocol"><a class="header-link" href="#modify-request-protocol"></a>modify request protocol</h3>
-<ul class="list">
-<li>modify the http request towards <a href="http://httpbin.org">http://httpbin.org</a> to https</li>
-</ul>
-<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_request_protocol.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
-  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" }
-*/</span>
-<span class="hljs-built_in">module</span>.exports = {
-  *beforeSendRequest(requestDetail) {
-    <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org'</span>) === <span class="hljs-number">0</span>) {
-      <span class="hljs-keyword">const</span> newOption = requestDetail.requestOptions;
-      newOption.port = <span class="hljs-number">443</span>;
-      <span class="hljs-keyword">return</span> {
-        <span class="hljs-attr">protocol</span>: <span class="hljs-string">'https'</span>,
-        <span class="hljs-attr">requestOptions</span>: newOption
-      };
-    }
-  }
-};</code></pre><h3 id="modify-response-status-code"><a class="header-link" href="#modify-response-status-code"></a>modify response status code</h3>
-<ul class="list">
-<li>modify all status code from <a href="http://httpbin.org">http://httpbin.org</a> to 404</li>
-</ul>
-<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_response_statuscode.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
-  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
-*/</span>
-<span class="hljs-built_in">module</span>.exports = {
-  *beforeSendResponse(requestDetail, responseDetail) {
-    <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org'</span>) === <span class="hljs-number">0</span>) {
-      <span class="hljs-keyword">const</span> newResponse = responseDetail.response;
-      newResponse.statusCode = <span class="hljs-number">404</span>;
-      <span class="hljs-keyword">return</span> {
-        <span class="hljs-attr">response</span>: newResponse
-      };
-    }
-  }
-};</code></pre><h3 id="modify-the-response-header"><a class="header-link" href="#modify-the-response-header"></a>modify the response header</h3>
-<ul class="list">
-<li>add X-Proxy-By:AnyProxy to the response header from <a href="http://httpbin.org/user-agent">http://httpbin.org/user-agent</a></li>
-</ul>
-<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_response_header.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
-  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
-*/</span>
-<span class="hljs-built_in">module</span>.exports = {
-  *beforeSendResponse(requestDetail, responseDetail) {
-    <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org/user-agent'</span>) === <span class="hljs-number">0</span>) {
-      <span class="hljs-keyword">const</span> newResponse = responseDetail.response;
-      newResponse.header[<span class="hljs-string">'X-Proxy-By'</span>] = <span class="hljs-string">'AnyProxy'</span>;
-      <span class="hljs-keyword">return</span> {
-        <span class="hljs-attr">response</span>: newResponse
-      };
-    }
-  }
-};</code></pre><h3 id="modify-response-data-and-delay"><a class="header-link" href="#modify-response-data-and-delay"></a>modify response data and delay</h3>
-<ul class="list">
-<li>append some info to the response of <a href="http://httpbin.org/user-agent">http://httpbin.org/user-agent</a>, then delay the response for 5 seconds.</li>
-</ul>
-<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_response_data.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
-  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! --
-*/</span>
-
-<span class="hljs-built_in">module</span>.exports = {
-  *beforeSendResponse(requestDetail, responseDetail) {
-    <span class="hljs-keyword">if</span> (requestDetail.url === <span class="hljs-string">'http://httpbin.org/user-agent'</span>) {
-      <span class="hljs-keyword">const</span> newResponse = responseDetail.response;
-      newResponse.body += <span class="hljs-string">'-- AnyProxy Hacked! --'</span>;
-      <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =&gt;</span> {
-        setTimeout(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> { <span class="hljs-comment">// delay the response for 5s</span>
-          resolve({ <span class="hljs-attr">response</span>: newResponse });
-        }, <span class="hljs-number">5000</span>);
-      });
-    }
-  },
-};</code></pre><h2 id="use-anyproxy-as-an-npm-module"><a class="header-link" href="#use-anyproxy-as-an-npm-module"></a>Use AnyProxy as an npm module</h2>
-<p>AnyProxy can be used as an npm module</p>
-<blockquote>
-<p>To enable https feature, please guide users to use <code>anyproxy-ca</code> in cli. Or use methods under <code>AnyProxy.utils.certMgr</code> to generate certificates.</p>
-</blockquote>
-<ul class="list">
-<li>install</li>
-</ul>
-<pre class="hljs"><code>npm i anyproxy@beta --save <span class="hljs-comment"># 4.0 is in beta now</span></code></pre><ul class="list">
-<li>sample</li>
-</ul>
-<pre class="hljs"><code><span class="hljs-keyword">const</span> AnyProxy = <span class="hljs-built_in">require</span>(<span class="hljs-string">'anyproxy'</span>);
-<span class="hljs-keyword">const</span> options = {
-  <span class="hljs-attr">port</span>: <span class="hljs-number">8001</span>,
-  <span class="hljs-attr">rule</span>: <span class="hljs-built_in">require</span>(<span class="hljs-string">'myRuleModule'</span>),
-  <span class="hljs-attr">webInterface</span>: {
-    <span class="hljs-attr">enable</span>: <span class="hljs-literal">true</span>,
-    <span class="hljs-attr">webPort</span>: <span class="hljs-number">8002</span>,
-    <span class="hljs-attr">wsPort</span>: <span class="hljs-number">8003</span>,
-  },
-  <span class="hljs-attr">throttle</span>: <span class="hljs-number">10000</span>,
-  <span class="hljs-attr">forceProxyHttps</span>: <span class="hljs-literal">false</span>,
-  <span class="hljs-attr">silent</span>: <span class="hljs-literal">false</span>
-};
-<span class="hljs-keyword">const</span> proxyServer = <span class="hljs-keyword">new</span> AnyProxy.ProxyServer(options);
-
-proxyServer.on(<span class="hljs-string">'ready'</span>, () =&gt; { <span class="hljs-comment">/* */</span> });
-proxyServer.on(<span class="hljs-string">'error'</span>, (e) =&gt; { <span class="hljs-comment">/* */</span> });
-proxyServer.start();
-
-<span class="hljs-comment">//when finished</span>
-proxyServer.close();</code></pre><ul class="list">
-<li><p>Class: AnyProxy.proxyServer</p>
-<ul class="list">
-<li><p>create a proxy server</p>
-<pre class="hljs"><code><span class="hljs-keyword">const</span> proxy = <span class="hljs-keyword">new</span> AnyProxy.proxyServer(options)</code></pre></li>
-<li><p><code>options</code></p>
-<ul class="list">
-<li><code>port</code> {number} required, port number of proxy server</li>
-<li><code>rule</code> {object} your rule module</li>
-<li><code>throttle</code> {number} throttle in kb/s, unlimited for default</li>
-<li><code>forceProxyHttps</code> {boolean} in force intercept all https request, false for default</li>
-<li><code>silent</code> {boolean} if keep silent in console, false for default<code>false</code></li>
-<li><code>dangerouslyIgnoreUnauthorized</code> {boolean} if ignore certificate error in request, false for default</li>
-<li><code>webInterface</code> {object} config for web interface<ul class="list">
-<li><code>enable</code> {boolean} if enable web interface, false for default</li>
-<li><code>webPort</code> {number} port number for web interface</li>
-</ul>
-</li>
-</ul>
-</li>
-<li><p>Event: <code>ready</code></p>
-<ul class="list">
-<li>emit when proxy server is ready</li>
-<li>sample</li>
-</ul>
-<pre class="hljs"><code>proxy.on(<span class="hljs-string">'ready'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{ })</code></pre></li>
-<li><p>Event: <code>error</code></p>
-<ul class="list">
-<li>emit when error happened inside proxy server</li>
-<li>sample</li>
-</ul>
-<pre class="hljs"><code>proxy.on(<span class="hljs-string">'error'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{ })</code></pre></li>
-<li><p>Method: <code>start</code></p>
-<ul class="list">
-<li>start proxy server</li>
-<li>sample</li>
-</ul>
-<pre class="hljs"><code>proxy.start();</code></pre></li>
-<li><p>Method: <code>close</code></p>
-<ul class="list">
-<li>close proxy server</li>
-<li>sample</li>
-</ul>
-<pre class="hljs"><code>proxy.close();</code></pre></li>
-</ul>
-</li>
-<li><p>AnyProxy.utils.systemProxyMgr</p>
-<ul class="list">
-<li>manage the system proxy config. sudo password may be required</li>
-<li>sample</li>
-</ul>
-<pre class="hljs"><code><span class="hljs-comment">// set 127.0.0.1:8001 as system http server</span>
-AnyProxy.utils.systemProxyMgr.enableGlobalProxy(<span class="hljs-string">'127.0.0.1'</span>, <span class="hljs-string">'8001'</span>);    
-
-<span class="hljs-comment">// disable global proxy server</span>
-AnyProxy.utils.systemProxyMgr.disableGlobalProxy();</code></pre></li>
-<li><p>AnyProxy.utils.certMgr</p>
-<ul class="list">
-<li>Manage certificates of AnyProxy</li>
-<li><code>AnyProxy.utils.certMgr.ifRootCAFileExists()</code><ul class="list">
-<li>detect if AnyProx rootCA exists</li>
-</ul>
-</li>
-<li><code>AnyProxy.utils.certMgr.generateRootCA(callback)</code><ul class="list">
-<li>generate a rootCA</li>
-</ul>
-</li>
-<li>Sample</li>
-</ul>
-<pre class="hljs"><code>  <span class="hljs-keyword">const</span> AnyProxy = <span class="hljs-built_in">require</span>(<span class="hljs-string">'AnyProxy'</span>);
-  <span class="hljs-keyword">const</span> exec = <span class="hljs-built_in">require</span>(<span class="hljs-string">'child_process'</span>).exec;
-
-  <span class="hljs-keyword">if</span> (!AnyProxy.utils.certMgr.ifRootCAFileExists()) {
-    AnyProxy.utils.certMgr.generateRootCA(<span class="hljs-function">(<span class="hljs-params">error, keyPath</span>) =&gt;</span> {
-      <span class="hljs-comment">// let users to trust this CA before using proxy</span>
-      <span class="hljs-keyword">if</span> (!error) {
-        <span class="hljs-keyword">const</span> certDir = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>).dirname(keyPath);
-        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'The cert is generated at'</span>, certDir);
-        <span class="hljs-keyword">const</span> isWin = <span class="hljs-regexp">/^win/</span>.test(process.platform);
-        <span class="hljs-keyword">if</span> (isWin) {
-          exec(<span class="hljs-string">'start .'</span>, { <span class="hljs-attr">cwd</span>: certDir });
-        } <span class="hljs-keyword">else</span> {
-          exec(<span class="hljs-string">'open .'</span>, { <span class="hljs-attr">cwd</span>: certDir });
-        }
-      } <span class="hljs-keyword">else</span> {
-        <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'error when generating rootCA'</span>, error);
-      }
-    });
-  }</code></pre></li>
-</ul>
-<h2 id="about-anyproxy"><a class="header-link" href="#about-anyproxy"></a>About AnyProxy</h2>
-<ul class="list">
-<li>Change Log: <a href="https://github.com/alibaba/anyproxy/blob/master/CHANGELOG">https://github.com/alibaba/anyproxy/blob/master/CHANGELOG</a></li>
-<li>Github:<a href="https://github.com/alibaba/anyproxy">https://github.com/alibaba/anyproxy</a></li>
-<li>issue:<a href="https://github.com/alibaba/anyproxy/issues">https://github.com/alibaba/anyproxy/issues</a></li>
-</ul>
-<h2 id="appendix"><a class="header-link" href="#appendix"></a>Appendix</h2>
-<h3 id="config-root-ca-in-osx"><a class="header-link" href="#config-root-ca-in-osx"></a>Config root CA in OSX</h3>
-<ul class="list">
-<li>this kind of errors is usually caused by untrusted root CA</li>
-</ul>
-<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/CBkLGYgvoHAYwNVAYkpk.png" width="450" /></p>
-<blockquote>
-<p>Warning: please keep your root CA safe since it may influence your system security.</p>
-</blockquote>
-<p>install :</p>
-<ul class="list">
-<li><p>double click <em>rootCA.crt</em></p>
-</li>
-<li><p>add cert into login or system</p>
-</li>
-</ul>
-<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/bCwNUFFpvsmVuljQKrIk.png" width="350" /></p>
-<ul class="list">
-<li>find the newly imported AnyProxy certificates, configured as <strong>Always Trust</strong></li>
-</ul>
-<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/HOmEElNGdoZEWFMLsTNT.png" width="700" /></p>
-<h3 id="trust-root-ca-in-windows"><a class="header-link" href="#trust-root-ca-in-windows"></a>trust root CA in windows</h3>
-<p class="img-container"><img src="https://t.alipayobjects.com/tfscom/T1D3hfXeFtXXXXXXXX.jpg" width="700" /></p>
-<h3 id="config-osx-system-proxy"><a class="header-link" href="#config-osx-system-proxy"></a>config OSX system proxy</h3>
-<ul class="list">
-<li>the config is in wifi - advanced</li>
-</ul>
-<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/vduwhobSTypTfgniBvoa.png" width="500" /></p>
-<h3 id="config-http-proxy-server"><a class="header-link" href="#config-http-proxy-server"></a>config http proxy server</h3>
-<ul class="list">
-<li>take Chrome extent [SwitchyOmega] as an example(<a href="https://chrome.google.com/webstore/detail/padekgcemlokbadohgkifijomclgjgif)为例">https://chrome.google.com/webstore/detail/padekgcemlokbadohgkifijomclgjgif)为例</a></li>
-</ul>
-<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/jIPZrKmqXRaSledQeJUJ.png" width="500" /></p>
-<h3 id="trust-root-ca-in-ios"><a class="header-link" href="#trust-root-ca-in-ios"></a>trust root CA in iOS</h3>
-<ul class="list">
-<li>Click <em>Root CA</em> in web ui, and follow the instruction to install</li>
-</ul>
-<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/BrugmMelGVysLDOIBblj.png" width="260" /></p>
-<h3 id="trust-root-ca-in-ios->=-10.3"><a class="header-link" href="#trust-root-ca-in-ios->=-10.3"></a>trust root CA in iOS &gt;= 10.3</h3>
-<ul class="list">
-<li>Besides installing root CA, you have to &quot;turn on&quot; the certificate for web manually in <em>settings - general - about - Certificate Trust Settings</em>. Otherwire, safari will not trust the root CA generated by AnyProxy.</li>
-</ul>
-<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/hVWkXHrzHmOKOtCKGUWx.png" width="500" /></p>
-<h3 id="config-ios/android-proxy-server"><a class="header-link" href="#config-ios/android-proxy-server"></a>config iOS/Android proxy server</h3>
-<ul class="list">
-<li><p>proxy settings are placed in wifi setting</p>
-</li>
-<li><p>iOS</p>
-</li>
-</ul>
-<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/tLGqIozhffTccUgPakuw.png" width="260" /></p>
-<ul class="list">
-<li>Android</li>
-</ul>
-<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/YQtbQYVNuOszZGdAOauU.png" width="260" /></p>
-    </div>
-  </article>
-
-  <script src="//cdn.bootcss.com/zepto/1.2.0/zepto.min.js"></script>
-  <script>
-  window.onload = function(){
-    var itemList = [];
-    var targetMap = {};
-    $("[id]", ".main-content").map(function (index, heading) {
-      targetMap[heading.getAttribute('id')] = heading;
-    });
-
-    $("#j_toc li").map(function (index, item) {
-      if (item.className.indexOf('sidebar-header-2') >= 0 || item.className.indexOf('sidebar-header-3') >= 0) {
-        var targetName = item.firstChild.getAttribute('href').replace('#', '');
-        var targetItem = targetMap[targetName];
-        itemList.push({ target: targetItem, tocItem: item, top: $(targetItem).position().top });
-      }
-    });
-
-    var updateTocActive = function (e) {
-      var windowHeight = window.innerHeight;
-      //find the first item to match
-      var scrollYThres = window.scrollY + 200;
-      var target;
-      if (scrollYThres < 100) {
-        target = itemList[0].tocItem;
-      } else {
-        itemList.forEach(function (item, index) {
-          if (target) return;
-          if (index > 0) {
-            if (item.top >= scrollYThres) {
-              target = itemList[index - 1].tocItem;
-            }
-          }
-        });
-      }
-
-      $('.toc-active').removeClass('toc-active');
-      $(target).addClass('toc-active');
-    };
-
-    window.onscroll = updateTocActive;
-    updateTocActive();
-  }
-  </script>
+ 
 </body>
 
 </html>
\ No newline at end of file
diff --git a/4.x/index.html b/4.x/index.html
index 3ee6ab7..5968c39 100644
--- a/4.x/index.html
+++ b/4.x/index.html
@@ -15,7 +15,7 @@
   <script>
     //redirect to Chinese version if in China
     if (new Date().getTimezoneOffset() == "-480" && !(/(cn|en)/i.test(location.href))) {
-      location.href = "./cn.html";
+      location.href = "/";
     } else {
       var _hmt = _hmt || []; (function () { var hm = document.createElement("script"); hm.src = "//hm.baidu.com/hm.js?4e51565b7d471fd6623c163a8fd79e07"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })();
     }
@@ -23,810 +23,7 @@
 </head>
 
 <body>
-  <a href="https://github.com/alibaba/anyproxy/tree/4.x" target="_blank">
-    <img style="position: fixed; top: 0; right: 0; border: 0;z-index: 1;" src="https://camo.githubusercontent.com/a6677b08c955af8400f44c6298f40e7d19cc5b2d/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f677261795f3664366436642e706e67"
-      alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_gray_6d6d6d.png">
-  </a>
 
-  <article class="markdown-body">
-    <div class="toc-container" id="j_toc">
-      <div class="toc-content"><ul class="nav nav-list">
-    <li class="sidebar-header-1"><a href="#anyproxy">AnyProxy</a></li>
-    <li class="sidebar-header-2"><a href="#quick-start">Quick start</a></li>
-    <li class="sidebar-header-3"><a href="#install">install</a></li>
-    <li class="sidebar-header-3"><a href="#launch">launch</a></li>
-    <li class="sidebar-header-3"><a href="#other-commands">other commands</a></li>
-    <li class="sidebar-header-2"><a href="#proxy-https-request">Proxy https request</a></li>
-    <li class="sidebar-header-2"><a href="#use-rule-module">Use rule module</a></li>
-    <li class="sidebar-header-3"><a href="#sample">sample</a></li>
-    <li class="sidebar-header-3"><a href="#the-entire-process">the entire process</a></li>
-    <li class="sidebar-header-3"><a href="#how-to-load-rule-module">how to load rule module</a></li>
-    <li class="sidebar-header-2"><a href="#rule-module-interface">Rule module interface</a></li>
-    <li class="sidebar-header-3"><a href="#summary">summary</a></li>
-    <li class="sidebar-header-4"><a href="#summary-1">summary</a></li>
-    <li class="sidebar-header-3"><a href="#beforesendrequest">beforeSendRequest</a></li>
-    <li class="sidebar-header-4"><a href="#beforesendrequest(requestdetail)">beforeSendRequest(requestDetail)</a></li>
-    <li class="sidebar-header-3"><a href="#beforesendresponse">beforeSendResponse</a></li>
-    <li class="sidebar-header-4"><a href="#beforesendresponse(requestdetail,-responsedetail)">beforeSendResponse(requestDetail, responseDetail)</a></li>
-    <li class="sidebar-header-3"><a href="#beforedealhttpsrequest">beforeDealHttpsRequest</a></li>
-    <li class="sidebar-header-4"><a href="#beforedealhttpsrequest(requestdetail)">beforeDealHttpsRequest(requestDetail)</a></li>
-    <li class="sidebar-header-3"><a href="#onerror">onError</a></li>
-    <li class="sidebar-header-4"><a href="#onerror(requestdetail,-error)">onError(requestDetail, error)</a></li>
-    <li class="sidebar-header-3"><a href="#onconnecterror">onConnectError</a></li>
-    <li class="sidebar-header-4"><a href="#onconnecterror(requestdetail,-error)">onConnectError(requestDetail, error)</a></li>
-    <li class="sidebar-header-3"><a href="#faq">FAQ</a></li>
-    <li class="sidebar-header-2"><a href="#rule-samples">Rule Samples</a></li>
-    <li class="sidebar-header-3"><a href="#use-local-response">use local response</a></li>
-    <li class="sidebar-header-3"><a href="#modify-request-header">modify request header</a></li>
-    <li class="sidebar-header-3"><a href="#modify-request-body">modify request body</a></li>
-    <li class="sidebar-header-3"><a href="#modify-the-request-target">modify the request target</a></li>
-    <li class="sidebar-header-3"><a href="#modify-request-protocol">modify request protocol</a></li>
-    <li class="sidebar-header-3"><a href="#modify-response-status-code">modify response status code</a></li>
-    <li class="sidebar-header-3"><a href="#modify-the-response-header">modify the response header</a></li>
-    <li class="sidebar-header-3"><a href="#modify-response-data-and-delay">modify response data and delay</a></li>
-    <li class="sidebar-header-2"><a href="#use-anyproxy-as-an-npm-module">Use AnyProxy as an npm module</a></li>
-    <li class="sidebar-header-2"><a href="#about-anyproxy">About AnyProxy</a></li>
-    <li class="sidebar-header-2"><a href="#appendix">Appendix</a></li>
-    <li class="sidebar-header-3"><a href="#config-root-ca-in-osx">Config root CA in OSX</a></li>
-    <li class="sidebar-header-3"><a href="#trust-root-ca-in-windows">trust root CA in windows</a></li>
-    <li class="sidebar-header-3"><a href="#config-osx-system-proxy">config OSX system proxy</a></li>
-    <li class="sidebar-header-3"><a href="#config-http-proxy-server">config http proxy server</a></li>
-    <li class="sidebar-header-3"><a href="#trust-root-ca-in-ios">trust root CA in iOS</a></li>
-    <li class="sidebar-header-3"><a href="#trust-root-ca-in-ios-&gt;&#x3D;-10.3">trust root CA in iOS &gt;&#x3D; 10.3</a></li>
-    <li class="sidebar-header-3"><a href="#config-ios/android-proxy-server">config iOS/Android proxy server</a></li>
-</ul>
-      </div>
-    </div>
-    <div class="main-content"><h1 id="anyproxy"><a class="header-link" href="#anyproxy"></a>AnyProxy</h1>
-<p>AnyProxy is a fully configurable http/https proxy in NodeJS. Version 4.0 is in beta now.</p>
-<p>Ref: <a href="./cn.html">Chinese Doc 中文文档</a></p>
-<p>Github: </p>
-<ul class="list">
-<li><a href="https://github.com/alibaba/anyproxy/tree/4.x">https://github.com/alibaba/anyproxy/tree/4.x</a></li>
-</ul>
-<p>Features:</p>
-<ul class="list">
-<li>Offer you the ablity to handle http traffic by invoking a js module</li>
-<li>Intercept https</li>
-<li>GUI webinterface</li>
-</ul>
-<p>Change Logs since 3.x:</p>
-<ul class="list">
-<li>Support Promise and Generator in rule module</li>
-<li>Simplified interface in rule module</li>
-<li>A newly designed web interface</li>
-</ul>
-<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/SqVntpzmscXPbSzfcGcr.png" width="500" /></p>
-<h2 id="quick-start"><a class="header-link" href="#quick-start"></a>Quick start</h2>
-<h3 id="install"><a class="header-link" href="#install"></a>install</h3>
-<pre class="hljs"><code>npm install -g anyproxy@beta <span class="hljs-comment"># 4.x is in beta now</span></code></pre><h3 id="launch"><a class="header-link" href="#launch"></a>launch</h3>
-<ul class="list">
-<li>start AnyProxy in command line, with default port 8001</li>
-</ul>
-<pre class="hljs"><code>anyproxy</code></pre><ul class="list">
-<li>now you can use http proxy server by 127.0.0.1:8001</li>
-<li>visit <a href="http://127.0.0.1:8002">http://127.0.0.1:8002</a> to see the http requests</li>
-</ul>
-<h3 id="other-commands"><a class="header-link" href="#other-commands"></a>other commands</h3>
-<ul class="list">
-<li>specify the port of http proxy</li>
-</ul>
-<pre class="hljs"><code>anyproxy --port 1080</code></pre><h2 id="proxy-https-request"><a class="header-link" href="#proxy-https-request"></a>Proxy https request</h2>
-<ul class="list">
-<li>AnyProxy does NOT intercept https requests by default. To view decrypted info, you have to config the CA certificate.</li>
-</ul>
-<blockquote>
-<p>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.</p>
-</blockquote>
-<ul class="list">
-<li>generate certifycates and intercept</li>
-</ul>
-<pre class="hljs"><code>anyproxy-ca <span class="hljs-comment">#generate root CA. manually trust it after that.</span>
-anyproxy --intercept <span class="hljs-comment">#launch anyproxy and intercept all https traffic</span></code></pre><ul class="list">
-<li><a href="#osx系统信任ca证书">Appendix:how to trust CA</a></li>
-</ul>
-<h2 id="use-rule-module"><a class="header-link" href="#use-rule-module"></a>Use rule module</h2>
-<p>AnyProxy provides the ability to load your own rules written in javascript. With rule module, you could customize the logic to handle requests.</p>
-<blockquote>
-<p>Make sure your rule file is got from a trusted source. Otherwise, you may face some unknown security risk.</p>
-</blockquote>
-<p>Rule module could do the following stuff:</p>
-<ul class="list">
-<li>intercept and modify the request which is being sent<ul class="list">
-<li>editable fields include request header, body, target address</li>
-</ul>
-</li>
-<li>intercept and modify the response from server<ul class="list">
-<li>editable fields include response status code, header, body</li>
-</ul>
-</li>
-<li>intercept https requests, modify request and response</li>
-</ul>
-<h3 id="sample"><a class="header-link" href="#sample"></a>sample</h3>
-<ul class="list">
-<li><p>Target</p>
-<ul class="list">
-<li>write a rule module to append some text to the response of GET <a href="http://httpbin.org/user-agent">http://httpbin.org/user-agent</a>, and delay the response for 5 seconds</li>
-</ul>
-</li>
-<li><p>Step 1,Write the rule file, save as sample.js</p>
-<pre class="hljs"><code><span class="hljs-comment">// file: sample.js</span>
-<span class="hljs-built_in">module</span>.exports = {
-  <span class="hljs-attr">summary</span>: <span class="hljs-string">'a rule to modify response'</span>,
-  *beforeSendResponse(requestDetail, responseDetail) {
-    <span class="hljs-keyword">if</span> (requestDetail.url === <span class="hljs-string">'http://httpbin.org/user-agent'</span>) {
-      <span class="hljs-keyword">const</span> newResponse = responseDetail.response;
-      newResponse.body += <span class="hljs-string">'-- AnyProxy Hacked! --'</span>;
-      <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =&gt;</span> {
-        setTimeout(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> { <span class="hljs-comment">// delay</span>
-          resolve({ <span class="hljs-attr">response</span>: newResponse });
-        }, <span class="hljs-number">5000</span>);
-      });
-    }
-  },
-};</code></pre></li>
-<li><p>Step 2, start AnyProxy and load the rule file</p>
-<ul class="list">
-<li>run <code>anyproxy --rule sample.js</code></li>
-</ul>
-</li>
-<li><p>Step 3, test</p>
-<ul class="list">
-<li><p>use curl </p>
-<pre class="hljs"><code>curl http://httpbin.org/user-agent --proxy http://127.0.0.1:8001</code></pre></li>
-<li><p>use browser. Point the http proxy of browser to 127.0.0.1:8001, then visit <a href="http://httpbin.org/user-agent">http://httpbin.org/user-agent</a> </p>
-</li>
-<li><p>the expected response from proxy is </p>
-</li>
-</ul>
-<pre class="hljs"><code>{
-  <span class="hljs-string">"user-agent"</span>: <span class="hljs-string">"curl/7.43.0"</span>
-}
-- AnyProxy Hacked!</code></pre></li>
-<li><p>Step 4, view the request log</p>
-<ul class="list">
-<li>visit <a href="http://127.0.0.1:8002">http://127.0.0.1:8002</a>, the request just sent should be listed here</li>
-</ul>
-</li>
-</ul>
-<h3 id="the-entire-process"><a class="header-link" href="#the-entire-process"></a>the entire process</h3>
-<ul class="list">
-<li>The flow chart is as follows</li>
-</ul>
-<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/TWyNuSJtEZBdrdcOMRjE.png" width="550" /></p>
-<ul class="list">
-<li><p>When got an http request, the entire process of proxy server is</p>
-<ul class="list">
-<li>AnyProxy collects all the quest info, include method, header, body</li>
-<li>AnyProxy calls <code>beforeSendRequest</code> of the rule module. Rule module deal the request, return new request param or response content</li>
-<li>If <code>beforeSendRequest</code> returns the response content, AnyProxy will send the response to client without sending to target server. The process ends here.</li>
-<li>Send request to target server, collect response</li>
-<li>Call <code>beforeSendResponse</code> of the rule module. Rule module deal the response data</li>
-<li>Send response to client</li>
-</ul>
-</li>
-<li><p>When AnyProxy get https request, it could replace the certificate and decrypt the request data</p>
-<ul class="list">
-<li>AnyProxy calls <code>beforeDealHttpsRequest</code> of the rule module</li>
-<li>If the function returns <code>true</code>, AnyProxy will do the man-in-the-middle attack to it. Otherwise, the request will not be dealed.</li>
-</ul>
-</li>
-</ul>
-<h3 id="how-to-load-rule-module"><a class="header-link" href="#how-to-load-rule-module"></a>how to load rule module</h3>
-<ul class="list">
-<li><p>use local file</p>
-<pre class="hljs"><code>anyproxy --rule ./rule.js</code></pre></li>
-<li><p>use an online rule file</p>
-<pre class="hljs"><code>anyproxy --rule https://sample.com/rule.js</code></pre></li>
-<li><p>use an npm module</p>
-<ul class="list">
-<li>AnyProxy uses <code>require()</code> to load rule module. You could either load a local npm module or a global-installed one.</li>
-</ul>
-<pre class="hljs"><code>anyproxy --rule ./myRulePkg/ <span class="hljs-comment">#local module</span>
-npm i -g myRulePkg &amp;&amp; anyproxy --rule myRulePkg <span class="hljs-comment">#global-installed module</span></code></pre></li>
-</ul>
-<h2 id="rule-module-interface"><a class="header-link" href="#rule-module-interface"></a>Rule module interface</h2>
-<p>A typical rule module is as follows. All the functions are optional, just write the part you are interested in.</p>
-<pre class="hljs"><code><span class="hljs-built_in">module</span>.exports = {
-  <span class="hljs-comment">// introduction</span>
-  summary: <span class="hljs-string">'my customized rule for AnyProxy'</span>, 
-  <span class="hljs-comment">// intercept before send request to server</span>
-  *beforeSendRequest(requestDetail) { <span class="hljs-comment">/* ... */</span> }, 
-  <span class="hljs-comment">// deal response before send to client </span>
-  *beforeSendResponse(requestDetail, responseDetail) { <span class="hljs-comment">/* ... */</span> }, 
-  <span class="hljs-comment">// if deal https request</span>
-  *beforeDealHttpsRequest(requestDetail) { <span class="hljs-comment">/* ... */</span> }, 
-  <span class="hljs-comment">// error happened when dealing requests</span>
-  *onError(requestDetail, error) { <span class="hljs-comment">/* ... */</span> }, 
-  <span class="hljs-comment">// error happened when connect to https server</span>
-  *onConnectError(requestDetail, error) { <span class="hljs-comment">/* ... */</span> } 
-};</code></pre><blockquote>
-<p>All functions in your rule file, except summary, are all driven by <a href="https://www.npmjs.com/package/co">co</a> . They should be yieldable, i.e. return a promise or be a generator function.</p>
-</blockquote>
-<h3 id="summary"><a class="header-link" href="#summary"></a>summary</h3>
-<h4 id="summary-1"><a class="header-link" href="#summary-1"></a>summary</h4>
-<ul class="list">
-<li>Introduction of this rule file. AnyProxy will read this field and give some tip to user.</li>
-</ul>
-<h3 id="beforesendrequest"><a class="header-link" href="#beforesendrequest"></a>beforeSendRequest</h3>
-<h4 id="beforesendrequest(requestdetail)"><a class="header-link" href="#beforesendrequest(requestdetail)"></a>beforeSendRequest(requestDetail)</h4>
-<ul class="list">
-<li>Before sending request to server, AnyProxy will call <code>beforeSendRequest</code> with param <code>requestDetail</code></li>
-<li><code>requestDetail</code> <ul class="list">
-<li><code>protocol</code> {string} the protocol to use, http or https</li>
-<li><code>requestOptions</code> {object} the options of the request-to-go, a param of require(&#39;http&#39;).request . ref: <a href="https://nodejs.org/api/http.html#http_http_request_options_callback">https://nodejs.org/api/http.html#http_http_request_options_callback</a></li>
-<li><code>requestData</code> {object} request body</li>
-<li><code>url</code> {string} request url</li>
-<li><code>_req</code> {object} the native node.js request object</li>
-</ul>
-</li>
-<li><p>e.g. When requesting  <em>anyproxy.io</em>, <code>requestDetail</code> is something like the following</p>
-<pre class="hljs"><code>{
-  <span class="hljs-attr">protocol</span>: <span class="hljs-string">'http'</span>,
-  <span class="hljs-attr">url</span>: <span class="hljs-string">'http://anyproxy.io/'</span>,
-  <span class="hljs-attr">requestOptions</span>: {
-    <span class="hljs-attr">hostname</span>: <span class="hljs-string">'anyproxy.io'</span>,
-    <span class="hljs-attr">port</span>: <span class="hljs-number">80</span>,
-    <span class="hljs-attr">path</span>: <span class="hljs-string">'/'</span>,
-    <span class="hljs-attr">method</span>: <span class="hljs-string">'GET'</span>,
-    <span class="hljs-attr">headers</span>: {
-      <span class="hljs-attr">Host</span>: <span class="hljs-string">'anyproxy.io'</span>,
-      <span class="hljs-string">'Proxy-Connection'</span>: <span class="hljs-string">'keep-alive'</span>,
-      <span class="hljs-string">'User-Agent'</span>: <span class="hljs-string">'...'</span>
-    }
-  },
-  <span class="hljs-attr">requestData</span>: <span class="hljs-string">'...'</span>,
-  <span class="hljs-attr">_req</span>: { <span class="hljs-comment">/* ... */</span>}
-}</code></pre></li>
-<li><p>Any of these return values are valid</p>
-<ul class="list">
-<li>do nothing, and return null</li>
-</ul>
-<pre class="hljs"><code><span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;</code></pre><ul class="list">
-<li>modify the request protocol,i.e. force use https</li>
-</ul>
-<pre class="hljs"><code><span class="hljs-keyword">return</span> {
-  <span class="hljs-attr">protocol</span>: <span class="hljs-string">'https'</span>
-};</code></pre><ul class="list">
-<li>modify request param</li>
-</ul>
-<pre class="hljs"><code><span class="hljs-keyword">var</span> newOption = <span class="hljs-built_in">Object</span>.assign({}, requestDetail.requestOptions);
-newOption.path = <span class="hljs-string">'/redirect/to/another/path'</span>;
-<span class="hljs-keyword">return</span> {
-  <span class="hljs-attr">requestOptions</span>: newOption
-};</code></pre><ul class="list">
-<li>modify request body</li>
-</ul>
-<pre class="hljs"><code><span class="hljs-keyword">return</span> {
-  <span class="hljs-attr">requestData</span>: <span class="hljs-string">'my new request data'</span>
-  <span class="hljs-comment">// requestOptions can also be used here</span>
-};</code></pre><ul class="list">
-<li>give response to the client, not sending request any longer. <code>statusCode</code> <code>headers</code>are required is this situation.</li>
-</ul>
-<pre class="hljs"><code><span class="hljs-keyword">return</span> {
-  <span class="hljs-attr">response</span>: {
-    <span class="hljs-attr">statusCode</span>: <span class="hljs-number">200</span>,
-    <span class="hljs-attr">header</span>: { <span class="hljs-string">'content-type'</span>: <span class="hljs-string">'text/html'</span> },
-    <span class="hljs-attr">body</span>: <span class="hljs-string">'this could be a &lt;string&gt; or &lt;buffer&gt;'</span>
-  }
-};</code></pre></li>
-</ul>
-<h3 id="beforesendresponse"><a class="header-link" href="#beforesendresponse"></a>beforeSendResponse</h3>
-<h4 id="beforesendresponse(requestdetail,-responsedetail)"><a class="header-link" href="#beforesendresponse(requestdetail,-responsedetail)"></a>beforeSendResponse(requestDetail, responseDetail)</h4>
-<ul class="list">
-<li>Before sending response to client, AnyProxy will call <code>beforeSendResponse</code> with param <code>requestDetail</code> <code>responseDetail</code></li>
-<li><code>requestDetail</code> is the same param as in <code>beforeSendRequest</code></li>
-<li><code>responseDetail</code> <ul class="list">
-<li><code>response</code> {object} the response from server, includes <code>statusCode</code> <code>header</code> <code>body</code></li>
-<li><code>_res</code> {object} the native node.js response object</li>
-</ul>
-</li>
-<li><p>e.g. When requesting <em>anyproxy.io</em>, <code>responseDetail</code> is something like the following</p>
-<pre class="hljs"><code>{ 
-  <span class="hljs-attr">response</span>: { 
-    <span class="hljs-attr">statusCode</span>: <span class="hljs-number">200</span>,
-    <span class="hljs-attr">header</span>: { 
-      <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'image/gif'</span>,
-      <span class="hljs-attr">Connection</span>: <span class="hljs-string">'close'</span>,
-      <span class="hljs-string">'Cache-Control'</span>: <span class="hljs-string">'...'</span>
-    },
-    <span class="hljs-attr">body</span>: <span class="hljs-string">'...'</span>
-  },
-  <span class="hljs-attr">_res</span>: { <span class="hljs-comment">/* ... */</span> }
-}</code></pre></li>
-<li><p>Any of these return values are valid</p>
-<ul class="list">
-<li>do nothing, and return null</li>
-</ul>
-<pre class="hljs"><code><span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;</code></pre><ul class="list">
-<li>modify the response status code</li>
-</ul>
-<pre class="hljs"><code><span class="hljs-keyword">var</span> newResponse = <span class="hljs-built_in">Object</span>.assign({}, responseDetail.reponse);
-newResponse.statusCode = <span class="hljs-number">404</span>;
-<span class="hljs-keyword">return</span> {
-  <span class="hljs-attr">response</span>: newResponse
-};</code></pre><ul class="list">
-<li>modify the response content</li>
-</ul>
-<pre class="hljs"><code><span class="hljs-keyword">var</span> newResponse = <span class="hljs-built_in">Object</span>.assign({}, responseDetail.reponse);
-newResponse.body += <span class="hljs-string">'--from anyproxy--'</span>;
-<span class="hljs-keyword">return</span> {
-  <span class="hljs-attr">response</span>: newResponse
-};</code></pre></li>
-</ul>
-<h3 id="beforedealhttpsrequest"><a class="header-link" href="#beforedealhttpsrequest"></a>beforeDealHttpsRequest</h3>
-<h4 id="beforedealhttpsrequest(requestdetail)"><a class="header-link" href="#beforedealhttpsrequest(requestdetail)"></a>beforeDealHttpsRequest(requestDetail)</h4>
-<ul class="list">
-<li>When receiving https request, AnyProxy will call <code>beforeDealHttpsRequest</code> with param <code>requestDetail</code></li>
-<li>If configed with <code>forceProxyHttps</code> in launching, AnyProxy will skip calling this method</li>
-<li>Only by returning true, AnyProxy will try to replace the certificate and intercept the https request.</li>
-<li><code>requestDetail</code><ul class="list">
-<li><code>host</code> {string} the target host to request. Due to the request protocol, full url couldn&#39;t be got here</li>
-<li><code>_req</code> {object} the native node.js request object. The <code>_req</code> here refers to the CONNECT request.</li>
-</ul>
-</li>
-<li>return value<ul class="list">
-<li><code>true</code> or <code>false</code>, whether AnyProxy should intercept the https request</li>
-</ul>
-</li>
-</ul>
-<h3 id="onerror"><a class="header-link" href="#onerror"></a>onError</h3>
-<h4 id="onerror(requestdetail,-error)"><a class="header-link" href="#onerror(requestdetail,-error)"></a>onError(requestDetail, error)</h4>
-<ul class="list">
-<li>AnyProxy will call this method when an error happened in request handling.</li>
-<li>Errors usually are issued during requesting, e.g. DNS failure, request timeout</li>
-<li><code>requestDetail</code> is the same one as in <code>beforeSendRequest</code></li>
-<li><p>Any of these return values are valid</p>
-<ul class="list">
-<li>do nothing, and AnyProxy will response a default error page</li>
-</ul>
-<pre class="hljs"><code><span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;</code></pre><ul class="list">
-<li>return a customized error page</li>
-</ul>
-<pre class="hljs"><code><span class="hljs-keyword">return</span> {
-  <span class="hljs-attr">response</span>: {
-    <span class="hljs-attr">statusCode</span>: <span class="hljs-number">200</span>,
-    <span class="hljs-attr">header</span>: { <span class="hljs-string">'content-type'</span>: <span class="hljs-string">'text/html'</span> },
-    <span class="hljs-attr">body</span>: <span class="hljs-string">'this could be a &lt;string&gt; or &lt;buffer&gt;'</span>
-  }
-};</code></pre></li>
-</ul>
-<h3 id="onconnecterror"><a class="header-link" href="#onconnecterror"></a>onConnectError</h3>
-<h4 id="onconnecterror(requestdetail,-error)"><a class="header-link" href="#onconnecterror(requestdetail,-error)"></a>onConnectError(requestDetail, error)</h4>
-<ul class="list">
-<li>AnyProxy will call this method when failed to connect target server in https request</li>
-<li><code>requestDetail</code> is the same one as in <code>beforeDealHttpsRequest</code></li>
-<li>no return value is required </li>
-</ul>
-<h3 id="faq"><a class="header-link" href="#faq"></a>FAQ</h3>
-<ul class="list">
-<li>Q: can not deal https request in rule module.</li>
-<li><p>A: Any of these options could be used to change the way AnyProxy deall https requests </p>
-<ol class="list">
-<li>config <code>--intercept</code> when luanching AnyProxy via cli, or use <code>forceProxyHttps</code> when using as an npm module</li>
-<li>place a <code>beforeDealHttpsRequest</code> function in your rule file and determine which request to intercept by your own.</li>
-</ol>
-</li>
-<li><p>Q: get an error says <em>function is not yieldable</em></p>
-</li>
-<li>A: Rule module is driven by <a href="https://www.npmjs.com/package/co">co</a>. The functions inside should  be yieldable, i.e. return a promise or be a generator function.</li>
-</ul>
-<h2 id="rule-samples"><a class="header-link" href="#rule-samples"></a>Rule Samples</h2>
-<ul class="list">
-<li>here are some samples about frequently used rule file</li>
-<li>try these samples by <code>anyproxy --rule http://....js</code></li>
-<li>how to test with curl:<ul class="list">
-<li>request the server directly <code>curl http://httpbin.org/</code></li>
-<li>request the server via proxy <code>curl http://httpbin.org/ --proxy http://127.0.0.1:8001</code></li>
-</ul>
-</li>
-</ul>
-<h3 id="use-local-response"><a class="header-link" href="#use-local-response"></a>use local response</h3>
-<ul class="list">
-<li>intercept the request towards <a href="http://httpbin.org">http://httpbin.org</a> , return the local-defined response</li>
-</ul>
-<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_use_local_response.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
-  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
-*/</span>
-<span class="hljs-built_in">module</span>.exports = {
-  *beforeSendRequest(requestDetail) {
-    <span class="hljs-keyword">const</span> localResponse = {
-      <span class="hljs-attr">statusCode</span>: <span class="hljs-number">200</span>,
-      <span class="hljs-attr">header</span>: { <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'application/json'</span> },
-      <span class="hljs-attr">body</span>: <span class="hljs-string">'{"hello": "this is local response"}'</span>
-    };
-    <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org'</span>) === <span class="hljs-number">0</span>) {
-      <span class="hljs-keyword">return</span> {
-        <span class="hljs-attr">response</span>: localResponse
-      };
-    }
-  },
-};</code></pre><h3 id="modify-request-header"><a class="header-link" href="#modify-request-header"></a>modify request header</h3>
-<ul class="list">
-<li>modify the user-agent sent to httpbin.org</li>
-</ul>
-<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_request_header.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
-  sample: 
-    modify the user-agent in requests toward httpbin.org
-  test:
-    curl http://httpbin.org/user-agent --proxy http://127.0.0.1:8001
-*/</span>
-<span class="hljs-built_in">module</span>.exports = {
-  *beforeSendRequest(requestDetail) {
-    <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org'</span>) === <span class="hljs-number">0</span>) {
-      <span class="hljs-keyword">const</span> newRequestOptions = requestDetail.requestOptions;
-      newRequestOptions.headers[<span class="hljs-string">'User-Agent'</span>] = <span class="hljs-string">'AnyProxy/0.0.0'</span>;
-      <span class="hljs-keyword">return</span> {
-        <span class="hljs-attr">requestOptions</span>: newRequestOptions
-      };
-    }
-  },
-};</code></pre><h3 id="modify-request-body"><a class="header-link" href="#modify-request-body"></a>modify request body</h3>
-<ul class="list">
-<li>modify the post body of <a href="http://httpbin.org/post">http://httpbin.org/post</a></li>
-</ul>
-<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_request_data.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
-  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" }
-*/</span>
-<span class="hljs-built_in">module</span>.exports = {
-  *beforeSendRequest(requestDetail) {
-    <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org/post'</span>) === <span class="hljs-number">0</span>) {
-      <span class="hljs-keyword">return</span> {
-        <span class="hljs-attr">requestData</span>: <span class="hljs-string">'i-am-anyproxy-modified-post-data'</span>
-      };
-    }
-  },
-};</code></pre><h3 id="modify-the-request-target"><a class="header-link" href="#modify-the-request-target"></a>modify the request target</h3>
-<ul class="list">
-<li>send all the request towards <a href="http://httpbin.org/">http://httpbin.org/</a> to <a href="http://httpbin.org/user-agent">http://httpbin.org/user-agent</a></li>
-</ul>
-<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_request_path.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
-  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" }
-*/</span>
-<span class="hljs-built_in">module</span>.exports = {
-  *beforeSendRequest(requestDetail) {
-    <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org'</span>) === <span class="hljs-number">0</span>) {
-      <span class="hljs-keyword">const</span> newRequestOptions = requestDetail.requestOptions;
-      newRequestOptions.path = <span class="hljs-string">'/user-agent'</span>;
-      newRequestOptions.method = <span class="hljs-string">'GET'</span>;
-      <span class="hljs-keyword">return</span> {
-        <span class="hljs-attr">requestOptions</span>: newRequestOptions
-      };
-    }
-  },
-};</code></pre><h3 id="modify-request-protocol"><a class="header-link" href="#modify-request-protocol"></a>modify request protocol</h3>
-<ul class="list">
-<li>modify the http request towards <a href="http://httpbin.org">http://httpbin.org</a> to https</li>
-</ul>
-<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_request_protocol.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
-  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" }
-*/</span>
-<span class="hljs-built_in">module</span>.exports = {
-  *beforeSendRequest(requestDetail) {
-    <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org'</span>) === <span class="hljs-number">0</span>) {
-      <span class="hljs-keyword">const</span> newOption = requestDetail.requestOptions;
-      newOption.port = <span class="hljs-number">443</span>;
-      <span class="hljs-keyword">return</span> {
-        <span class="hljs-attr">protocol</span>: <span class="hljs-string">'https'</span>,
-        <span class="hljs-attr">requestOptions</span>: newOption
-      };
-    }
-  }
-};</code></pre><h3 id="modify-response-status-code"><a class="header-link" href="#modify-response-status-code"></a>modify response status code</h3>
-<ul class="list">
-<li>modify all status code from <a href="http://httpbin.org">http://httpbin.org</a> to 404</li>
-</ul>
-<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_response_statuscode.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
-  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
-*/</span>
-<span class="hljs-built_in">module</span>.exports = {
-  *beforeSendResponse(requestDetail, responseDetail) {
-    <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org'</span>) === <span class="hljs-number">0</span>) {
-      <span class="hljs-keyword">const</span> newResponse = responseDetail.response;
-      newResponse.statusCode = <span class="hljs-number">404</span>;
-      <span class="hljs-keyword">return</span> {
-        <span class="hljs-attr">response</span>: newResponse
-      };
-    }
-  }
-};</code></pre><h3 id="modify-the-response-header"><a class="header-link" href="#modify-the-response-header"></a>modify the response header</h3>
-<ul class="list">
-<li>add X-Proxy-By:AnyProxy to the response header from <a href="http://httpbin.org/user-agent">http://httpbin.org/user-agent</a></li>
-</ul>
-<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_response_header.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
-  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
-*/</span>
-<span class="hljs-built_in">module</span>.exports = {
-  *beforeSendResponse(requestDetail, responseDetail) {
-    <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org/user-agent'</span>) === <span class="hljs-number">0</span>) {
-      <span class="hljs-keyword">const</span> newResponse = responseDetail.response;
-      newResponse.header[<span class="hljs-string">'X-Proxy-By'</span>] = <span class="hljs-string">'AnyProxy'</span>;
-      <span class="hljs-keyword">return</span> {
-        <span class="hljs-attr">response</span>: newResponse
-      };
-    }
-  }
-};</code></pre><h3 id="modify-response-data-and-delay"><a class="header-link" href="#modify-response-data-and-delay"></a>modify response data and delay</h3>
-<ul class="list">
-<li>append some info to the response of <a href="http://httpbin.org/user-agent">http://httpbin.org/user-agent</a>, then delay the response for 5 seconds.</li>
-</ul>
-<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_response_data.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
-  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! --
-*/</span>
-
-<span class="hljs-built_in">module</span>.exports = {
-  *beforeSendResponse(requestDetail, responseDetail) {
-    <span class="hljs-keyword">if</span> (requestDetail.url === <span class="hljs-string">'http://httpbin.org/user-agent'</span>) {
-      <span class="hljs-keyword">const</span> newResponse = responseDetail.response;
-      newResponse.body += <span class="hljs-string">'-- AnyProxy Hacked! --'</span>;
-      <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =&gt;</span> {
-        setTimeout(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> { <span class="hljs-comment">// delay the response for 5s</span>
-          resolve({ <span class="hljs-attr">response</span>: newResponse });
-        }, <span class="hljs-number">5000</span>);
-      });
-    }
-  },
-};</code></pre><h2 id="use-anyproxy-as-an-npm-module"><a class="header-link" href="#use-anyproxy-as-an-npm-module"></a>Use AnyProxy as an npm module</h2>
-<p>AnyProxy can be used as an npm module</p>
-<blockquote>
-<p>To enable https feature, please guide users to use <code>anyproxy-ca</code> in cli. Or use methods under <code>AnyProxy.utils.certMgr</code> to generate certificates.</p>
-</blockquote>
-<ul class="list">
-<li>install</li>
-</ul>
-<pre class="hljs"><code>npm i anyproxy@beta --save <span class="hljs-comment"># 4.0 is in beta now</span></code></pre><ul class="list">
-<li>sample</li>
-</ul>
-<pre class="hljs"><code><span class="hljs-keyword">const</span> AnyProxy = <span class="hljs-built_in">require</span>(<span class="hljs-string">'anyproxy'</span>);
-<span class="hljs-keyword">const</span> options = {
-  <span class="hljs-attr">port</span>: <span class="hljs-number">8001</span>,
-  <span class="hljs-attr">rule</span>: <span class="hljs-built_in">require</span>(<span class="hljs-string">'myRuleModule'</span>),
-  <span class="hljs-attr">webInterface</span>: {
-    <span class="hljs-attr">enable</span>: <span class="hljs-literal">true</span>,
-    <span class="hljs-attr">webPort</span>: <span class="hljs-number">8002</span>,
-    <span class="hljs-attr">wsPort</span>: <span class="hljs-number">8003</span>,
-  },
-  <span class="hljs-attr">throttle</span>: <span class="hljs-number">10000</span>,
-  <span class="hljs-attr">forceProxyHttps</span>: <span class="hljs-literal">false</span>,
-  <span class="hljs-attr">silent</span>: <span class="hljs-literal">false</span>
-};
-<span class="hljs-keyword">const</span> proxyServer = <span class="hljs-keyword">new</span> AnyProxy.ProxyServer(options);
-
-proxyServer.on(<span class="hljs-string">'ready'</span>, () =&gt; { <span class="hljs-comment">/* */</span> });
-proxyServer.on(<span class="hljs-string">'error'</span>, (e) =&gt; { <span class="hljs-comment">/* */</span> });
-proxyServer.start();
-
-<span class="hljs-comment">//when finished</span>
-proxyServer.close();</code></pre><ul class="list">
-<li><p>Class: AnyProxy.proxyServer</p>
-<ul class="list">
-<li><p>create a proxy server</p>
-<pre class="hljs"><code><span class="hljs-keyword">const</span> proxy = <span class="hljs-keyword">new</span> AnyProxy.proxyServer(options)</code></pre></li>
-<li><p><code>options</code></p>
-<ul class="list">
-<li><code>port</code> {number} required, port number of proxy server</li>
-<li><code>rule</code> {object} your rule module</li>
-<li><code>throttle</code> {number} throttle in kb/s, unlimited for default</li>
-<li><code>forceProxyHttps</code> {boolean} in force intercept all https request, false for default</li>
-<li><code>silent</code> {boolean} if keep silent in console, false for default<code>false</code></li>
-<li><code>dangerouslyIgnoreUnauthorized</code> {boolean} if ignore certificate error in request, false for default</li>
-<li><code>webInterface</code> {object} config for web interface<ul class="list">
-<li><code>enable</code> {boolean} if enable web interface, false for default</li>
-<li><code>webPort</code> {number} port number for web interface</li>
-</ul>
-</li>
-</ul>
-</li>
-<li><p>Event: <code>ready</code></p>
-<ul class="list">
-<li>emit when proxy server is ready</li>
-<li>sample</li>
-</ul>
-<pre class="hljs"><code>proxy.on(<span class="hljs-string">'ready'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{ })</code></pre></li>
-<li><p>Event: <code>error</code></p>
-<ul class="list">
-<li>emit when error happened inside proxy server</li>
-<li>sample</li>
-</ul>
-<pre class="hljs"><code>proxy.on(<span class="hljs-string">'error'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{ })</code></pre></li>
-<li><p>Method: <code>start</code></p>
-<ul class="list">
-<li>start proxy server</li>
-<li>sample</li>
-</ul>
-<pre class="hljs"><code>proxy.start();</code></pre></li>
-<li><p>Method: <code>close</code></p>
-<ul class="list">
-<li>close proxy server</li>
-<li>sample</li>
-</ul>
-<pre class="hljs"><code>proxy.close();</code></pre></li>
-</ul>
-</li>
-<li><p>AnyProxy.utils.systemProxyMgr</p>
-<ul class="list">
-<li>manage the system proxy config. sudo password may be required</li>
-<li>sample</li>
-</ul>
-<pre class="hljs"><code><span class="hljs-comment">// set 127.0.0.1:8001 as system http server</span>
-AnyProxy.utils.systemProxyMgr.enableGlobalProxy(<span class="hljs-string">'127.0.0.1'</span>, <span class="hljs-string">'8001'</span>);    
-
-<span class="hljs-comment">// disable global proxy server</span>
-AnyProxy.utils.systemProxyMgr.disableGlobalProxy();</code></pre></li>
-<li><p>AnyProxy.utils.certMgr</p>
-<ul class="list">
-<li>Manage certificates of AnyProxy</li>
-<li><code>AnyProxy.utils.certMgr.ifRootCAFileExists()</code><ul class="list">
-<li>detect if AnyProx rootCA exists</li>
-</ul>
-</li>
-<li><code>AnyProxy.utils.certMgr.generateRootCA(callback)</code><ul class="list">
-<li>generate a rootCA</li>
-</ul>
-</li>
-<li>Sample</li>
-</ul>
-<pre class="hljs"><code>  <span class="hljs-keyword">const</span> AnyProxy = <span class="hljs-built_in">require</span>(<span class="hljs-string">'AnyProxy'</span>);
-  <span class="hljs-keyword">const</span> exec = <span class="hljs-built_in">require</span>(<span class="hljs-string">'child_process'</span>).exec;
-
-  <span class="hljs-keyword">if</span> (!AnyProxy.utils.certMgr.ifRootCAFileExists()) {
-    AnyProxy.utils.certMgr.generateRootCA(<span class="hljs-function">(<span class="hljs-params">error, keyPath</span>) =&gt;</span> {
-      <span class="hljs-comment">// let users to trust this CA before using proxy</span>
-      <span class="hljs-keyword">if</span> (!error) {
-        <span class="hljs-keyword">const</span> certDir = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>).dirname(keyPath);
-        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'The cert is generated at'</span>, certDir);
-        <span class="hljs-keyword">const</span> isWin = <span class="hljs-regexp">/^win/</span>.test(process.platform);
-        <span class="hljs-keyword">if</span> (isWin) {
-          exec(<span class="hljs-string">'start .'</span>, { <span class="hljs-attr">cwd</span>: certDir });
-        } <span class="hljs-keyword">else</span> {
-          exec(<span class="hljs-string">'open .'</span>, { <span class="hljs-attr">cwd</span>: certDir });
-        }
-      } <span class="hljs-keyword">else</span> {
-        <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'error when generating rootCA'</span>, error);
-      }
-    });
-  }</code></pre></li>
-</ul>
-<h2 id="about-anyproxy"><a class="header-link" href="#about-anyproxy"></a>About AnyProxy</h2>
-<ul class="list">
-<li>Change Log: <a href="https://github.com/alibaba/anyproxy/blob/master/CHANGELOG">https://github.com/alibaba/anyproxy/blob/master/CHANGELOG</a></li>
-<li>Github:<a href="https://github.com/alibaba/anyproxy">https://github.com/alibaba/anyproxy</a></li>
-<li>issue:<a href="https://github.com/alibaba/anyproxy/issues">https://github.com/alibaba/anyproxy/issues</a></li>
-</ul>
-<h2 id="appendix"><a class="header-link" href="#appendix"></a>Appendix</h2>
-<h3 id="config-root-ca-in-osx"><a class="header-link" href="#config-root-ca-in-osx"></a>Config root CA in OSX</h3>
-<ul class="list">
-<li>this kind of errors is usually caused by untrusted root CA</li>
-</ul>
-<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/CBkLGYgvoHAYwNVAYkpk.png" width="450" /></p>
-<blockquote>
-<p>Warning: please keep your root CA safe since it may influence your system security.</p>
-</blockquote>
-<p>install :</p>
-<ul class="list">
-<li><p>double click <em>rootCA.crt</em></p>
-</li>
-<li><p>add cert into login or system</p>
-</li>
-</ul>
-<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/bCwNUFFpvsmVuljQKrIk.png" width="350" /></p>
-<ul class="list">
-<li>find the newly imported AnyProxy certificates, configured as <strong>Always Trust</strong></li>
-</ul>
-<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/HOmEElNGdoZEWFMLsTNT.png" width="700" /></p>
-<h3 id="trust-root-ca-in-windows"><a class="header-link" href="#trust-root-ca-in-windows"></a>trust root CA in windows</h3>
-<p class="img-container"><img src="https://t.alipayobjects.com/tfscom/T1D3hfXeFtXXXXXXXX.jpg" width="700" /></p>
-<h3 id="config-osx-system-proxy"><a class="header-link" href="#config-osx-system-proxy"></a>config OSX system proxy</h3>
-<ul class="list">
-<li>the config is in wifi - advanced</li>
-</ul>
-<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/vduwhobSTypTfgniBvoa.png" width="500" /></p>
-<h3 id="config-http-proxy-server"><a class="header-link" href="#config-http-proxy-server"></a>config http proxy server</h3>
-<ul class="list">
-<li>take Chrome extent [SwitchyOmega] as an example(<a href="https://chrome.google.com/webstore/detail/padekgcemlokbadohgkifijomclgjgif)为例">https://chrome.google.com/webstore/detail/padekgcemlokbadohgkifijomclgjgif)为例</a></li>
-</ul>
-<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/jIPZrKmqXRaSledQeJUJ.png" width="500" /></p>
-<h3 id="trust-root-ca-in-ios"><a class="header-link" href="#trust-root-ca-in-ios"></a>trust root CA in iOS</h3>
-<ul class="list">
-<li>Click <em>Root CA</em> in web ui, and follow the instruction to install</li>
-</ul>
-<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/BrugmMelGVysLDOIBblj.png" width="260" /></p>
-<h3 id="trust-root-ca-in-ios->=-10.3"><a class="header-link" href="#trust-root-ca-in-ios->=-10.3"></a>trust root CA in iOS &gt;= 10.3</h3>
-<ul class="list">
-<li>Besides installing root CA, you have to &quot;turn on&quot; the certificate for web manually in <em>settings - general - about - Certificate Trust Settings</em>. Otherwire, safari will not trust the root CA generated by AnyProxy.</li>
-</ul>
-<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/hVWkXHrzHmOKOtCKGUWx.png" width="500" /></p>
-<h3 id="config-ios/android-proxy-server"><a class="header-link" href="#config-ios/android-proxy-server"></a>config iOS/Android proxy server</h3>
-<ul class="list">
-<li><p>proxy settings are placed in wifi setting</p>
-</li>
-<li><p>iOS</p>
-</li>
-</ul>
-<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/tLGqIozhffTccUgPakuw.png" width="260" /></p>
-<ul class="list">
-<li>Android</li>
-</ul>
-<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/YQtbQYVNuOszZGdAOauU.png" width="260" /></p>
-    </div>
-  </article>
-
-  <script src="//cdn.bootcss.com/zepto/1.2.0/zepto.min.js"></script>
-  <script>
-  window.onload = function(){
-    var itemList = [];
-    var targetMap = {};
-    $("[id]", ".main-content").map(function (index, heading) {
-      targetMap[heading.getAttribute('id')] = heading;
-    });
-
-    $("#j_toc li").map(function (index, item) {
-      if (item.className.indexOf('sidebar-header-2') >= 0 || item.className.indexOf('sidebar-header-3') >= 0) {
-        var targetName = item.firstChild.getAttribute('href').replace('#', '');
-        var targetItem = targetMap[targetName];
-        itemList.push({ target: targetItem, tocItem: item, top: $(targetItem).position().top });
-      }
-    });
-
-    var updateTocActive = function (e) {
-      var windowHeight = window.innerHeight;
-      //find the first item to match
-      var scrollYThres = window.scrollY + 200;
-      var target;
-      if (scrollYThres < 100) {
-        target = itemList[0].tocItem;
-      } else {
-        itemList.forEach(function (item, index) {
-          if (target) return;
-          if (index > 0) {
-            if (item.top >= scrollYThres) {
-              target = itemList[index - 1].tocItem;
-            }
-          }
-        });
-      }
-
-      $('.toc-active').removeClass('toc-active');
-      $(target).addClass('toc-active');
-    };
-
-    window.onscroll = updateTocActive;
-    updateTocActive();
-  }
-  </script>
 </body>
 
 </html>
\ No newline at end of file
diff --git a/4.x/assets/css/atom-one-light.css b/assets/css/atom-one-light.css
similarity index 100%
rename from 4.x/assets/css/atom-one-light.css
rename to assets/css/atom-one-light.css
diff --git a/4.x/assets/css/custom.css b/assets/css/custom.css
similarity index 100%
rename from 4.x/assets/css/custom.css
rename to assets/css/custom.css
diff --git a/4.x/assets/css/github-markdown.css b/assets/css/github-markdown.css
similarity index 100%
rename from 4.x/assets/css/github-markdown.css
rename to assets/css/github-markdown.css
diff --git a/4.x/assets/css/pilcrow.css b/assets/css/pilcrow.css
similarity index 100%
rename from 4.x/assets/css/pilcrow.css
rename to assets/css/pilcrow.css
diff --git a/cn.html b/cn.html
new file mode 100644
index 0000000..9e14363
--- /dev/null
+++ b/cn.html
@@ -0,0 +1,837 @@
+<!doctype html>
+<html>
+
+<head>
+  <meta charset="utf-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1, minimal-ui">
+  <title>AnyProxy</title>
+  <link type="text/css" rel="stylesheet" href="assets/css/github-markdown.css">
+  <link type="text/css" rel="stylesheet" href="assets/css/pilcrow.css">
+  <link type="text/css" rel="stylesheet" href="assets/css/atom-one-light.css" />
+  <link type="text/css" rel="stylesheet" href="assets/css/custom.css" />
+  <meta name="description" content="A fully configurable proxy in NodeJS, which can handle HTTPS requests perfectly.">
+  <meta name="description" content="AnyProxy - 开放式的HTTP/HTTPS代理,你可以灵活控制各种网络数据">
+  <meta name="keywords" content="代理服务器 Proxy HTTP HTTPS">
+  <script>
+    //redirect to Chinese version if in China
+    if (new Date().getTimezoneOffset() == "-480" && !(/(cn|en)/i.test(location.href))) {
+      location.href = "./cn.html";
+    } else {
+      var _hmt = _hmt || []; (function () { var hm = document.createElement("script"); hm.src = "//hm.baidu.com/hm.js?4e51565b7d471fd6623c163a8fd79e07"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })();
+    }
+  </script>
+</head>
+
+<body>
+  <a href="https://github.com/alibaba/anyproxy/tree/4.x" target="_blank">
+    <img style="position: fixed; top: 0; right: 0; border: 0;z-index: 1;" src="https://camo.githubusercontent.com/a6677b08c955af8400f44c6298f40e7d19cc5b2d/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f677261795f3664366436642e706e67"
+      alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_gray_6d6d6d.png">
+  </a>
+
+  <article class="markdown-body">
+    <div class="toc-container" id="j_toc">
+      <div class="toc-content"><ul class="nav nav-list">
+    <li class="sidebar-header-1"><a href="#anyproxy">AnyProxy</a></li>
+    <li class="sidebar-header-2"><a href="#快速上手">快速上手</a></li>
+    <li class="sidebar-header-3"><a href="#安装">安装</a></li>
+    <li class="sidebar-header-3"><a href="#启动">启动</a></li>
+    <li class="sidebar-header-3"><a href="#其他命令">其他命令</a></li>
+    <li class="sidebar-header-2"><a href="#代理https请求">代理https请求</a></li>
+    <li class="sidebar-header-2"><a href="#规则模块(rule)">规则模块(Rule)</a></li>
+    <li class="sidebar-header-3"><a href="#开发示例">开发示例</a></li>
+    <li class="sidebar-header-3"><a href="#处理流程">处理流程</a></li>
+    <li class="sidebar-header-3"><a href="#如何引用">如何引用</a></li>
+    <li class="sidebar-header-2"><a href="#规则接口文档">规则接口文档</a></li>
+    <li class="sidebar-header-3"><a href="#summary">summary</a></li>
+    <li class="sidebar-header-4"><a href="#summary-1">summary</a></li>
+    <li class="sidebar-header-3"><a href="#beforesendrequest">beforeSendRequest</a></li>
+    <li class="sidebar-header-4"><a href="#beforesendrequest(requestdetail)">beforeSendRequest(requestDetail)</a></li>
+    <li class="sidebar-header-3"><a href="#beforesendresponse">beforeSendResponse</a></li>
+    <li class="sidebar-header-4"><a href="#beforesendresponse(requestdetail,-responsedetail)">beforeSendResponse(requestDetail, responseDetail)</a></li>
+    <li class="sidebar-header-3"><a href="#beforedealhttpsrequest">beforeDealHttpsRequest</a></li>
+    <li class="sidebar-header-4"><a href="#beforedealhttpsrequest(requestdetail)">beforeDealHttpsRequest(requestDetail)</a></li>
+    <li class="sidebar-header-3"><a href="#onerror">onError</a></li>
+    <li class="sidebar-header-4"><a href="#onerror(requestdetail,-error)">onError(requestDetail, error)</a></li>
+    <li class="sidebar-header-3"><a href="#onconnecterror">onConnectError</a></li>
+    <li class="sidebar-header-4"><a href="#onconnecterror(requestdetail,-error)">onConnectError(requestDetail, error)</a></li>
+    <li class="sidebar-header-3"><a href="#faq">FAQ</a></li>
+    <li class="sidebar-header-2"><a href="#规则模块样例">规则模块样例</a></li>
+    <li class="sidebar-header-3"><a href="#使用本地数据">使用本地数据</a></li>
+    <li class="sidebar-header-3"><a href="#修改请求头">修改请求头</a></li>
+    <li class="sidebar-header-3"><a href="#修改请求数据">修改请求数据</a></li>
+    <li class="sidebar-header-3"><a href="#修改请求的目标地址">修改请求的目标地址</a></li>
+    <li class="sidebar-header-3"><a href="#修改请求协议">修改请求协议</a></li>
+    <li class="sidebar-header-3"><a href="#修改返回状态码">修改返回状态码</a></li>
+    <li class="sidebar-header-3"><a href="#修改返回头">修改返回头</a></li>
+    <li class="sidebar-header-3"><a href="#修改返回内容并延迟">修改返回内容并延迟</a></li>
+    <li class="sidebar-header-2"><a href="#作为npm模块使用">作为npm模块使用</a></li>
+    <li class="sidebar-header-2"><a href="#关于anyproxy">关于AnyProxy</a></li>
+    <li class="sidebar-header-2"><a href="#配置帮助">配置帮助</a></li>
+    <li class="sidebar-header-3"><a href="#osx系统信任ca证书">OSX系统信任CA证书</a></li>
+    <li class="sidebar-header-3"><a href="#windows系统信任ca证书">Windows系统信任CA证书</a></li>
+    <li class="sidebar-header-3"><a href="#配置osx系统代理">配置OSX系统代理</a></li>
+    <li class="sidebar-header-3"><a href="#配置浏览器http代理">配置浏览器HTTP代理</a></li>
+    <li class="sidebar-header-3"><a href="#ios系统信任ca证书">iOS系统信任CA证书</a></li>
+    <li class="sidebar-header-3"><a href="#ios-&gt;&#x3D;-10.3信任ca证书">iOS &gt;&#x3D; 10.3信任CA证书</a></li>
+    <li class="sidebar-header-3"><a href="#配置ios/android系统代理">配置iOS/Android系统代理</a></li>
+</ul>
+      </div>
+    </div>
+    <div class="main-content"><h1 id="anyproxy"><a class="header-link" href="#anyproxy"></a>AnyProxy</h1>
+<blockquote>
+<p>本文档的适用范围是AnyProxy 4.0,此版本当前正在beta中,欢迎提供反馈</p>
+</blockquote>
+<p>Ref: <a href="./en.html">English Doc</a></p>
+<p>AnyProxy是一个开放式的HTTP代理服务器。</p>
+<p>Github主页:<a href="https://github.com/alibaba/anyproxy/tree/4.x">https://github.com/alibaba/anyproxy/tree/4.x</a></p>
+<p>主要特性包括:</p>
+<ul class="list">
+<li>基于Node.js,开放二次开发能力,允许自定义请求处理逻辑</li>
+<li>支持Https的解析</li>
+<li>提供GUI界面,用以观察请求</li>
+</ul>
+<p>相比3.x版本,AnyProxy 4.0的主要变化:</p>
+<ul class="list">
+<li>规则文件(Rule)全面支持Promise和Generator</li>
+<li>简化了规则文件内的接口</li>
+<li>Web版界面重构</li>
+</ul>
+<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/SqVntpzmscXPbSzfcGcr.png" width="500" /></p>
+<h2 id="快速上手"><a class="header-link" href="#快速上手"></a>快速上手</h2>
+<h3 id="安装"><a class="header-link" href="#安装"></a>安装</h3>
+<pre class="hljs"><code>npm install -g anyproxy@beta <span class="hljs-comment">#本文档对应的AnyProxy为4.0Beta版</span></code></pre><h3 id="启动"><a class="header-link" href="#启动"></a>启动</h3>
+<ul class="list">
+<li>命令行启动AnyProxy,默认端口号8001</li>
+</ul>
+<pre class="hljs"><code>anyproxy</code></pre><ul class="list">
+<li>启动后将终端http代理服务器配置为127.0.0.1:8001即可</li>
+<li>访问<a href="http://127.0.0.1:8002">http://127.0.0.1:8002</a> ,web界面上能看到所有的请求信息</li>
+</ul>
+<h3 id="其他命令"><a class="header-link" href="#其他命令"></a>其他命令</h3>
+<ul class="list">
+<li>配置启动端口,如1080端口启动</li>
+</ul>
+<pre class="hljs"><code>anyproxy --port 1080</code></pre><h2 id="代理https请求"><a class="header-link" href="#代理https请求"></a>代理https请求</h2>
+<ul class="list">
+<li>AnyProxy默认不对https请求做处理,如需看到明文信息,需要配置CA证书</li>
+</ul>
+<blockquote>
+<p>解析https请求的原理是中间人攻击(man-in-the-middle),用户必须信任AnyProxy生成的CA证书,才能进行后续流程</p>
+</blockquote>
+<ul class="list">
+<li>生成证书并解析所有https请求</li>
+</ul>
+<pre class="hljs"><code>anyproxy-ca <span class="hljs-comment">#生成rootCA证书,生成后需要手动信任</span>
+anyproxy --intercept <span class="hljs-comment">#启动AnyProxy,并解析所有https请求</span></code></pre><ul class="list">
+<li><a href="#osx系统信任ca证书">附录:如何信任CA证书</a></li>
+</ul>
+<h2 id="规则模块(rule)"><a class="header-link" href="#规则模块(rule)"></a>规则模块(Rule)</h2>
+<p>AnyProxy提供了二次开发的能力,你可以用js编写自己的规则模块(rule),来自定义网络请求的处理逻辑。</p>
+<blockquote>
+<p>注意:引用规则前,请务必确保文件来源可靠,以免发生安全问题</p>
+</blockquote>
+<p>规则模块的能力范围包括:</p>
+<ul class="list">
+<li>拦截并修改正在发送的请求<ul class="list">
+<li>可修改内容包括请求头(request header),请求体(request body),甚至是请求的目标地址等</li>
+</ul>
+</li>
+<li>拦截并修改服务端响应<ul class="list">
+<li>可修改的内容包括http状态码(status code)、响应头(response header)、响应内容等</li>
+</ul>
+</li>
+<li>拦截https请求,对内容做修改<ul class="list">
+<li>本质是中间人攻击(man-in-the-middle attack),需要客户端提前信任AnyProxy生成的CA</li>
+</ul>
+</li>
+</ul>
+<h3 id="开发示例"><a class="header-link" href="#开发示例"></a>开发示例</h3>
+<ul class="list">
+<li><p>举例</p>
+<ul class="list">
+<li>需要编写一个规则模块,在 GET <a href="http://httpbin.org/user-agent">http://httpbin.org/user-agent</a> 的返回值里加上测试信息,并延迟5秒返回</li>
+</ul>
+</li>
+<li><p>Step 1,编写规则</p>
+<pre class="hljs"><code><span class="hljs-comment">// file: sample.js</span>
+<span class="hljs-built_in">module</span>.exports = {
+  <span class="hljs-attr">summary</span>: <span class="hljs-string">'a rule to modify response'</span>,
+  *beforeSendResponse(requestDetail, responseDetail) {
+    <span class="hljs-keyword">if</span> (requestDetail.url === <span class="hljs-string">'http://httpbin.org/user-agent'</span>) {
+      <span class="hljs-keyword">const</span> newResponse = responseDetail.response;
+      newResponse.body += <span class="hljs-string">'-- AnyProxy Hacked! --'</span>;
+      <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =&gt;</span> {
+        setTimeout(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> { <span class="hljs-comment">// delay</span>
+          resolve({ <span class="hljs-attr">response</span>: newResponse });
+        }, <span class="hljs-number">5000</span>);
+      });
+    }
+  },
+};</code></pre></li>
+<li><p>Step 2, 启动AnyProxy,加载规则</p>
+<ul class="list">
+<li>运行 <code>anyproxy --rule sample.js</code></li>
+</ul>
+</li>
+<li><p>Step 3, 测试规则</p>
+<ul class="list">
+<li><p>用curl测试 </p>
+<pre class="hljs"><code>curl http://httpbin.org/user-agent --proxy http://127.0.0.1:8001</code></pre></li>
+<li><p>用浏览器测试:配置浏览器http代理为 127.0.0.1:8001,访问 <a href="http://httpbin.org/user-agent">http://httpbin.org/user-agent</a> </p>
+</li>
+<li><p>经过代理服务器后,期望的返回如下</p>
+</li>
+</ul>
+<pre class="hljs"><code>{
+  <span class="hljs-string">"user-agent"</span>: <span class="hljs-string">"curl/7.43.0"</span>
+}
+- AnyProxy Hacked!</code></pre></li>
+<li><p>Step 4, 查看请求信息</p>
+<ul class="list">
+<li>浏览器访问<a href="http://127.0.0.1:8002">http://127.0.0.1:8002</a> ,界面上能看到刚才的请求信息</li>
+</ul>
+</li>
+</ul>
+<h3 id="处理流程"><a class="header-link" href="#处理流程"></a>处理流程</h3>
+<ul class="list">
+<li>处理流程图如下</li>
+</ul>
+<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/TWyNuSJtEZBdrdcOMRjE.png" width="550" /></p>
+<ul class="list">
+<li><p>当http请求经过代理服务器时,具体处理过程是:</p>
+<ul class="list">
+<li>收集请求所有请求参数,包括method, header, body等</li>
+<li>AnyProxy调用规则模块<code>beforeSendRequest</code>方法,由模块做处理,返回新的请求参数,或返回响应内容</li>
+<li>如果<code>beforeSendRequest</code>返回了响应内容,则立即把此响应返回到客户端(而不再发送到真正的服务端),流程结束。</li>
+<li>根据请求参数,向服务端发出请求,接收服务端响应。</li>
+<li>调用规则模块<code>beforeSendResponse</code>方法,由模块对响应内容进行处理</li>
+<li>把响应信息返回给客户端</li>
+</ul>
+</li>
+<li><p>当代理服务器收到https请求时,AnyProxy可以替换证书,对请求做明文解析。</p>
+<ul class="list">
+<li>调用规则模块<code>beforeDealHttpsRequest</code>方法,如果返回<code>true</code>,会明文解析这个请求,其他请求不处理</li>
+<li>被明文解析后的https请求,处理流程同http一致。未明文解析请求不会再进入规则模块做处理。</li>
+</ul>
+</li>
+</ul>
+<h3 id="如何引用"><a class="header-link" href="#如何引用"></a>如何引用</h3>
+<p>如下几种方案都可以用来引用规则模块:</p>
+<ul class="list">
+<li>使用本地路径<pre class="hljs"><code>anyproxy --rule ./rule.js</code></pre></li>
+<li><p>使用在线地址</p>
+<pre class="hljs"><code>anyproxy --rule https://sample.com/rule.js</code></pre></li>
+<li><p>使用npm包</p>
+<ul class="list">
+<li>AnyProxy使用<code>require()</code>加载本地规则,你可以在参数里传入一个本地的npm包路径,或是某个全局安装的npm包</li>
+</ul>
+<pre class="hljs"><code>anyproxy --rule ./myRulePkg/ <span class="hljs-comment">#本地包</span>
+npm i -g myRulePkg &amp;&amp; anyproxy --rule myRulePkg <span class="hljs-comment">#全局包</span></code></pre></li>
+</ul>
+<h2 id="规则接口文档"><a class="header-link" href="#规则接口文档"></a>规则接口文档</h2>
+<p>规则模块应该符合cmd规范,一个典型的规则模块代码结构如下。模块中所有方法都是可选的,只需实现业务感兴趣的部分即可。</p>
+<pre class="hljs"><code><span class="hljs-built_in">module</span>.exports = {
+  <span class="hljs-comment">// 模块介绍</span>
+  summary: <span class="hljs-string">'my customized rule for AnyProxy'</span>, 
+  <span class="hljs-comment">// 发送请求前拦截处理</span>
+  *beforeSendRequest(requestDetail) { <span class="hljs-comment">/* ... */</span> }, 
+  <span class="hljs-comment">// 发送响应前处理</span>
+  *beforeSendResponse(requestDetail, responseDetail) { <span class="hljs-comment">/* ... */</span> }, 
+  <span class="hljs-comment">// 是否处理https请求</span>
+  *beforeDealHttpsRequest(requestDetail) { <span class="hljs-comment">/* ... */</span> }, 
+  <span class="hljs-comment">// 请求出错的事件</span>
+  *onError(requestDetail, error) { <span class="hljs-comment">/* ... */</span> }, 
+  <span class="hljs-comment">// https连接服务器出错</span>
+  *onConnectError(requestDetail, error) { <span class="hljs-comment">/* ... */</span> } 
+};</code></pre><blockquote>
+<p>规则文件中,除了summary,都是由 <a href="https://www.npmjs.com/package/co">co</a> 驱动的,函数需要满足yieldable。可以返回promise或使用generator函数。</p>
+</blockquote>
+<h3 id="summary"><a class="header-link" href="#summary"></a>summary</h3>
+<h4 id="summary-1"><a class="header-link" href="#summary-1"></a>summary</h4>
+<ul class="list">
+<li>规则模块的介绍文案,用于AnyProxy提示用户</li>
+</ul>
+<h3 id="beforesendrequest"><a class="header-link" href="#beforesendrequest"></a>beforeSendRequest</h3>
+<h4 id="beforesendrequest(requestdetail)"><a class="header-link" href="#beforesendrequest(requestdetail)"></a>beforeSendRequest(requestDetail)</h4>
+<ul class="list">
+<li>AnyProxy向服务端发送请求前,会调用<code>beforeSendRequest</code>,并带上参数<code>requestDetail</code></li>
+<li><code>requestDetail</code> <ul class="list">
+<li><code>protocol</code> {string} 请求使用的协议,http或者https</li>
+<li><code>requestOptions</code> {object} 即将发送的请求配置,供require(&#39;http&#39;).request作为使用。详见:<a href="https://nodejs.org/api/http.html#http_http_request_options_callback">https://nodejs.org/api/http.html#http_http_request_options_callback</a></li>
+<li><code>requestData</code> {object} 请求Body</li>
+<li><code>url</code> {string} 请求url</li>
+<li><code>_req</code> {object} 请求的原始request</li>
+</ul>
+</li>
+<li><p>举例:请求 <em>anyproxy.io</em> 时,<code>requestDetail</code>参数内容大致如下</p>
+<pre class="hljs"><code>{
+  <span class="hljs-attr">protocol</span>: <span class="hljs-string">'http'</span>,
+  <span class="hljs-attr">url</span>: <span class="hljs-string">'http://anyproxy.io/'</span>,
+  <span class="hljs-attr">requestOptions</span>: {
+    <span class="hljs-attr">hostname</span>: <span class="hljs-string">'anyproxy.io'</span>,
+    <span class="hljs-attr">port</span>: <span class="hljs-number">80</span>,
+    <span class="hljs-attr">path</span>: <span class="hljs-string">'/'</span>,
+    <span class="hljs-attr">method</span>: <span class="hljs-string">'GET'</span>,
+    <span class="hljs-attr">headers</span>: {
+      <span class="hljs-attr">Host</span>: <span class="hljs-string">'anyproxy.io'</span>,
+      <span class="hljs-string">'Proxy-Connection'</span>: <span class="hljs-string">'keep-alive'</span>,
+      <span class="hljs-string">'User-Agent'</span>: <span class="hljs-string">'...'</span>
+    }
+  },
+  <span class="hljs-attr">requestData</span>: <span class="hljs-string">'...'</span>,
+  <span class="hljs-attr">_req</span>: { <span class="hljs-comment">/* ... */</span>}
+}</code></pre></li>
+<li><p>以下几种返回都是合法的</p>
+<ul class="list">
+<li>不做任何处理,返回null</li>
+</ul>
+<pre class="hljs"><code><span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;</code></pre><ul class="list">
+<li>修改请求协议,如强制改用https发起请求</li>
+</ul>
+<pre class="hljs"><code><span class="hljs-keyword">return</span> {
+  <span class="hljs-attr">protocol</span>: <span class="hljs-string">'https'</span>
+};</code></pre><ul class="list">
+<li>修改请求参数</li>
+</ul>
+<pre class="hljs"><code><span class="hljs-keyword">var</span> newOption = <span class="hljs-built_in">Object</span>.assign({}, requestDetail.requestOptions);
+newOption.path = <span class="hljs-string">'/redirect/to/another/path'</span>;
+<span class="hljs-keyword">return</span> {
+  <span class="hljs-attr">requestOptions</span>: newOption
+};</code></pre><ul class="list">
+<li>修改请求body</li>
+</ul>
+<pre class="hljs"><code><span class="hljs-keyword">return</span> {
+  <span class="hljs-attr">requestData</span>: <span class="hljs-string">'my new request data'</span>
+  <span class="hljs-comment">//这里也可以同时加上requestOptions</span>
+};</code></pre><ul class="list">
+<li>直接返回客户端,不再发起请求,其中<code>statusCode</code> <code>header</code> 是必选字段</li>
+</ul>
+<pre class="hljs"><code><span class="hljs-keyword">return</span> {
+  <span class="hljs-attr">response</span>: {
+    <span class="hljs-attr">statusCode</span>: <span class="hljs-number">200</span>,
+    <span class="hljs-attr">header</span>: { <span class="hljs-string">'content-type'</span>: <span class="hljs-string">'text/html'</span> },
+    <span class="hljs-attr">body</span>: <span class="hljs-string">'this could be a &lt;string&gt; or &lt;buffer&gt;'</span>
+  }
+};</code></pre></li>
+</ul>
+<h3 id="beforesendresponse"><a class="header-link" href="#beforesendresponse"></a>beforeSendResponse</h3>
+<h4 id="beforesendresponse(requestdetail,-responsedetail)"><a class="header-link" href="#beforesendresponse(requestdetail,-responsedetail)"></a>beforeSendResponse(requestDetail, responseDetail)</h4>
+<ul class="list">
+<li>AnyProxy向客户端发送请求前,会调用<code>beforeSendResponse</code>,并带上参数<code>requestDetail</code> <code>responseDetail</code></li>
+<li><code>requestDetail</code> 同<code>beforeSendRequest</code>中的参数</li>
+<li><code>responseDetail</code> <ul class="list">
+<li><code>response</code> {object} 服务端的返回信息,包括<code>statusCode</code> <code>header</code> <code>body</code>三个字段</li>
+<li><code>_res</code> {object} 原始的服务端返回对象</li>
+</ul>
+</li>
+<li><p>举例,请求 <em>anyproxy.io</em> 时,<code>responseDetail</code>参数内容大致如下</p>
+<pre class="hljs"><code>{ 
+  <span class="hljs-attr">response</span>: { 
+    <span class="hljs-attr">statusCode</span>: <span class="hljs-number">200</span>,
+    <span class="hljs-attr">header</span>: { 
+      <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'image/gif'</span>,
+      <span class="hljs-attr">Connection</span>: <span class="hljs-string">'close'</span>,
+      <span class="hljs-string">'Cache-Control'</span>: <span class="hljs-string">'...'</span>
+    },
+    <span class="hljs-attr">body</span>: <span class="hljs-string">'...'</span>
+  },
+  <span class="hljs-attr">_res</span>: { <span class="hljs-comment">/* ... */</span> }
+}</code></pre></li>
+<li><p>以下几种返回都是合法的</p>
+<ul class="list">
+<li>不做任何处理,返回null</li>
+</ul>
+<pre class="hljs"><code><span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;</code></pre><ul class="list">
+<li>修改返回的状态码</li>
+</ul>
+<pre class="hljs"><code><span class="hljs-keyword">var</span> newResponse = <span class="hljs-built_in">Object</span>.assign({}, responseDetail.reponse);
+newResponse.statusCode = <span class="hljs-number">404</span>;
+<span class="hljs-keyword">return</span> {
+  <span class="hljs-attr">response</span>: newResponse
+};</code></pre><ul class="list">
+<li>修改返回的内容</li>
+</ul>
+<pre class="hljs"><code><span class="hljs-keyword">var</span> newResponse = <span class="hljs-built_in">Object</span>.assign({}, responseDetail.reponse);
+newResponse.body += <span class="hljs-string">'--from anyproxy--'</span>;
+<span class="hljs-keyword">return</span> {
+  <span class="hljs-attr">response</span>: newResponse
+};</code></pre></li>
+</ul>
+<h3 id="beforedealhttpsrequest"><a class="header-link" href="#beforedealhttpsrequest"></a>beforeDealHttpsRequest</h3>
+<h4 id="beforedealhttpsrequest(requestdetail)"><a class="header-link" href="#beforedealhttpsrequest(requestdetail)"></a>beforeDealHttpsRequest(requestDetail)</h4>
+<ul class="list">
+<li>AnyProxy收到https请求时,会调用<code>beforeDealHttpsRequest</code>,并带上参数<code>requestDetail</code></li>
+<li>如果配置了全局解析https的参数,则AnyProxy会略过这个调用</li>
+<li>只有返回<code>true</code>时,AnyProxy才会尝试替换证书、解析https。否则只做数据流转发,无法看到明文数据。</li>
+<li>注意:https over http的代理模式中,这里的request是CONNECT请求</li>
+<li><code>requestDetail</code><ul class="list">
+<li><code>host</code> {string} 请求目标的Host,受制于协议,这里无法获取完整url</li>
+<li><code>_req</code> {object} 请求的原始request</li>
+</ul>
+</li>
+<li>返回值<ul class="list">
+<li><code>true</code>或者<code>false</code>,表示是否需要AnyProxy替换证书并解析https</li>
+</ul>
+</li>
+</ul>
+<h3 id="onerror"><a class="header-link" href="#onerror"></a>onError</h3>
+<h4 id="onerror(requestdetail,-error)"><a class="header-link" href="#onerror(requestdetail,-error)"></a>onError(requestDetail, error)</h4>
+<ul class="list">
+<li>在请求处理过程中发生错误时,AnyProxy会调用<code>onError</code>方法,并提供对应的错误信息</li>
+<li>多数场景下,错误会在请求目标服务器的时候发生,比如DNS解析失败、请求超时等</li>
+<li><code>requestDetail</code> 同<code>beforeSendRequest</code>中的参数</li>
+<li><p>以下几种返回都是合法的</p>
+<ul class="list">
+<li>不做任何处理。此时AnyProxy会返回一个默认的错误页。</li>
+</ul>
+<pre class="hljs"><code><span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;</code></pre><ul class="list">
+<li>返回自定义错误页</li>
+</ul>
+<pre class="hljs"><code><span class="hljs-keyword">return</span> {
+  <span class="hljs-attr">response</span>: {
+    <span class="hljs-attr">statusCode</span>: <span class="hljs-number">200</span>,
+    <span class="hljs-attr">header</span>: { <span class="hljs-string">'content-type'</span>: <span class="hljs-string">'text/html'</span> },
+    <span class="hljs-attr">body</span>: <span class="hljs-string">'this could be a &lt;string&gt; or &lt;buffer&gt;'</span>
+  }
+};</code></pre></li>
+</ul>
+<h3 id="onconnecterror"><a class="header-link" href="#onconnecterror"></a>onConnectError</h3>
+<h4 id="onconnecterror(requestdetail,-error)"><a class="header-link" href="#onconnecterror(requestdetail,-error)"></a>onConnectError(requestDetail, error)</h4>
+<ul class="list">
+<li>AnyProxy在与目标HTTPS服务器建立连接的过程中,如果发生错误,AnyProxy会调用这个方法</li>
+<li><code>requestDetail</code> 同<code>beforeDealHttpsRequest</code>中的参数</li>
+<li>此处无法控制向客户端的返回信息,无需返回值。</li>
+</ul>
+<h3 id="faq"><a class="header-link" href="#faq"></a>FAQ</h3>
+<ul class="list">
+<li>Q: 为什么https请求不能进入处理函数?</li>
+<li><p>A: 以下任意一项都能用来改变https的处理特性:</p>
+<ol class="list">
+<li>命令行启动AnyProxy时配置<code>--intercept</code>参数,按npm模块启动时配置<code>forceProxyHttps</code>参数,所有Https请求都会被替换证书并解析</li>
+<li>规则文件内提供<code>beforeDealHttpsRequest</code>方法,返回 <em>true</em> 的https请求会被解析</li>
+</ol>
+</li>
+<li><p>Q: 提示 <em>function is not yieldable</em></p>
+</li>
+<li>A: 规则模块是用 <a href="https://www.npmjs.com/package/co">co</a> 驱动的,函数需要满足yieldable。可以使用generator方法或是返回Promise。</li>
+</ul>
+<h2 id="规则模块样例"><a class="header-link" href="#规则模块样例"></a>规则模块样例</h2>
+<ul class="list">
+<li>这里提供一些样例,来讲解规则模块的常见用法</li>
+<li>你可以通过 <code>anyproxy --rule http://....js</code> 来加载模块并体验</li>
+<li>用curl发请求测试的方法如下<ul class="list">
+<li>直接请求服务器:<code>curl http://httpbin.org/</code></li>
+<li>通过代理服务器请求:<code>curl http://httpbin.org/ --proxy http://127.0.0.1:8001</code></li>
+</ul>
+</li>
+</ul>
+<h3 id="使用本地数据"><a class="header-link" href="#使用本地数据"></a>使用本地数据</h3>
+<ul class="list">
+<li>拦截发送到 <a href="http://httpbin.org">http://httpbin.org</a> 的请求,使用本地数据代替服务端返回</li>
+</ul>
+<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_use_local_response.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
+  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
+*/</span>
+<span class="hljs-built_in">module</span>.exports = {
+  *beforeSendRequest(requestDetail) {
+    <span class="hljs-keyword">const</span> localResponse = {
+      <span class="hljs-attr">statusCode</span>: <span class="hljs-number">200</span>,
+      <span class="hljs-attr">header</span>: { <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'application/json'</span> },
+      <span class="hljs-attr">body</span>: <span class="hljs-string">'{"hello": "this is local response"}'</span>
+    };
+    <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org'</span>) === <span class="hljs-number">0</span>) {
+      <span class="hljs-keyword">return</span> {
+        <span class="hljs-attr">response</span>: localResponse
+      };
+    }
+  },
+};</code></pre><h3 id="修改请求头"><a class="header-link" href="#修改请求头"></a>修改请求头</h3>
+<ul class="list">
+<li>修改发送到 httpbin.org 的user-agent</li>
+</ul>
+<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_request_header.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
+  sample: 
+    modify the user-agent in requests toward httpbin.org
+  test:
+    curl http://httpbin.org/user-agent --proxy http://127.0.0.1:8001
+*/</span>
+<span class="hljs-built_in">module</span>.exports = {
+  *beforeSendRequest(requestDetail) {
+    <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org'</span>) === <span class="hljs-number">0</span>) {
+      <span class="hljs-keyword">const</span> newRequestOptions = requestDetail.requestOptions;
+      newRequestOptions.headers[<span class="hljs-string">'User-Agent'</span>] = <span class="hljs-string">'AnyProxy/0.0.0'</span>;
+      <span class="hljs-keyword">return</span> {
+        <span class="hljs-attr">requestOptions</span>: newRequestOptions
+      };
+    }
+  },
+};</code></pre><h3 id="修改请求数据"><a class="header-link" href="#修改请求数据"></a>修改请求数据</h3>
+<ul class="list">
+<li>修改发送到 <a href="http://httpbin.org/post">http://httpbin.org/post</a> 的post数据</li>
+</ul>
+<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_request_data.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
+  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" }
+*/</span>
+<span class="hljs-built_in">module</span>.exports = {
+  *beforeSendRequest(requestDetail) {
+    <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org/post'</span>) === <span class="hljs-number">0</span>) {
+      <span class="hljs-keyword">return</span> {
+        <span class="hljs-attr">requestData</span>: <span class="hljs-string">'i-am-anyproxy-modified-post-data'</span>
+      };
+    }
+  },
+};</code></pre><h3 id="修改请求的目标地址"><a class="header-link" href="#修改请求的目标地址"></a>修改请求的目标地址</h3>
+<ul class="list">
+<li>把所有发送到 <a href="http://httpbin.org/">http://httpbin.org/</a> 的请求全部改到 <a href="http://httpbin.org/user-agent">http://httpbin.org/user-agent</a></li>
+</ul>
+<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_request_path.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
+  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" }
+*/</span>
+<span class="hljs-built_in">module</span>.exports = {
+  *beforeSendRequest(requestDetail) {
+    <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org'</span>) === <span class="hljs-number">0</span>) {
+      <span class="hljs-keyword">const</span> newRequestOptions = requestDetail.requestOptions;
+      newRequestOptions.path = <span class="hljs-string">'/user-agent'</span>;
+      newRequestOptions.method = <span class="hljs-string">'GET'</span>;
+      <span class="hljs-keyword">return</span> {
+        <span class="hljs-attr">requestOptions</span>: newRequestOptions
+      };
+    }
+  },
+};</code></pre><h3 id="修改请求协议"><a class="header-link" href="#修改请求协议"></a>修改请求协议</h3>
+<ul class="list">
+<li>把用http协议请求的 <a href="http://httpbin.org">http://httpbin.org</a> 改成https并发送</li>
+</ul>
+<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_request_protocol.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
+  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" }
+*/</span>
+<span class="hljs-built_in">module</span>.exports = {
+  *beforeSendRequest(requestDetail) {
+    <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org'</span>) === <span class="hljs-number">0</span>) {
+      <span class="hljs-keyword">const</span> newOption = requestDetail.requestOptions;
+      newOption.port = <span class="hljs-number">443</span>;
+      <span class="hljs-keyword">return</span> {
+        <span class="hljs-attr">protocol</span>: <span class="hljs-string">'https'</span>,
+        <span class="hljs-attr">requestOptions</span>: newOption
+      };
+    }
+  }
+};</code></pre><h3 id="修改返回状态码"><a class="header-link" href="#修改返回状态码"></a>修改返回状态码</h3>
+<ul class="list">
+<li>把 所有<a href="http://httpbin.org">http://httpbin.org</a> 的返回状态码都改成404</li>
+</ul>
+<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_response_statuscode.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
+  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
+*/</span>
+<span class="hljs-built_in">module</span>.exports = {
+  *beforeSendResponse(requestDetail, responseDetail) {
+    <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org'</span>) === <span class="hljs-number">0</span>) {
+      <span class="hljs-keyword">const</span> newResponse = responseDetail.response;
+      newResponse.statusCode = <span class="hljs-number">404</span>;
+      <span class="hljs-keyword">return</span> {
+        <span class="hljs-attr">response</span>: newResponse
+      };
+    }
+  }
+};</code></pre><h3 id="修改返回头"><a class="header-link" href="#修改返回头"></a>修改返回头</h3>
+<ul class="list">
+<li>在 <a href="http://httpbin.org/user-agent">http://httpbin.org/user-agent</a> 的返回头里加上 X-Proxy-By:AnyProxy</li>
+</ul>
+<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_response_header.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
+  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
+*/</span>
+<span class="hljs-built_in">module</span>.exports = {
+  *beforeSendResponse(requestDetail, responseDetail) {
+    <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org/user-agent'</span>) === <span class="hljs-number">0</span>) {
+      <span class="hljs-keyword">const</span> newResponse = responseDetail.response;
+      newResponse.header[<span class="hljs-string">'X-Proxy-By'</span>] = <span class="hljs-string">'AnyProxy'</span>;
+      <span class="hljs-keyword">return</span> {
+        <span class="hljs-attr">response</span>: newResponse
+      };
+    }
+  }
+};</code></pre><h3 id="修改返回内容并延迟"><a class="header-link" href="#修改返回内容并延迟"></a>修改返回内容并延迟</h3>
+<ul class="list">
+<li>在 <a href="http://httpbin.org/user-agent">http://httpbin.org/user-agent</a> 的返回最后追加AnyProxy的签名,并延迟5秒</li>
+</ul>
+<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_response_data.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
+  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! --
+*/</span>
+
+<span class="hljs-built_in">module</span>.exports = {
+  *beforeSendResponse(requestDetail, responseDetail) {
+    <span class="hljs-keyword">if</span> (requestDetail.url === <span class="hljs-string">'http://httpbin.org/user-agent'</span>) {
+      <span class="hljs-keyword">const</span> newResponse = responseDetail.response;
+      newResponse.body += <span class="hljs-string">'-- AnyProxy Hacked! --'</span>;
+      <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =&gt;</span> {
+        setTimeout(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> { <span class="hljs-comment">// delay the response for 5s</span>
+          resolve({ <span class="hljs-attr">response</span>: newResponse });
+        }, <span class="hljs-number">5000</span>);
+      });
+    }
+  },
+};</code></pre><h2 id="作为npm模块使用"><a class="header-link" href="#作为npm模块使用"></a>作为npm模块使用</h2>
+<p>AnyProxy可以作为一个npm模块使用,整合进其他工具。</p>
+<blockquote>
+<p>如要启用https解析,请在代理服务器启动前自行调用<code>AnyProxy.utils.certMgr</code>相关方法生成证书,并引导用户信任安装。或引导用户使用<code>anyproxy-ca</code>方法。</p>
+</blockquote>
+<ul class="list">
+<li>引入</li>
+</ul>
+<pre class="hljs"><code>npm i anyproxy@beta --save <span class="hljs-comment"># 4.0版正在beta中</span></code></pre><ul class="list">
+<li>使用举例</li>
+</ul>
+<pre class="hljs"><code><span class="hljs-keyword">const</span> AnyProxy = <span class="hljs-built_in">require</span>(<span class="hljs-string">'anyproxy'</span>);
+<span class="hljs-keyword">const</span> options = {
+  <span class="hljs-attr">port</span>: <span class="hljs-number">8001</span>,
+  <span class="hljs-attr">rule</span>: <span class="hljs-built_in">require</span>(<span class="hljs-string">'myRuleModule'</span>),
+  <span class="hljs-attr">webInterface</span>: {
+    <span class="hljs-attr">enable</span>: <span class="hljs-literal">true</span>,
+    <span class="hljs-attr">webPort</span>: <span class="hljs-number">8002</span>,
+    <span class="hljs-attr">wsPort</span>: <span class="hljs-number">8003</span>,
+  },
+  <span class="hljs-attr">throttle</span>: <span class="hljs-number">10000</span>,
+  <span class="hljs-attr">forceProxyHttps</span>: <span class="hljs-literal">false</span>,
+  <span class="hljs-attr">silent</span>: <span class="hljs-literal">false</span>
+};
+<span class="hljs-keyword">const</span> proxyServer = <span class="hljs-keyword">new</span> AnyProxy.ProxyServer(options);
+
+proxyServer.on(<span class="hljs-string">'ready'</span>, () =&gt; { <span class="hljs-comment">/* */</span> });
+proxyServer.on(<span class="hljs-string">'error'</span>, (e) =&gt; { <span class="hljs-comment">/* */</span> });
+proxyServer.start();
+
+<span class="hljs-comment">//when finished</span>
+proxyServer.close();</code></pre><ul class="list">
+<li><p>Class: AnyProxy.proxyServer</p>
+<ul class="list">
+<li><p>创建代理服务器</p>
+<pre class="hljs"><code><span class="hljs-keyword">const</span> proxy = <span class="hljs-keyword">new</span> AnyProxy.proxyServer(options)</code></pre></li>
+<li><p><code>options</code></p>
+<ul class="list">
+<li><code>port</code> {number} 必选,代理服务器端口</li>
+<li><code>rule</code> {object} 自定义规则模块</li>
+<li><code>throttle</code> {number} 限速值,单位kb/s,默认不限速</li>
+<li><code>forceProxyHttps</code> {boolean} 是否强制拦截所有的https,忽略规则模块的返回,默认<code>false</code></li>
+<li><code>silent</code> {boolean} 是否屏蔽所有console输出,默认<code>false</code></li>
+<li><code>dangerouslyIgnoreUnauthorized</code> {boolean} 是否忽略请求中的证书错误,默认<code>false</code></li>
+<li><code>webInterface</code> {object} web版界面配置<ul class="list">
+<li><code>enable</code> {boolean} 是否启用web版界面,默认<code>false</code></li>
+<li><code>webPort</code> {number} web版界面端口号,默认<code>8002</code></li>
+</ul>
+</li>
+</ul>
+</li>
+<li><p>Event: <code>ready</code></p>
+<ul class="list">
+<li>代理服务器启动完成</li>
+<li>示例</li>
+</ul>
+<pre class="hljs"><code>proxy.on(<span class="hljs-string">'ready'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{ })</code></pre></li>
+<li><p>Event: <code>error</code></p>
+<ul class="list">
+<li>代理服务器发生错误</li>
+<li>示例</li>
+</ul>
+<pre class="hljs"><code>proxy.on(<span class="hljs-string">'error'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{ })</code></pre></li>
+<li><p>Method: <code>start</code></p>
+<ul class="list">
+<li>启动代理服务器</li>
+<li>示例</li>
+</ul>
+<pre class="hljs"><code>proxy.start();</code></pre></li>
+<li><p>Method: <code>close</code></p>
+<ul class="list">
+<li>关闭代理服务器</li>
+<li>示例</li>
+</ul>
+<pre class="hljs"><code>proxy.close();</code></pre></li>
+</ul>
+</li>
+<li><p>AnyProxy.utils.systemProxyMgr</p>
+<ul class="list">
+<li>管理系统的全局代理配置,方法调用时可能会弹出密码框</li>
+<li>使用示例</li>
+</ul>
+<pre class="hljs"><code><span class="hljs-comment">// 配置127.0.0.1:8001为全局http代理服务器</span>
+AnyProxy.utils.systemProxyMgr.enableGlobalProxy(<span class="hljs-string">'127.0.0.1'</span>, <span class="hljs-string">'8001'</span>);    
+
+<span class="hljs-comment">// 关闭全局代理服务器</span>
+AnyProxy.utils.systemProxyMgr.disableGlobalProxy();</code></pre></li>
+<li><p>AnyProxy.utils.certMgr</p>
+<ul class="list">
+<li>管理AnyProxy的证书</li>
+<li><code>AnyProxy.utils.certMgr.ifRootCAFileExists()</code><ul class="list">
+<li>校验系统内是否存在AnyProxy的根证书</li>
+</ul>
+</li>
+<li><code>AnyProxy.utils.certMgr.generateRootCA(callback)</code><ul class="list">
+<li>生成AnyProxy的rootCA,完成后请引导用户信任.crt文件</li>
+</ul>
+</li>
+<li>样例</li>
+</ul>
+<pre class="hljs"><code>  <span class="hljs-keyword">const</span> AnyProxy = <span class="hljs-built_in">require</span>(<span class="hljs-string">'AnyProxy'</span>);
+  <span class="hljs-keyword">const</span> exec = <span class="hljs-built_in">require</span>(<span class="hljs-string">'child_process'</span>).exec;
+
+  <span class="hljs-keyword">if</span> (!AnyProxy.utils.certMgr.ifRootCAFileExists()) {
+    AnyProxy.utils.certMgr.generateRootCA(<span class="hljs-function">(<span class="hljs-params">error, keyPath</span>) =&gt;</span> {
+      <span class="hljs-comment">// let users to trust this CA before using proxy</span>
+      <span class="hljs-keyword">if</span> (!error) {
+        <span class="hljs-keyword">const</span> certDir = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>).dirname(keyPath);
+        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'The cert is generated at'</span>, certDir);
+        <span class="hljs-keyword">const</span> isWin = <span class="hljs-regexp">/^win/</span>.test(process.platform);
+        <span class="hljs-keyword">if</span> (isWin) {
+          exec(<span class="hljs-string">'start .'</span>, { <span class="hljs-attr">cwd</span>: certDir });
+        } <span class="hljs-keyword">else</span> {
+          exec(<span class="hljs-string">'open .'</span>, { <span class="hljs-attr">cwd</span>: certDir });
+        }
+      } <span class="hljs-keyword">else</span> {
+        <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'error when generating rootCA'</span>, error);
+      }
+    });
+  }</code></pre></li>
+</ul>
+<h2 id="关于anyproxy"><a class="header-link" href="#关于anyproxy"></a>关于AnyProxy</h2>
+<ul class="list">
+<li>AnyProxy是支付宝前端团队推出的开源产品</li>
+<li>Change Log: <a href="https://github.com/alibaba/anyproxy/blob/master/CHANGELOG">https://github.com/alibaba/anyproxy/blob/master/CHANGELOG</a></li>
+<li>代码库:<a href="https://github.com/alibaba/anyproxy">https://github.com/alibaba/anyproxy</a></li>
+<li>issue反馈:<a href="https://github.com/alibaba/anyproxy/issues">https://github.com/alibaba/anyproxy/issues</a></li>
+</ul>
+<h2 id="配置帮助"><a class="header-link" href="#配置帮助"></a>配置帮助</h2>
+<h3 id="osx系统信任ca证书"><a class="header-link" href="#osx系统信任ca证书"></a>OSX系统信任CA证书</h3>
+<ul class="list">
+<li>类似这种报错都是因为系统没有信任AnyProxy生成的CA所造成的</li>
+</ul>
+<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/CBkLGYgvoHAYwNVAYkpk.png" width="450" /></p>
+<blockquote>
+<p>警告:CA证书和系统安全息息相关,建议亲自生成,并妥善保管</p>
+</blockquote>
+<p>安装CA:</p>
+<ul class="list">
+<li><p>双击打开<em>rootCA.crt</em></p>
+</li>
+<li><p>确认将证书添加到login或system</p>
+</li>
+</ul>
+<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/bCwNUFFpvsmVuljQKrIk.png" width="350" /></p>
+<ul class="list">
+<li>找到刚刚导入的AnyProxy证书,配置为信任(Always Trust)</li>
+</ul>
+<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/HOmEElNGdoZEWFMLsTNT.png" width="700" /></p>
+<h3 id="windows系统信任ca证书"><a class="header-link" href="#windows系统信任ca证书"></a>Windows系统信任CA证书</h3>
+<p class="img-container"><img src="https://t.alipayobjects.com/tfscom/T1D3hfXeFtXXXXXXXX.jpg" width="700" /></p>
+<h3 id="配置osx系统代理"><a class="header-link" href="#配置osx系统代理"></a>配置OSX系统代理</h3>
+<ul class="list">
+<li>在wifi高级设置中,配置http代理即可</li>
+</ul>
+<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/vduwhobSTypTfgniBvoa.png" width="500" /></p>
+<h3 id="配置浏览器http代理"><a class="header-link" href="#配置浏览器http代理"></a>配置浏览器HTTP代理</h3>
+<ul class="list">
+<li>以Chrome的<a href="https://chrome.google.com/webstore/detail/padekgcemlokbadohgkifijomclgjgif">SwitchyOmega插件</a>为例</li>
+</ul>
+<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/jIPZrKmqXRaSledQeJUJ.png" width="500" /></p>
+<h3 id="ios系统信任ca证书"><a class="header-link" href="#ios系统信任ca证书"></a>iOS系统信任CA证书</h3>
+<ul class="list">
+<li>点击web ui中的 <em>Root CA</em>,按提示扫描二维码即可安装</li>
+</ul>
+<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/BrugmMelGVysLDOIBblj.png" width="260" /></p>
+<h3 id="ios->=-10.3信任ca证书"><a class="header-link" href="#ios->=-10.3信任ca证书"></a>iOS &gt;= 10.3信任CA证书</h3>
+<ul class="list">
+<li>除了上述证书安装过程,还需要在 <em>设置-&gt;通用-&gt;证书信任设置</em> 中把AnyProxy证书的开关打开,否则safari将报错。</li>
+</ul>
+<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/hVWkXHrzHmOKOtCKGUWx.png" width="500" /></p>
+<h3 id="配置ios/android系统代理"><a class="header-link" href="#配置ios/android系统代理"></a>配置iOS/Android系统代理</h3>
+<ul class="list">
+<li><p>代理服务器都在wifi设置中配置</p>
+</li>
+<li><p>iOS HTTP代理配置</p>
+</li>
+</ul>
+<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/tLGqIozhffTccUgPakuw.png" width="260" /></p>
+<ul class="list">
+<li>Android HTTP代理配置</li>
+</ul>
+<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/YQtbQYVNuOszZGdAOauU.png" width="260" /></p>
+    </div>
+  </article>
+
+  <script src="//cdn.bootcss.com/zepto/1.2.0/zepto.min.js"></script>
+  <script>
+  window.onload = function(){
+    var itemList = [];
+    var targetMap = {};
+    $("[id]", ".main-content").map(function (index, heading) {
+      targetMap[heading.getAttribute('id')] = heading;
+    });
+
+    $("#j_toc li").map(function (index, item) {
+      if (item.className.indexOf('sidebar-header-2') >= 0 || item.className.indexOf('sidebar-header-3') >= 0) {
+        var targetName = item.firstChild.getAttribute('href').replace('#', '');
+        var targetItem = targetMap[targetName];
+        itemList.push({ target: targetItem, tocItem: item, top: $(targetItem).position().top });
+      }
+    });
+
+    var updateTocActive = function (e) {
+      var windowHeight = window.innerHeight;
+      //find the first item to match
+      var scrollYThres = window.scrollY + 200;
+      var target;
+      if (scrollYThres < 100) {
+        target = itemList[0].tocItem;
+      } else {
+        itemList.forEach(function (item, index) {
+          if (target) return;
+          if (index > 0) {
+            if (item.top >= scrollYThres) {
+              target = itemList[index - 1].tocItem;
+            }
+          }
+        });
+      }
+
+      $('.toc-active').removeClass('toc-active');
+      $(target).addClass('toc-active');
+    };
+
+    window.onscroll = updateTocActive;
+    updateTocActive();
+  }
+  </script>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/cn/index.html b/cn/index.html
deleted file mode 100644
index 2676988..0000000
--- a/cn/index.html
+++ /dev/null
@@ -1,248 +0,0 @@
-<html>
-<head>
-    <title>AnyProxy</title>
-    <link rel="stylesheet" type="text/css" href="/dest/index.css">
-    <link rel="shortcut icon" type="image/png" href="/favico.png?t=2" />
-    <meta name="description" content="A fully configurable proxy in NodeJS, which can handle HTTPS requests perfectly.">
-    <meta name="description" content="AnyProxy - 开放式的HTTP/HTTPS代理,你可以灵活控制各种网络数据">
-    <meta name="keywords" content="代理服务器 Proxy HTTP HTTPS">
-    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
-    <script> 
-        //redirect to Chinese version if in China
-        if(new Date().getTimezoneOffset() == "-480" && !(/(cn|en)/i.test(location.href))){
-            location.href = "/cn";
-        }else{
-            var _hmt = _hmt || []; (function() {var hm = document.createElement("script"); hm.src = "//hm.baidu.com/hm.js?4e51565b7d471fd6623c163a8fd79e07"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })();
-        }
-    </script>
-
-</head>
-<body>
-
-    <div class="wrapper">
-        <div class="cornerBtnWrapper">
-            <a href="/cn">中文</a>|
-            <a href="/en">English</a>|
-            <a href="https://github.com/alibaba/anyproxy" target="_blank">View on Github</a>
-        </div>
-
-        <div class="brief">
-            <div class="logo">
-                <img src="http://gtms04.alicdn.com/tps/i4/TB1XfxDHpXXXXXpapXX20ySQVXX-512-512.png" width="250" height="250" alt="anyproxy logo" />
-            </div>
-            <h2 class="slogan">AnyProxy 4.x版正在Beta中,欢迎试用 Ref:<a href="/4.x/">AnyProxy 4.x 文档</a></h2>
-            <div class="action">
-                <iframe src="https://ghbtns.com/github-btn.html?user=alibaba&repo=anyproxy&type=star&count=true" frameborder="0" scrolling="0" width="100px" height="20px"></iframe>&nbsp;&nbsp;&nbsp;
-                <iframe src="https://ghbtns.com/github-btn.html?user=alibaba&repo=anyproxy&type=fork&count=true" frameborder="0" scrolling="0" width="100px" height="20px"></iframe>
-            </div>
-        </div>
-
-        <div class="feature">
-            <div class="featureContent">
-                <div class="item">
-                    <span class="iconWrapper">
-                        <i class="iconfont">&#xe602;</i>
-                    </span>
-                    <h4>基于Node.js</h4>
-                    <h5>全程JavaScript,学习无压力</h5>
-                </div>
-                <div class="item">
-                    <span class="iconWrapper">
-                        <i class="iconfont">&#xe601;</i>
-                    </span>
-                    <h4>支持Https</h4>
-                    <h5>明文解析Https请求数据<a href="https://github.com/alibaba/anyproxy/wiki/HTTPS%E7%9B%B8%E5%85%B3%E6%95%99%E7%A8%8B" target="_blank"><br>如何配置&nbsp;&gt;&gt;</a></h5>
-                </div>
-                <div class="item">
-                    <span class="iconWrapper">
-                        <i class="iconfont bigger">&#xe600;</i>
-                    </span>
-                    <h4>Web界面</h4>
-                    <h5>多终端共享,可视化观察每个请求</h5>
-                </div>
-                <div class="item">
-                    <span class="iconWrapper">
-                        <i class="iconfont">&#xe604;</i>
-                    </span>
-                    <h4>规则逻辑(Rule)</h4>
-                    <h5>个性化处理规则,定制专属调试工具</h5>
-                </div>
-                <div style="clear:both"></div>
-            </div>
-        </div>
-
-        <div class="quickstart listSection">
-            <div class="quickstartContent listContent">
-                <h4 class="subtitle" id="install">安装</h4>
-                <ul>
-                    <li>安装 <a href="http://nodejs.org/" target="_blank">Node.js</a> &gt;= v0.12</li>
-                    <li><code class="simpleBash">npm install -g anyproxy</code>, 可能需要<code class="simpleBash">sudo</code></li>
-                    <li><a href="https://github.com/alibaba/anyproxy#quick-start" target="_blank">More&gt;&gt;</a></li>
-                </ul>
-                <h4 class="subtitle" id="quickstart">使用</h4>
-                <ul>
-                    <li>运行&nbsp;&nbsp;<code class="simpleBash">anyproxy</code></li>
-                    <li>把浏览器http代理指向 127.0.0.1:8001</li>
-                    <li>访问界面:http://127.0.0.1:8002</li>
-                    <li><a href="https://github.com/alibaba/anyproxy#quick-start" target="_blank">更多用法&nbsp;&gt;&gt;</a></li>
-                </ul>
-                <a href="https://github.com/alibaba/anyproxy#step-4---launch-web-interface" target="_blank"><img class="screenshot" src="http://gtms01.alicdn.com/tps/i1/TB1IdgqGXXXXXa9apXXLExM2pXX-854-480.gif" width="350"/></a>
-            </div>
-        </div>
-
-        <div class="sample">
-
-            <div class="sampleContent">
-                <h4 class="subtitle" id="sample ">规则文件(rule)样例</h4>
-
-                <div class="item">
-                    <h5 class="itemTitle">在HTML响应末尾加上&quot;hello world&quot;</h5>
-                    <pre>
-<code class="javascript">
-//append "hello world" to all web pages
-//file : rule_replace_response_data.js
-//run  : anyproxy --rule rule_replace_response_data.js
-module.exports = {
-    replaceServerResDataAsync: function(req,res,serverRes,cb){
-
-        if(/html/i.test(res.headers['content-type'])){
-            var newDataStr = serverRes.toString();
-            newDataStr += "hello world!";
-            cb(newDataStr);
-        }
-    }
-};
-</code>
-                    </pre>
-                    <span class="figure">
-                        <img src="https://t.alipayobjects.com/images/rmsweb/T1LcphXf0eXXXXXXXX.png" width="350"/>
-                    </span>
-                    <hr />
-                </div>              
-                <div class="item">
-                    <h5 class="itemTitle">去除请求头的if-modified-since字段</h5>
-                    <pre>
-<code class="javascript">
-//remove cache related header
-//file : rule_remove_cache_header.js
-//run  : anyproxy --rule rule_remove_cache_header.js
-module.exports = {
-    replaceRequestOption : function(req,option){
-        var newOption = option;
-        delete newOption.headers['if-modified-since'];
-
-        return newOption;
-    }
-};
-</code>
-                    </pre>
-                    <span class="figure">
-                        <img src="https://t.alipayobjects.com/images/rmsweb/T1ecFhXjxcXXXXXXXX.png" width="350"/>
-                    </span>
-                    <hr />
-                </div>
-
-                <div class="item">
-                    <h5 class="itemTitle">为某个请求指定目标IP地址</h5>
-                    <pre>
-<code class="javascript">
-//assign a specific IP adress for some request
-//file : rule_reverse_proxy.js
-//run  : anyproxy --rule anyproxy --rule rule_reverse_proxy.js
-module.exports = {
-    replaceRequestOption : function(req,option){
-        var newOption = option;
-        if(newOption.headers.host == "www.taobao.com"){
-            newOption.hostname = "192.168.1.3";
-            newOption.port     = "80";
-        }
-
-        return newOption;
-    }
-};
-</code>
-                    </pre>
-                    <span class="figure">
-                        <img src="https://t.alipayobjects.com/images/rmsweb/T1hsxhXeddXXXXXXXX.png" width="350"/>
-                    </span>
-                    <hr />
-                </div>
-
-                <div class="item">
-                    <h5 class="itemTitle">把所有图片响应替换成本地图片</h5>
-                    <pre>
-<code class="javascript">
-//replace all the images with local one
-//file : rule_use_local_data.js
-//run  : anyproxy --rule anyproxy --rule rule_use_local_data.js
-var fs  = require("fs"),
-    img = fs.readFileSync("sample.jpg");
-
-module.exports = {
-    shouldUseLocalResponse : function(req,reqBody){
-        if(/\.(png|gif|jpg|jpeg)$/.test(req.url)){
-            req.replaceLocalFile = true;
-            return true;
-        }else{
-            return false;
-        }
-    },
-
-    dealLocalResponse : function(req,reqBody,callback){
-        if(req.replaceLocalFile){
-            callback(200, {"content-type":"image/png"},img );
-        }
-    }
-};
-</code>
-                    </pre>
-                    <span class="figure">
-                        <img src="https://t.alipayobjects.com/images/rmsweb/T1Zr4hXeXhXXXXXXXX.png" width="350"/>
-                    </span>
-                </div>
-
-                <div class="readmoreBtn">
-                    <a href="https://github.com/alibaba/anyproxy/wiki/%E4%BB%A3%E7%90%86%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%9A%84%E6%96%B0%E8%BD%AE%E5%AD%90%EF%BC%9Aanyproxy#%E5%BC%80%E6%94%BE%E5%BC%8F%E4%BB%A3%E7%90%86%E6%9C%8D%E5%8A%A1%E5%99%A8%E8%AE%BE%E8%AE%A1" target="_blank">&gt;&gt;&nbsp;阅读:规则文件(Rule)API</a>
-                </div>
-
-            </div>
-        </div>
-
-        <div class="readMore listSection">
-            <div class="listContent">
-                <h4 class="subtitle" id="otherfeature">其他特性</h4>
-                <ul>
-                    <li>Map Local,Log Filter等常规功能</li>
-                    <li><a href="https://github.com/alibaba/anyproxy#throttling">低网速网速模拟</a>,调试应用在2G/3G下的表现</li>
-                    <li><a href="https://github.com/alibaba/anyproxy#work-as-a-module-for-nodejs" target="_blank">把AnyProxy作为npm模块</a>,基于它做二次开发</li>
-                </ul>
-                <h4 class="subtitle" id="ref">相关阅读</h4>
-                <ul>
-                    <li><a href="https://github.com/alibaba/anyproxy/wiki/%E4%BB%A3%E7%90%86%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%9A%84%E6%96%B0%E8%BD%AE%E5%AD%90%EF%BC%9Aanyproxy" target="_blank">代理服务器的新轮子</a>,介绍AnyProxy的设计初衷,以及它的开放式设计可以解决什么问题。</li>
-                    <li><a href="http://www.infoq.com/cn/presentations/alipay-hybrid-application-quality-assurance-practice" target="_blank">QCon - 《支付宝hybrid应用质量保证实践》</a>,涉及到AnyProxy在测试工程中的应用(By 陈晔)</li>
-                </ul>
-            </div>
-        </div>
-
-        <div class="learnMore listSection">
-            <div class="btnWrapper">
-                <h4 class="subtitle white" id="readmore">Read More</h4>
-                <a class="actionBtn actionBtnWhite" href="https://github.com/alibaba/anyproxy" target="_blank">https://github.com/alibaba/anyproxy</a>
-            </div>
-        </div>
-
-        <div class="footer"></div>
-
-    </div>
-
-    <link rel="stylesheet" type="text/css" href="/dest/github.css" />
-    <script src="/dest/lib.js"></script>
-    <script type="text/javascript">
-        Zepto(document).ready(function() {
-            Zepto('.sample code').each(function(i, block) {
-                hljs.highlightBlock(block);
-            });
-        });
-    </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/dest/github.css b/dest/github.css
deleted file mode 100644
index 791537e..0000000
--- a/dest/github.css
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
-
-github.com style (c) Vasily Polovnyov <vast@whiteants.net>
-
-*/
-
-.hljs {
-  display: block;
-  overflow-x: auto;
-  padding: 0.5em;
-  color: #333;
-  background: #f8f8f8;
-  -webkit-text-size-adjust: none;
-}
-
-.hljs-comment,
-.diff .hljs-header {
-  color: #998;
-  font-style: italic;
-}
-
-.hljs-keyword,
-.css .rule .hljs-keyword,
-.hljs-winutils,
-.nginx .hljs-title,
-.hljs-subst,
-.hljs-request,
-.hljs-status {
-  color: #333;
-  font-weight: bold;
-}
-
-.hljs-number,
-.hljs-hexcolor,
-.ruby .hljs-constant {
-  color: #008080;
-}
-
-.hljs-string,
-.hljs-tag .hljs-value,
-.hljs-doctag,
-.tex .hljs-formula {
-  color: #d14;
-}
-
-.hljs-title,
-.hljs-id,
-.scss .hljs-preprocessor {
-  color: #900;
-  font-weight: bold;
-}
-
-.hljs-list .hljs-keyword,
-.hljs-subst {
-  font-weight: normal;
-}
-
-.hljs-class .hljs-title,
-.hljs-type,
-.vhdl .hljs-literal,
-.tex .hljs-command {
-  color: #458;
-  font-weight: bold;
-}
-
-.hljs-tag,
-.hljs-tag .hljs-title,
-.hljs-rule .hljs-property,
-.django .hljs-tag .hljs-keyword {
-  color: #000080;
-  font-weight: normal;
-}
-
-.hljs-attribute,
-.hljs-variable,
-.lisp .hljs-body,
-.hljs-name {
-  color: #008080;
-}
-
-.hljs-regexp {
-  color: #009926;
-}
-
-.hljs-symbol,
-.ruby .hljs-symbol .hljs-string,
-.lisp .hljs-keyword,
-.clojure .hljs-keyword,
-.scheme .hljs-keyword,
-.tex .hljs-special,
-.hljs-prompt {
-  color: #990073;
-}
-
-.hljs-built_in {
-  color: #0086b3;
-}
-
-.hljs-preprocessor,
-.hljs-pragma,
-.hljs-pi,
-.hljs-doctype,
-.hljs-shebang,
-.hljs-cdata {
-  color: #999;
-  font-weight: bold;
-}
-
-.hljs-deletion {
-  background: #fdd;
-}
-
-.hljs-addition {
-  background: #dfd;
-}
-
-.diff .hljs-change {
-  background: #0086b3;
-}
-
-.hljs-chunk {
-  color: #aaa;
-}
diff --git a/dest/index.css b/dest/index.css
deleted file mode 100644
index fb8d4e1..0000000
--- a/dest/index.css
+++ /dev/null
@@ -1,308 +0,0 @@
-@font-face {
-  font-family: 'iconfont';
-  src: url('//at.alicdn.com/t/font_1440130445_6601267.eot');
-  /* IE9*/
-  src: url('//at.alicdn.com/t/font_1440130445_6601267.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ url('//at.alicdn.com/t/font_1440130445_6601267.woff') format('woff'), /* chrome、firefox */ url('//at.alicdn.com/t/font_1440130445_6601267.ttf') format('truetype'), /* chrome、firefox、opera、Safari, Android, iOS 4.2+*/ url('//at.alicdn.com/t/font_1440130445_6601267.svg#iconfont') format('svg');
-  /* iOS 4.1- */
-}
-i.iconfont {
-  font-family: "iconfont";
-  font-style: normal;
-}
-body {
-  margin: 0;
-  padding: 0;
-  font-family: 'Source Sans Pro', 'Helvetica Neue', Arial, sans-serif;
-  -webkit-font-smoothing: antialiased;
-  -moz-osx-font-smoothing: grayscale;
-}
-.wrapper .cornerBtnWrapper {
-  position: absolute;
-  right: 10px;
-  top: 10px;
-  z-index: 1;
-  width: 100%;
-  text-align: right;
-  color: #5A5A5A;
-}
-.wrapper .cornerBtnWrapper a {
-  display: inline-block;
-  margin-right: 10px;
-  margin-left: 10px;
-}
-.wrapper a,
-.wrapper a:hover {
-  text-decoration: none;
-}
-.wrapper a {
-  font-size: 16px;
-  color: #00AAEE;
-}
-.wrapper h4.subTitle {
-  font-size: 30px;
-  margin: 0;
-  padding: 50px 0 10px 0;
-  width: 100%;
-  text-align: center;
-  color: #5A5A5A;
-}
-.wrapper h4.subTitle.white {
-  color: #FFF;
-}
-.wrapper code {
-  display: inline-block;
-}
-.wrapper .actionBtn.actionBtnWhite {
-  color: #FFF;
-  border: 1px solid #FFF;
-}
-.wrapper .actionBtn.actionBtnWhite:hover {
-  background: #F9F9F9;
-  color: #326EEB;
-}
-.wrapper .actionBtn {
-  color: #326EEB;
-  border: 1px solid #326EEB;
-  line-height: 30px;
-  font-size: 30px;
-  padding: 20px 45px;
-  border-radius: 30px;
-  display: inline-block;
-  transition: 0.3s;
-}
-@media only screen and (min-device-width: 320px) and (max-device-width: 600px) and (-webkit-min-device-pixel-ratio: 2) {
-  .wrapper .actionBtn {
-    font-size: 16px;
-    padding: 10px 20px;
-  }
-}
-.wrapper .actionBtn:hover {
-  background: #326EEB;
-  color: #F9F9F9;
-}
-.wrapper > div {
-  width: 100%;
-  min-width: 890px;
-}
-@media only screen and (min-device-width: 320px) and (max-device-width: 600px) and (-webkit-min-device-pixel-ratio: 2) {
-  .wrapper > div {
-    min-width: 100%;
-  }
-}
-.brief {
-  height: 300px;
-  text-align: center;
-  padding: 100px 0;
-  position: relative;
-  margin-top: 20px;
-}
-@media only screen and (min-device-width: 320px) and (max-device-width: 600px) and (-webkit-min-device-pixel-ratio: 2) {
-  .brief {
-    padding: 60px 0 90px;
-  }
-}
-.brief .slogan {
-  font-size: 16px;
-  color: #5A5A5A;
-  padding: 0 20px;
-}
-.feature {
-  background: #DEDEDE;
-}
-.feature .featureContent {
-  width: 1200px;
-  margin: 0 auto;
-}
-@media only screen and (min-device-width: 320px) and (max-device-width: 600px) and (-webkit-min-device-pixel-ratio: 2) {
-  .feature .featureContent {
-    width: 100%;
-  }
-}
-.feature .featureContent .item {
-  padding: 30px 0 20px;
-  width: 280px;
-  /*border: 1px solid #AAA;*/
-  margin: 0 10px;
-  float: left;
-  box-sizing: border-box;
-  -webkit-box-sizing: border-box;
-  font-size: 30px;
-  text-align: center;
-}
-.feature .featureContent .iconWrapper {
-  display: inline-block;
-  line-height: 40px;
-  width: 70px;
-  text-align: center;
-  font-size: 40px;
-  color: #5A5A5A;
-}
-.feature .featureContent .iconWrapper .bigger {
-  font-size: 44px;
-}
-.feature .featureContent h4 {
-  color: #5A5A5A;
-  margin: 12px auto 2px;
-  font-size: 20px;
-}
-.feature .featureContent h5 {
-  color: #777;
-  margin: 0;
-}
-.feature .featureContent h5,
-.feature .featureContent a {
-  font-size: 14px;
-  line-height: 20px;
-}
-@media only screen and (min-device-width: 320px) and (max-device-width: 600px) and (-webkit-min-device-pixel-ratio: 2) {
-  .feature .featureContent .item {
-    padding: 20px 0;
-    float: none;
-    margin: 0 auto;
-    font-size: 24px;
-  }
-  .feature .featureContent .iconWrapper {
-    font-size: 25px;
-    line-height: 25px;
-  }
-  .feature .featureContent .iconWrapper .bigger {
-    font-size: 30px;
-  }
-  .feature .featureContent h4 {
-    font-size: 16px;
-    margin: 4px;
-  }
-}
-.quickstart {
-  background: #F9F9F9;
-}
-.quickstart .quickstartContent {
-  position: relative;
-}
-.quickstart .screenshot {
-  position: absolute;
-  right: 0;
-  bottom: 0;
-}
-@media only screen and (min-device-width: 320px) and (max-device-width: 600px) and (-webkit-min-device-pixel-ratio: 2) {
-  .quickstart .screenshot {
-    display: none;
-  }
-}
-.quickstart code.simpleBash {
-  font-family: monospace;
-  font-weight: bold;
-  color: #333;
-  padding: 0;
-}
-.listSection .listContent {
-  width: 890px;
-  margin: 0 auto;
-}
-@media only screen and (min-device-width: 320px) and (max-device-width: 600px) and (-webkit-min-device-pixel-ratio: 2) {
-  .listSection .listContent {
-    width: 100%;
-  }
-}
-.listSection ul {
-  margin: 0 auto;
-}
-@media only screen and (min-device-width: 320px) and (max-device-width: 600px) and (-webkit-min-device-pixel-ratio: 2) {
-  .listSection ul {
-    padding: 0 20px 0 30px;
-  }
-}
-.listSection li {
-  color: #5A5A5A;
-  font-size: 16px;
-  line-height: 40px;
-}
-.sample {
-  background: #F9F9F9;
-}
-.sample .sampleContent {
-  width: 890px;
-  margin: 0 auto;
-}
-@media only screen and (min-device-width: 320px) and (max-device-width: 600px) and (-webkit-min-device-pixel-ratio: 2) {
-  .sample .sampleContent {
-    width: 100%;
-  }
-}
-.sample .item {
-  margin: 10px;
-}
-.sample .itemTitle {
-  font-size: 16px;
-  margin: 0px 10px;
-  color: #5A5A5A;
-}
-@media only screen and (min-device-width: 320px) and (max-device-width: 600px) and (-webkit-min-device-pixel-ratio: 2) {
-  .sample .itemTitle {
-    margin: 0;
-  }
-}
-.sample .figure {
-  vertical-align: top;
-}
-@media only screen and (min-device-width: 320px) and (max-device-width: 600px) and (-webkit-min-device-pixel-ratio: 2) {
-  .sample .figure {
-    display: block;
-    margin: 0 auto;
-    text-align: center;
-  }
-}
-.sample pre {
-  margin: 0;
-  display: inline-block;
-  vertical-align: top;
-}
-@media only screen and (min-device-width: 320px) and (max-device-width: 600px) and (-webkit-min-device-pixel-ratio: 2) {
-  .sample pre {
-    width: 100%;
-  }
-}
-.sample code {
-  width: 495px;
-}
-@media only screen and (min-device-width: 320px) and (max-device-width: 600px) and (-webkit-min-device-pixel-ratio: 2) {
-  .sample code {
-    width: 100%;
-    margin: 0 auto;
-    word-wrap: break-word;
-    padding: 0;
-  }
-}
-.sample hr {
-  border: none;
-  border-top: 1px solid #777;
-  width: 80%;
-  margin: 0 auto;
-  padding: 15px 0;
-}
-.sample .readmoreBtn {
-  margin-left: 10px;
-  padding-bottom: 20px;
-}
-.readMore {
-  background: #F9F9F9;
-  padding-bottom: 50px;
-}
-.learnMore {
-  background: #326EEB;
-  text-align: center;
-  position: relative;
-  padding: 120px 0;
-}
-@media only screen and (min-device-width: 320px) and (max-device-width: 600px) and (-webkit-min-device-pixel-ratio: 2) {
-  .learnMore {
-    padding: 70px 0;
-  }
-}
-.learnMore h4.subtitle {
-  padding: 0;
-  margin-bottom: 30px;
-}
-.learnMore .btnWrapper {
-  text-align: center;
-}
diff --git a/dest/lib.js b/dest/lib.js
deleted file mode 100644
index edbc256..0000000
--- a/dest/lib.js
+++ /dev/null
@@ -1,5 +0,0 @@
-/* Zepto v1.1.6 - zepto event ajax form ie - zeptojs.com/license */
-var Zepto=function(){function L(t){return null==t?String(t):j[S.call(t)]||"object"}function Z(t){return"function"==L(t)}function _(t){return null!=t&&t==t.window}function $(t){return null!=t&&t.nodeType==t.DOCUMENT_NODE}function D(t){return"object"==L(t)}function M(t){return D(t)&&!_(t)&&Object.getPrototypeOf(t)==Object.prototype}function R(t){return"number"==typeof t.length}function k(t){return s.call(t,function(t){return null!=t})}function z(t){return t.length>0?n.fn.concat.apply([],t):t}function F(t){return t.replace(/::/g,"/").replace(/([A-Z]+)([A-Z][a-z])/g,"$1_$2").replace(/([a-z\d])([A-Z])/g,"$1_$2").replace(/_/g,"-").toLowerCase()}function q(t){return t in f?f[t]:f[t]=new RegExp("(^|\\s)"+t+"(\\s|$)")}function H(t,e){return"number"!=typeof e||c[F(t)]?e:e+"px"}function I(t){var e,n;return u[t]||(e=a.createElement(t),a.body.appendChild(e),n=getComputedStyle(e,"").getPropertyValue("display"),e.parentNode.removeChild(e),"none"==n&&(n="block"),u[t]=n),u[t]}function V(t){return"children"in t?o.call(t.children):n.map(t.childNodes,function(t){return 1==t.nodeType?t:void 0})}function B(n,i,r){for(e in i)r&&(M(i[e])||A(i[e]))?(M(i[e])&&!M(n[e])&&(n[e]={}),A(i[e])&&!A(n[e])&&(n[e]=[]),B(n[e],i[e],r)):i[e]!==t&&(n[e]=i[e])}function U(t,e){return null==e?n(t):n(t).filter(e)}function J(t,e,n,i){return Z(e)?e.call(t,n,i):e}function X(t,e,n){null==n?t.removeAttribute(e):t.setAttribute(e,n)}function W(e,n){var i=e.className||"",r=i&&i.baseVal!==t;return n===t?r?i.baseVal:i:void(r?i.baseVal=n:e.className=n)}function Y(t){try{return t?"true"==t||("false"==t?!1:"null"==t?null:+t+""==t?+t:/^[\[\{]/.test(t)?n.parseJSON(t):t):t}catch(e){return t}}function G(t,e){e(t);for(var n=0,i=t.childNodes.length;i>n;n++)G(t.childNodes[n],e)}var t,e,n,i,C,N,r=[],o=r.slice,s=r.filter,a=window.document,u={},f={},c={"column-count":1,columns:1,"font-weight":1,"line-height":1,opacity:1,"z-index":1,zoom:1},l=/^\s*<(\w+|!)[^>]*>/,h=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,p=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,d=/^(?:body|html)$/i,m=/([A-Z])/g,g=["val","css","html","text","data","width","height","offset"],v=["after","prepend","before","append"],y=a.createElement("table"),x=a.createElement("tr"),b={tr:a.createElement("tbody"),tbody:y,thead:y,tfoot:y,td:x,th:x,"*":a.createElement("div")},w=/complete|loaded|interactive/,E=/^[\w-]*$/,j={},S=j.toString,T={},O=a.createElement("div"),P={tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},A=Array.isArray||function(t){return t instanceof Array};return T.matches=function(t,e){if(!e||!t||1!==t.nodeType)return!1;var n=t.webkitMatchesSelector||t.mozMatchesSelector||t.oMatchesSelector||t.matchesSelector;if(n)return n.call(t,e);var i,r=t.parentNode,o=!r;return o&&(r=O).appendChild(t),i=~T.qsa(r,e).indexOf(t),o&&O.removeChild(t),i},C=function(t){return t.replace(/-+(.)?/g,function(t,e){return e?e.toUpperCase():""})},N=function(t){return s.call(t,function(e,n){return t.indexOf(e)==n})},T.fragment=function(e,i,r){var s,u,f;return h.test(e)&&(s=n(a.createElement(RegExp.$1))),s||(e.replace&&(e=e.replace(p,"<$1></$2>")),i===t&&(i=l.test(e)&&RegExp.$1),i in b||(i="*"),f=b[i],f.innerHTML=""+e,s=n.each(o.call(f.childNodes),function(){f.removeChild(this)})),M(r)&&(u=n(s),n.each(r,function(t,e){g.indexOf(t)>-1?u[t](e):u.attr(t,e)})),s},T.Z=function(t,e){return t=t||[],t.__proto__=n.fn,t.selector=e||"",t},T.isZ=function(t){return t instanceof T.Z},T.init=function(e,i){var r;if(!e)return T.Z();if("string"==typeof e)if(e=e.trim(),"<"==e[0]&&l.test(e))r=T.fragment(e,RegExp.$1,i),e=null;else{if(i!==t)return n(i).find(e);r=T.qsa(a,e)}else{if(Z(e))return n(a).ready(e);if(T.isZ(e))return e;if(A(e))r=k(e);else if(D(e))r=[e],e=null;else if(l.test(e))r=T.fragment(e.trim(),RegExp.$1,i),e=null;else{if(i!==t)return n(i).find(e);r=T.qsa(a,e)}}return T.Z(r,e)},n=function(t,e){return T.init(t,e)},n.extend=function(t){var e,n=o.call(arguments,1);return"boolean"==typeof t&&(e=t,t=n.shift()),n.forEach(function(n){B(t,n,e)}),t},T.qsa=function(t,e){var n,i="#"==e[0],r=!i&&"."==e[0],s=i||r?e.slice(1):e,a=E.test(s);return $(t)&&a&&i?(n=t.getElementById(s))?[n]:[]:1!==t.nodeType&&9!==t.nodeType?[]:o.call(a&&!i?r?t.getElementsByClassName(s):t.getElementsByTagName(e):t.querySelectorAll(e))},n.contains=a.documentElement.contains?function(t,e){return t!==e&&t.contains(e)}:function(t,e){for(;e&&(e=e.parentNode);)if(e===t)return!0;return!1},n.type=L,n.isFunction=Z,n.isWindow=_,n.isArray=A,n.isPlainObject=M,n.isEmptyObject=function(t){var e;for(e in t)return!1;return!0},n.inArray=function(t,e,n){return r.indexOf.call(e,t,n)},n.camelCase=C,n.trim=function(t){return null==t?"":String.prototype.trim.call(t)},n.uuid=0,n.support={},n.expr={},n.map=function(t,e){var n,r,o,i=[];if(R(t))for(r=0;r<t.length;r++)n=e(t[r],r),null!=n&&i.push(n);else for(o in t)n=e(t[o],o),null!=n&&i.push(n);return z(i)},n.each=function(t,e){var n,i;if(R(t)){for(n=0;n<t.length;n++)if(e.call(t[n],n,t[n])===!1)return t}else for(i in t)if(e.call(t[i],i,t[i])===!1)return t;return t},n.grep=function(t,e){return s.call(t,e)},window.JSON&&(n.parseJSON=JSON.parse),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(t,e){j["[object "+e+"]"]=e.toLowerCase()}),n.fn={forEach:r.forEach,reduce:r.reduce,push:r.push,sort:r.sort,indexOf:r.indexOf,concat:r.concat,map:function(t){return n(n.map(this,function(e,n){return t.call(e,n,e)}))},slice:function(){return n(o.apply(this,arguments))},ready:function(t){return w.test(a.readyState)&&a.body?t(n):a.addEventListener("DOMContentLoaded",function(){t(n)},!1),this},get:function(e){return e===t?o.call(this):this[e>=0?e:e+this.length]},toArray:function(){return this.get()},size:function(){return this.length},remove:function(){return this.each(function(){null!=this.parentNode&&this.parentNode.removeChild(this)})},each:function(t){return r.every.call(this,function(e,n){return t.call(e,n,e)!==!1}),this},filter:function(t){return Z(t)?this.not(this.not(t)):n(s.call(this,function(e){return T.matches(e,t)}))},add:function(t,e){return n(N(this.concat(n(t,e))))},is:function(t){return this.length>0&&T.matches(this[0],t)},not:function(e){var i=[];if(Z(e)&&e.call!==t)this.each(function(t){e.call(this,t)||i.push(this)});else{var r="string"==typeof e?this.filter(e):R(e)&&Z(e.item)?o.call(e):n(e);this.forEach(function(t){r.indexOf(t)<0&&i.push(t)})}return n(i)},has:function(t){return this.filter(function(){return D(t)?n.contains(this,t):n(this).find(t).size()})},eq:function(t){return-1===t?this.slice(t):this.slice(t,+t+1)},first:function(){var t=this[0];return t&&!D(t)?t:n(t)},last:function(){var t=this[this.length-1];return t&&!D(t)?t:n(t)},find:function(t){var e,i=this;return e=t?"object"==typeof t?n(t).filter(function(){var t=this;return r.some.call(i,function(e){return n.contains(e,t)})}):1==this.length?n(T.qsa(this[0],t)):this.map(function(){return T.qsa(this,t)}):n()},closest:function(t,e){var i=this[0],r=!1;for("object"==typeof t&&(r=n(t));i&&!(r?r.indexOf(i)>=0:T.matches(i,t));)i=i!==e&&!$(i)&&i.parentNode;return n(i)},parents:function(t){for(var e=[],i=this;i.length>0;)i=n.map(i,function(t){return(t=t.parentNode)&&!$(t)&&e.indexOf(t)<0?(e.push(t),t):void 0});return U(e,t)},parent:function(t){return U(N(this.pluck("parentNode")),t)},children:function(t){return U(this.map(function(){return V(this)}),t)},contents:function(){return this.map(function(){return o.call(this.childNodes)})},siblings:function(t){return U(this.map(function(t,e){return s.call(V(e.parentNode),function(t){return t!==e})}),t)},empty:function(){return this.each(function(){this.innerHTML=""})},pluck:function(t){return n.map(this,function(e){return e[t]})},show:function(){return this.each(function(){"none"==this.style.display&&(this.style.display=""),"none"==getComputedStyle(this,"").getPropertyValue("display")&&(this.style.display=I(this.nodeName))})},replaceWith:function(t){return this.before(t).remove()},wrap:function(t){var e=Z(t);if(this[0]&&!e)var i=n(t).get(0),r=i.parentNode||this.length>1;return this.each(function(o){n(this).wrapAll(e?t.call(this,o):r?i.cloneNode(!0):i)})},wrapAll:function(t){if(this[0]){n(this[0]).before(t=n(t));for(var e;(e=t.children()).length;)t=e.first();n(t).append(this)}return this},wrapInner:function(t){var e=Z(t);return this.each(function(i){var r=n(this),o=r.contents(),s=e?t.call(this,i):t;o.length?o.wrapAll(s):r.append(s)})},unwrap:function(){return this.parent().each(function(){n(this).replaceWith(n(this).children())}),this},clone:function(){return this.map(function(){return this.cloneNode(!0)})},hide:function(){return this.css("display","none")},toggle:function(e){return this.each(function(){var i=n(this);(e===t?"none"==i.css("display"):e)?i.show():i.hide()})},prev:function(t){return n(this.pluck("previousElementSibling")).filter(t||"*")},next:function(t){return n(this.pluck("nextElementSibling")).filter(t||"*")},html:function(t){return 0 in arguments?this.each(function(e){var i=this.innerHTML;n(this).empty().append(J(this,t,e,i))}):0 in this?this[0].innerHTML:null},text:function(t){return 0 in arguments?this.each(function(e){var n=J(this,t,e,this.textContent);this.textContent=null==n?"":""+n}):0 in this?this[0].textContent:null},attr:function(n,i){var r;return"string"!=typeof n||1 in arguments?this.each(function(t){if(1===this.nodeType)if(D(n))for(e in n)X(this,e,n[e]);else X(this,n,J(this,i,t,this.getAttribute(n)))}):this.length&&1===this[0].nodeType?!(r=this[0].getAttribute(n))&&n in this[0]?this[0][n]:r:t},removeAttr:function(t){return this.each(function(){1===this.nodeType&&t.split(" ").forEach(function(t){X(this,t)},this)})},prop:function(t,e){return t=P[t]||t,1 in arguments?this.each(function(n){this[t]=J(this,e,n,this[t])}):this[0]&&this[0][t]},data:function(e,n){var i="data-"+e.replace(m,"-$1").toLowerCase(),r=1 in arguments?this.attr(i,n):this.attr(i);return null!==r?Y(r):t},val:function(t){return 0 in arguments?this.each(function(e){this.value=J(this,t,e,this.value)}):this[0]&&(this[0].multiple?n(this[0]).find("option").filter(function(){return this.selected}).pluck("value"):this[0].value)},offset:function(t){if(t)return this.each(function(e){var i=n(this),r=J(this,t,e,i.offset()),o=i.offsetParent().offset(),s={top:r.top-o.top,left:r.left-o.left};"static"==i.css("position")&&(s.position="relative"),i.css(s)});if(!this.length)return null;var e=this[0].getBoundingClientRect();return{left:e.left+window.pageXOffset,top:e.top+window.pageYOffset,width:Math.round(e.width),height:Math.round(e.height)}},css:function(t,i){if(arguments.length<2){var r,o=this[0];if(!o)return;if(r=getComputedStyle(o,""),"string"==typeof t)return o.style[C(t)]||r.getPropertyValue(t);if(A(t)){var s={};return n.each(t,function(t,e){s[e]=o.style[C(e)]||r.getPropertyValue(e)}),s}}var a="";if("string"==L(t))i||0===i?a=F(t)+":"+H(t,i):this.each(function(){this.style.removeProperty(F(t))});else for(e in t)t[e]||0===t[e]?a+=F(e)+":"+H(e,t[e])+";":this.each(function(){this.style.removeProperty(F(e))});return this.each(function(){this.style.cssText+=";"+a})},index:function(t){return t?this.indexOf(n(t)[0]):this.parent().children().indexOf(this[0])},hasClass:function(t){return t?r.some.call(this,function(t){return this.test(W(t))},q(t)):!1},addClass:function(t){return t?this.each(function(e){if("className"in this){i=[];var r=W(this),o=J(this,t,e,r);o.split(/\s+/g).forEach(function(t){n(this).hasClass(t)||i.push(t)},this),i.length&&W(this,r+(r?" ":"")+i.join(" "))}}):this},removeClass:function(e){return this.each(function(n){if("className"in this){if(e===t)return W(this,"");i=W(this),J(this,e,n,i).split(/\s+/g).forEach(function(t){i=i.replace(q(t)," ")}),W(this,i.trim())}})},toggleClass:function(e,i){return e?this.each(function(r){var o=n(this),s=J(this,e,r,W(this));s.split(/\s+/g).forEach(function(e){(i===t?!o.hasClass(e):i)?o.addClass(e):o.removeClass(e)})}):this},scrollTop:function(e){if(this.length){var n="scrollTop"in this[0];return e===t?n?this[0].scrollTop:this[0].pageYOffset:this.each(n?function(){this.scrollTop=e}:function(){this.scrollTo(this.scrollX,e)})}},scrollLeft:function(e){if(this.length){var n="scrollLeft"in this[0];return e===t?n?this[0].scrollLeft:this[0].pageXOffset:this.each(n?function(){this.scrollLeft=e}:function(){this.scrollTo(e,this.scrollY)})}},position:function(){if(this.length){var t=this[0],e=this.offsetParent(),i=this.offset(),r=d.test(e[0].nodeName)?{top:0,left:0}:e.offset();return i.top-=parseFloat(n(t).css("margin-top"))||0,i.left-=parseFloat(n(t).css("margin-left"))||0,r.top+=parseFloat(n(e[0]).css("border-top-width"))||0,r.left+=parseFloat(n(e[0]).css("border-left-width"))||0,{top:i.top-r.top,left:i.left-r.left}}},offsetParent:function(){return this.map(function(){for(var t=this.offsetParent||a.body;t&&!d.test(t.nodeName)&&"static"==n(t).css("position");)t=t.offsetParent;return t})}},n.fn.detach=n.fn.remove,["width","height"].forEach(function(e){var i=e.replace(/./,function(t){return t[0].toUpperCase()});n.fn[e]=function(r){var o,s=this[0];return r===t?_(s)?s["inner"+i]:$(s)?s.documentElement["scroll"+i]:(o=this.offset())&&o[e]:this.each(function(t){s=n(this),s.css(e,J(this,r,t,s[e]()))})}}),v.forEach(function(t,e){var i=e%2;n.fn[t]=function(){var t,o,r=n.map(arguments,function(e){return t=L(e),"object"==t||"array"==t||null==e?e:T.fragment(e)}),s=this.length>1;return r.length<1?this:this.each(function(t,u){o=i?u:u.parentNode,u=0==e?u.nextSibling:1==e?u.firstChild:2==e?u:null;var f=n.contains(a.documentElement,o);r.forEach(function(t){if(s)t=t.cloneNode(!0);else if(!o)return n(t).remove();o.insertBefore(t,u),f&&G(t,function(t){null==t.nodeName||"SCRIPT"!==t.nodeName.toUpperCase()||t.type&&"text/javascript"!==t.type||t.src||window.eval.call(window,t.innerHTML)})})})},n.fn[i?t+"To":"insert"+(e?"Before":"After")]=function(e){return n(e)[t](this),this}}),T.Z.prototype=n.fn,T.uniq=N,T.deserializeValue=Y,n.zepto=T,n}();window.Zepto=Zepto,void 0===window.$&&(window.$=Zepto),function(t){function l(t){return t._zid||(t._zid=e++)}function h(t,e,n,i){if(e=p(e),e.ns)var r=d(e.ns);return(s[l(t)]||[]).filter(function(t){return!(!t||e.e&&t.e!=e.e||e.ns&&!r.test(t.ns)||n&&l(t.fn)!==l(n)||i&&t.sel!=i)})}function p(t){var e=(""+t).split(".");return{e:e[0],ns:e.slice(1).sort().join(" ")}}function d(t){return new RegExp("(?:^| )"+t.replace(" "," .* ?")+"(?: |$)")}function m(t,e){return t.del&&!u&&t.e in f||!!e}function g(t){return c[t]||u&&f[t]||t}function v(e,i,r,o,a,u,f){var h=l(e),d=s[h]||(s[h]=[]);i.split(/\s/).forEach(function(i){if("ready"==i)return t(document).ready(r);var s=p(i);s.fn=r,s.sel=a,s.e in c&&(r=function(e){var n=e.relatedTarget;return!n||n!==this&&!t.contains(this,n)?s.fn.apply(this,arguments):void 0}),s.del=u;var l=u||r;s.proxy=function(t){if(t=j(t),!t.isImmediatePropagationStopped()){t.data=o;var i=l.apply(e,t._args==n?[t]:[t].concat(t._args));return i===!1&&(t.preventDefault(),t.stopPropagation()),i}},s.i=d.length,d.push(s),"addEventListener"in e&&e.addEventListener(g(s.e),s.proxy,m(s,f))})}function y(t,e,n,i,r){var o=l(t);(e||"").split(/\s/).forEach(function(e){h(t,e,n,i).forEach(function(e){delete s[o][e.i],"removeEventListener"in t&&t.removeEventListener(g(e.e),e.proxy,m(e,r))})})}function j(e,i){return(i||!e.isDefaultPrevented)&&(i||(i=e),t.each(E,function(t,n){var r=i[t];e[t]=function(){return this[n]=x,r&&r.apply(i,arguments)},e[n]=b}),(i.defaultPrevented!==n?i.defaultPrevented:"returnValue"in i?i.returnValue===!1:i.getPreventDefault&&i.getPreventDefault())&&(e.isDefaultPrevented=x)),e}function S(t){var e,i={originalEvent:t};for(e in t)w.test(e)||t[e]===n||(i[e]=t[e]);return j(i,t)}var n,e=1,i=Array.prototype.slice,r=t.isFunction,o=function(t){return"string"==typeof t},s={},a={},u="onfocusin"in window,f={focus:"focusin",blur:"focusout"},c={mouseenter:"mouseover",mouseleave:"mouseout"};a.click=a.mousedown=a.mouseup=a.mousemove="MouseEvents",t.event={add:v,remove:y},t.proxy=function(e,n){var s=2 in arguments&&i.call(arguments,2);if(r(e)){var a=function(){return e.apply(n,s?s.concat(i.call(arguments)):arguments)};return a._zid=l(e),a}if(o(n))return s?(s.unshift(e[n],e),t.proxy.apply(null,s)):t.proxy(e[n],e);throw new TypeError("expected function")},t.fn.bind=function(t,e,n){return this.on(t,e,n)},t.fn.unbind=function(t,e){return this.off(t,e)},t.fn.one=function(t,e,n,i){return this.on(t,e,n,i,1)};var x=function(){return!0},b=function(){return!1},w=/^([A-Z]|returnValue$|layer[XY]$)/,E={preventDefault:"isDefaultPrevented",stopImmediatePropagation:"isImmediatePropagationStopped",stopPropagation:"isPropagationStopped"};t.fn.delegate=function(t,e,n){return this.on(e,t,n)},t.fn.undelegate=function(t,e,n){return this.off(e,t,n)},t.fn.live=function(e,n){return t(document.body).delegate(this.selector,e,n),this},t.fn.die=function(e,n){return t(document.body).undelegate(this.selector,e,n),this},t.fn.on=function(e,s,a,u,f){var c,l,h=this;return e&&!o(e)?(t.each(e,function(t,e){h.on(t,s,a,e,f)}),h):(o(s)||r(u)||u===!1||(u=a,a=s,s=n),(r(a)||a===!1)&&(u=a,a=n),u===!1&&(u=b),h.each(function(n,r){f&&(c=function(t){return y(r,t.type,u),u.apply(this,arguments)}),s&&(l=function(e){var n,o=t(e.target).closest(s,r).get(0);return o&&o!==r?(n=t.extend(S(e),{currentTarget:o,liveFired:r}),(c||u).apply(o,[n].concat(i.call(arguments,1)))):void 0}),v(r,e,u,a,s,l||c)}))},t.fn.off=function(e,i,s){var a=this;return e&&!o(e)?(t.each(e,function(t,e){a.off(t,i,e)}),a):(o(i)||r(s)||s===!1||(s=i,i=n),s===!1&&(s=b),a.each(function(){y(this,e,s,i)}))},t.fn.trigger=function(e,n){return e=o(e)||t.isPlainObject(e)?t.Event(e):j(e),e._args=n,this.each(function(){e.type in f&&"function"==typeof this[e.type]?this[e.type]():"dispatchEvent"in this?this.dispatchEvent(e):t(this).triggerHandler(e,n)})},t.fn.triggerHandler=function(e,n){var i,r;return this.each(function(s,a){i=S(o(e)?t.Event(e):e),i._args=n,i.target=a,t.each(h(a,e.type||e),function(t,e){return r=e.proxy(i),i.isImmediatePropagationStopped()?!1:void 0})}),r},"focusin focusout focus blur load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select keydown keypress keyup error".split(" ").forEach(function(e){t.fn[e]=function(t){return 0 in arguments?this.bind(e,t):this.trigger(e)}}),t.Event=function(t,e){o(t)||(e=t,t=e.type);var n=document.createEvent(a[t]||"Events"),i=!0;if(e)for(var r in e)"bubbles"==r?i=!!e[r]:n[r]=e[r];return n.initEvent(t,i,!0),j(n)}}(Zepto),function(t){function h(e,n,i){var r=t.Event(n);return t(e).trigger(r,i),!r.isDefaultPrevented()}function p(t,e,i,r){return t.global?h(e||n,i,r):void 0}function d(e){e.global&&0===t.active++&&p(e,null,"ajaxStart")}function m(e){e.global&&!--t.active&&p(e,null,"ajaxStop")}function g(t,e){var n=e.context;return e.beforeSend.call(n,t,e)===!1||p(e,n,"ajaxBeforeSend",[t,e])===!1?!1:void p(e,n,"ajaxSend",[t,e])}function v(t,e,n,i){var r=n.context,o="success";n.success.call(r,t,o,e),i&&i.resolveWith(r,[t,o,e]),p(n,r,"ajaxSuccess",[e,n,t]),x(o,e,n)}function y(t,e,n,i,r){var o=i.context;i.error.call(o,n,e,t),r&&r.rejectWith(o,[n,e,t]),p(i,o,"ajaxError",[n,i,t||e]),x(e,n,i)}function x(t,e,n){var i=n.context;n.complete.call(i,e,t),p(n,i,"ajaxComplete",[e,n]),m(n)}function b(){}function w(t){return t&&(t=t.split(";",2)[0]),t&&(t==f?"html":t==u?"json":s.test(t)?"script":a.test(t)&&"xml")||"text"}function E(t,e){return""==e?t:(t+"&"+e).replace(/[&?]{1,2}/,"?")}function j(e){e.processData&&e.data&&"string"!=t.type(e.data)&&(e.data=t.param(e.data,e.traditional)),!e.data||e.type&&"GET"!=e.type.toUpperCase()||(e.url=E(e.url,e.data),e.data=void 0)}function S(e,n,i,r){return t.isFunction(n)&&(r=i,i=n,n=void 0),t.isFunction(i)||(r=i,i=void 0),{url:e,data:n,success:i,dataType:r}}function C(e,n,i,r){var o,s=t.isArray(n),a=t.isPlainObject(n);t.each(n,function(n,u){o=t.type(u),r&&(n=i?r:r+"["+(a||"object"==o||"array"==o?n:"")+"]"),!r&&s?e.add(u.name,u.value):"array"==o||!i&&"object"==o?C(e,u,i,n):e.add(n,u)})}var i,r,e=0,n=window.document,o=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,s=/^(?:text|application)\/javascript/i,a=/^(?:text|application)\/xml/i,u="application/json",f="text/html",c=/^\s*$/,l=n.createElement("a");l.href=window.location.href,t.active=0,t.ajaxJSONP=function(i,r){if(!("type"in i))return t.ajax(i);var f,h,o=i.jsonpCallback,s=(t.isFunction(o)?o():o)||"jsonp"+ ++e,a=n.createElement("script"),u=window[s],c=function(e){t(a).triggerHandler("error",e||"abort")},l={abort:c};return r&&r.promise(l),t(a).on("load error",function(e,n){clearTimeout(h),t(a).off().remove(),"error"!=e.type&&f?v(f[0],l,i,r):y(null,n||"error",l,i,r),window[s]=u,f&&t.isFunction(u)&&u(f[0]),u=f=void 0}),g(l,i)===!1?(c("abort"),l):(window[s]=function(){f=arguments},a.src=i.url.replace(/\?(.+)=\?/,"?$1="+s),n.head.appendChild(a),i.timeout>0&&(h=setTimeout(function(){c("timeout")},i.timeout)),l)},t.ajaxSettings={type:"GET",beforeSend:b,success:b,error:b,complete:b,context:null,global:!0,xhr:function(){return new window.XMLHttpRequest},accepts:{script:"text/javascript, application/javascript, application/x-javascript",json:u,xml:"application/xml, text/xml",html:f,text:"text/plain"},crossDomain:!1,timeout:0,processData:!0,cache:!0},t.ajax=function(e){var a,o=t.extend({},e||{}),s=t.Deferred&&t.Deferred();for(i in t.ajaxSettings)void 0===o[i]&&(o[i]=t.ajaxSettings[i]);d(o),o.crossDomain||(a=n.createElement("a"),a.href=o.url,a.href=a.href,o.crossDomain=l.protocol+"//"+l.host!=a.protocol+"//"+a.host),o.url||(o.url=window.location.toString()),j(o);var u=o.dataType,f=/\?.+=\?/.test(o.url);if(f&&(u="jsonp"),o.cache!==!1&&(e&&e.cache===!0||"script"!=u&&"jsonp"!=u)||(o.url=E(o.url,"_="+Date.now())),"jsonp"==u)return f||(o.url=E(o.url,o.jsonp?o.jsonp+"=?":o.jsonp===!1?"":"callback=?")),t.ajaxJSONP(o,s);var C,h=o.accepts[u],p={},m=function(t,e){p[t.toLowerCase()]=[t,e]},x=/^([\w-]+:)\/\//.test(o.url)?RegExp.$1:window.location.protocol,S=o.xhr(),T=S.setRequestHeader;if(s&&s.promise(S),o.crossDomain||m("X-Requested-With","XMLHttpRequest"),m("Accept",h||"*/*"),(h=o.mimeType||h)&&(h.indexOf(",")>-1&&(h=h.split(",",2)[0]),S.overrideMimeType&&S.overrideMimeType(h)),(o.contentType||o.contentType!==!1&&o.data&&"GET"!=o.type.toUpperCase())&&m("Content-Type",o.contentType||"application/x-www-form-urlencoded"),o.headers)for(r in o.headers)m(r,o.headers[r]);if(S.setRequestHeader=m,S.onreadystatechange=function(){if(4==S.readyState){S.onreadystatechange=b,clearTimeout(C);var e,n=!1;if(S.status>=200&&S.status<300||304==S.status||0==S.status&&"file:"==x){u=u||w(o.mimeType||S.getResponseHeader("content-type")),e=S.responseText;try{"script"==u?(1,eval)(e):"xml"==u?e=S.responseXML:"json"==u&&(e=c.test(e)?null:t.parseJSON(e))}catch(i){n=i}n?y(n,"parsererror",S,o,s):v(e,S,o,s)}else y(S.statusText||null,S.status?"error":"abort",S,o,s)}},g(S,o)===!1)return S.abort(),y(null,"abort",S,o,s),S;if(o.xhrFields)for(r in o.xhrFields)S[r]=o.xhrFields[r];var N="async"in o?o.async:!0;S.open(o.type,o.url,N,o.username,o.password);for(r in p)T.apply(S,p[r]);return o.timeout>0&&(C=setTimeout(function(){S.onreadystatechange=b,S.abort(),y(null,"timeout",S,o,s)},o.timeout)),S.send(o.data?o.data:null),S},t.get=function(){return t.ajax(S.apply(null,arguments))},t.post=function(){var e=S.apply(null,arguments);return e.type="POST",t.ajax(e)},t.getJSON=function(){var e=S.apply(null,arguments);return e.dataType="json",t.ajax(e)},t.fn.load=function(e,n,i){if(!this.length)return this;var a,r=this,s=e.split(/\s/),u=S(e,n,i),f=u.success;return s.length>1&&(u.url=s[0],a=s[1]),u.success=function(e){r.html(a?t("<div>").html(e.replace(o,"")).find(a):e),f&&f.apply(r,arguments)},t.ajax(u),this};var T=encodeURIComponent;t.param=function(e,n){var i=[];return i.add=function(e,n){t.isFunction(n)&&(n=n()),null==n&&(n=""),this.push(T(e)+"="+T(n))},C(i,e,n),i.join("&").replace(/%20/g,"+")}}(Zepto),function(t){t.fn.serializeArray=function(){var e,n,i=[],r=function(t){return t.forEach?t.forEach(r):void i.push({name:e,value:t})};return this[0]&&t.each(this[0].elements,function(i,o){n=o.type,e=o.name,e&&"fieldset"!=o.nodeName.toLowerCase()&&!o.disabled&&"submit"!=n&&"reset"!=n&&"button"!=n&&"file"!=n&&("radio"!=n&&"checkbox"!=n||o.checked)&&r(t(o).val())}),i},t.fn.serialize=function(){var t=[];return this.serializeArray().forEach(function(e){t.push(encodeURIComponent(e.name)+"="+encodeURIComponent(e.value))}),t.join("&")},t.fn.submit=function(e){if(0 in arguments)this.bind("submit",e);else if(this.length){var n=t.Event("submit");this.eq(0).trigger(n),n.isDefaultPrevented()||this.get(0).submit()}return this}}(Zepto),function(t){"__proto__"in{}||t.extend(t.zepto,{Z:function(e,n){return e=e||[],t.extend(e,t.fn),e.selector=n||"",e.__Z=!0,e},isZ:function(e){return"array"===t.type(e)&&"__Z"in e}});try{getComputedStyle(void 0)}catch(e){var n=getComputedStyle;window.getComputedStyle=function(t){try{return n(t)}catch(e){return null}}}}(Zepto);
-
-/* https://highlightjs.org/ */
-!function(e){"undefined"!=typeof exports?e(exports):(window.hljs=e({}),"function"==typeof define&&define.amd&&define("hljs",[],function(){return window.hljs}))}(function(e){function n(e){return e.replace(/&/gm,"&amp;").replace(/</gm,"&lt;").replace(/>/gm,"&gt;")}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0==t.index}function a(e){return/no-?highlight|plain|text/.test(e)}function i(e){var n,t,r,i=e.className+" ";if(i+=e.parentNode?e.parentNode.className:"",t=/\blang(?:uage)?-([\w-]+)\b/.exec(i))return E(t[1])?t[1]:"no-highlight";for(i=i.split(/\s+/),n=0,r=i.length;r>n;n++)if(E(i[n])||a(i[n]))return i[n]}function o(e,n){var t,r={};for(t in e)r[t]=e[t];if(n)for(t in n)r[t]=n[t];return r}function u(e){var n=[];return function r(e,a){for(var i=e.firstChild;i;i=i.nextSibling)3==i.nodeType?a+=i.nodeValue.length:1==i.nodeType&&(n.push({event:"start",offset:a,node:i}),a=r(i,a),t(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:i}));return a}(e,0),n}function c(e,r,a){function i(){return e.length&&r.length?e[0].offset!=r[0].offset?e[0].offset<r[0].offset?e:r:"start"==r[0].event?e:r:e.length?e:r}function o(e){function r(e){return" "+e.nodeName+'="'+n(e.value)+'"'}f+="<"+t(e)+Array.prototype.map.call(e.attributes,r).join("")+">"}function u(e){f+="</"+t(e)+">"}function c(e){("start"==e.event?o:u)(e.node)}for(var s=0,f="",l=[];e.length||r.length;){var g=i();if(f+=n(a.substr(s,g[0].offset-s)),s=g[0].offset,g==e){l.reverse().forEach(u);do c(g.splice(0,1)[0]),g=i();while(g==e&&g.length&&g[0].offset==s);l.reverse().forEach(o)}else"start"==g[0].event?l.push(g[0].node):l.pop(),c(g.splice(0,1)[0])}return f+n(a.substr(s))}function s(e){function n(e){return e&&e.source||e}function t(t,r){return new RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var u={},c=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");u[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof a.k?c("keyword",a.k):Object.keys(a.k).forEach(function(e){c(e,a.k[e])}),a.k=u}a.lR=t(a.l||/\b\w+\b/,!0),i&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=t(a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||"",a.eW&&i.tE&&(a.tE+=(a.e?"|":"")+i.tE)),a.i&&(a.iR=t(a.i)),void 0===a.r&&(a.r=1),a.c||(a.c=[]);var s=[];a.c.forEach(function(e){e.v?e.v.forEach(function(n){s.push(o(e,n))}):s.push("self"==e?a:e)}),a.c=s,a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var f=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=f.length?t(f.join("|"),!0):{exec:function(){return null}}}}r(e)}function f(e,t,a,i){function o(e,n){for(var t=0;t<n.c.length;t++)if(r(n.c[t].bR,e))return n.c[t]}function u(e,n){if(r(e.eR,n)){for(;e.endsParent&&e.parent;)e=e.parent;return e}return e.eW?u(e.parent,n):void 0}function c(e,n){return!a&&r(n.iR,e)}function g(e,n){var t=N.cI?n[0].toLowerCase():n[0];return e.k.hasOwnProperty(t)&&e.k[t]}function h(e,n,t,r){var a=r?"":w.classPrefix,i='<span class="'+a,o=t?"":"</span>";return i+=e+'">',i+n+o}function p(){if(!L.k)return n(y);var e="",t=0;L.lR.lastIndex=0;for(var r=L.lR.exec(y);r;){e+=n(y.substr(t,r.index-t));var a=g(L,r);a?(B+=a[1],e+=h(a[0],n(r[0]))):e+=n(r[0]),t=L.lR.lastIndex,r=L.lR.exec(y)}return e+n(y.substr(t))}function d(){var e="string"==typeof L.sL;if(e&&!x[L.sL])return n(y);var t=e?f(L.sL,y,!0,M[L.sL]):l(y,L.sL.length?L.sL:void 0);return L.r>0&&(B+=t.r),e&&(M[L.sL]=t.top),h(t.language,t.value,!1,!0)}function b(){return void 0!==L.sL?d():p()}function v(e,t){var r=e.cN?h(e.cN,"",!0):"";e.rB?(k+=r,y=""):e.eB?(k+=n(t)+r,y=""):(k+=r,y=t),L=Object.create(e,{parent:{value:L}})}function m(e,t){if(y+=e,void 0===t)return k+=b(),0;var r=o(t,L);if(r)return k+=b(),v(r,t),r.rB?0:t.length;var a=u(L,t);if(a){var i=L;i.rE||i.eE||(y+=t),k+=b();do L.cN&&(k+="</span>"),B+=L.r,L=L.parent;while(L!=a.parent);return i.eE&&(k+=n(t)),y="",a.starts&&v(a.starts,""),i.rE?0:t.length}if(c(t,L))throw new Error('Illegal lexeme "'+t+'" for mode "'+(L.cN||"<unnamed>")+'"');return y+=t,t.length||1}var N=E(e);if(!N)throw new Error('Unknown language: "'+e+'"');s(N);var R,L=i||N,M={},k="";for(R=L;R!=N;R=R.parent)R.cN&&(k=h(R.cN,"",!0)+k);var y="",B=0;try{for(var C,j,I=0;;){if(L.t.lastIndex=I,C=L.t.exec(t),!C)break;j=m(t.substr(I,C.index-I),C[0]),I=C.index+j}for(m(t.substr(I)),R=L;R.parent;R=R.parent)R.cN&&(k+="</span>");return{r:B,value:k,language:e,top:L}}catch(O){if(-1!=O.message.indexOf("Illegal"))return{r:0,value:n(t)};throw O}}function l(e,t){t=t||w.languages||Object.keys(x);var r={r:0,value:n(e)},a=r;return t.forEach(function(n){if(E(n)){var t=f(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}}),a.language&&(r.second_best=a),r}function g(e){return w.tabReplace&&(e=e.replace(/^((<[^>]+>|\t)+)/gm,function(e,n){return n.replace(/\t/g,w.tabReplace)})),w.useBR&&(e=e.replace(/\n/g,"<br>")),e}function h(e,n,t){var r=n?R[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),-1===e.indexOf(r)&&a.push(r),a.join(" ").trim()}function p(e){var n=i(e);if(!a(n)){var t;w.useBR?(t=document.createElementNS("http://www.w3.org/1999/xhtml","div"),t.innerHTML=e.innerHTML.replace(/\n/g,"").replace(/<br[ \/]*>/g,"\n")):t=e;var r=t.textContent,o=n?f(n,r,!0):l(r),s=u(t);if(s.length){var p=document.createElementNS("http://www.w3.org/1999/xhtml","div");p.innerHTML=o.value,o.value=c(s,u(p),r)}o.value=g(o.value),e.innerHTML=o.value,e.className=h(e.className,n,o.language),e.result={language:o.language,re:o.r},o.second_best&&(e.second_best={language:o.second_best.language,re:o.second_best.r})}}function d(e){w=o(w,e)}function b(){if(!b.called){b.called=!0;var e=document.querySelectorAll("pre code");Array.prototype.forEach.call(e,p)}}function v(){addEventListener("DOMContentLoaded",b,!1),addEventListener("load",b,!1)}function m(n,t){var r=x[n]=t(e);r.aliases&&r.aliases.forEach(function(e){R[e]=n})}function N(){return Object.keys(x)}function E(e){return x[e]||x[R[e]]}var w={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0},x={},R={};return e.highlight=f,e.highlightAuto=l,e.fixMarkup=g,e.highlightBlock=p,e.configure=d,e.initHighlighting=b,e.initHighlightingOnLoad=v,e.registerLanguage=m,e.listLanguages=N,e.getLanguage=E,e.inherit=o,e.IR="[a-zA-Z]\\w*",e.UIR="[a-zA-Z_]\\w*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such)\b/},e.C=function(n,t,r){var a=e.inherit({cN:"comment",b:n,e:t,c:[]},r||{});return a.c.push(e.PWM),a.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),a},e.CLCM=e.C("//","$"),e.CBCM=e.C("/\\*","\\*/"),e.HCM=e.C("#","$"),e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e});hljs.registerLanguage("javascript",function(e){return{aliases:["js"],k:{keyword:"in of if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect Promise"},c:[{cN:"pi",r:10,b:/^\s*['"]use (strict|asm)['"]/},e.ASM,e.QSM,{cN:"string",b:"`",e:"`",c:[e.BE,{cN:"subst",b:"\\$\\{",e:"\\}"}]},e.CLCM,e.CBCM,{cN:"number",v:[{b:"\\b(0[bB][01]+)"},{b:"\\b(0[oO][0-7]+)"},{b:e.CNR}],r:0},{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM,{b:/</,e:/>\s*[);\]]/,r:0,sL:"xml"}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[e.inherit(e.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,c:[e.CLCM,e.CBCM],i:/["'\(]/}],i:/\[|%/},{b:/\$[(.]/},{b:"\\."+e.IR,r:0},{bK:"import",e:"[;$]",k:"import from as",c:[e.ASM,e.QSM]},{cN:"class",bK:"class",e:/[{;=]/,eE:!0,i:/[:"\[\]]/,c:[{bK:"extends"},e.UTM]}],i:/#/}});hljs.registerLanguage("xml",function(t){var s="[A-Za-z0-9\\._:-]+",c={b:/<\?(php)?(?!\w)/,e:/\?>/,sL:"php"},e={eW:!0,i:/</,r:0,c:[c,{cN:"attribute",b:s,r:0},{b:"=",r:0,c:[{cN:"value",c:[c],v:[{b:/"/,e:/"/},{b:/'/,e:/'/},{b:/[^\s\/>]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xsl","plist"],cI:!0,c:[{cN:"doctype",b:"<!DOCTYPE",e:">",r:10,c:[{b:"\\[",e:"\\]"}]},t.C("<!--","-->",{r:10}),{cN:"cdata",b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"tag",b:"<style(?=\\s|>|$)",e:">",k:{title:"style"},c:[e],starts:{e:"</style>",rE:!0,sL:"css"}},{cN:"tag",b:"<script(?=\\s|>|$)",e:">",k:{title:"script"},c:[e],starts:{e:"</script>",rE:!0,sL:["actionscript","javascript","handlebars"]}},c,{cN:"pi",b:/<\?\w+/,e:/\?>/,r:10},{cN:"tag",b:"</?",e:"/?>",c:[{cN:"title",b:/[^ \/><\n\t]+/,r:0},e]}]}});
\ No newline at end of file
diff --git a/en.html b/en.html
new file mode 100644
index 0000000..3ee6ab7
--- /dev/null
+++ b/en.html
@@ -0,0 +1,832 @@
+<!doctype html>
+<html>
+
+<head>
+  <meta charset="utf-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1, minimal-ui">
+  <title>AnyProxy</title>
+  <link type="text/css" rel="stylesheet" href="assets/css/github-markdown.css">
+  <link type="text/css" rel="stylesheet" href="assets/css/pilcrow.css">
+  <link type="text/css" rel="stylesheet" href="assets/css/atom-one-light.css" />
+  <link type="text/css" rel="stylesheet" href="assets/css/custom.css" />
+  <meta name="description" content="A fully configurable proxy in NodeJS, which can handle HTTPS requests perfectly.">
+  <meta name="description" content="AnyProxy - 开放式的HTTP/HTTPS代理,你可以灵活控制各种网络数据">
+  <meta name="keywords" content="代理服务器 Proxy HTTP HTTPS">
+  <script>
+    //redirect to Chinese version if in China
+    if (new Date().getTimezoneOffset() == "-480" && !(/(cn|en)/i.test(location.href))) {
+      location.href = "./cn.html";
+    } else {
+      var _hmt = _hmt || []; (function () { var hm = document.createElement("script"); hm.src = "//hm.baidu.com/hm.js?4e51565b7d471fd6623c163a8fd79e07"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })();
+    }
+  </script>
+</head>
+
+<body>
+  <a href="https://github.com/alibaba/anyproxy/tree/4.x" target="_blank">
+    <img style="position: fixed; top: 0; right: 0; border: 0;z-index: 1;" src="https://camo.githubusercontent.com/a6677b08c955af8400f44c6298f40e7d19cc5b2d/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f677261795f3664366436642e706e67"
+      alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_gray_6d6d6d.png">
+  </a>
+
+  <article class="markdown-body">
+    <div class="toc-container" id="j_toc">
+      <div class="toc-content"><ul class="nav nav-list">
+    <li class="sidebar-header-1"><a href="#anyproxy">AnyProxy</a></li>
+    <li class="sidebar-header-2"><a href="#quick-start">Quick start</a></li>
+    <li class="sidebar-header-3"><a href="#install">install</a></li>
+    <li class="sidebar-header-3"><a href="#launch">launch</a></li>
+    <li class="sidebar-header-3"><a href="#other-commands">other commands</a></li>
+    <li class="sidebar-header-2"><a href="#proxy-https-request">Proxy https request</a></li>
+    <li class="sidebar-header-2"><a href="#use-rule-module">Use rule module</a></li>
+    <li class="sidebar-header-3"><a href="#sample">sample</a></li>
+    <li class="sidebar-header-3"><a href="#the-entire-process">the entire process</a></li>
+    <li class="sidebar-header-3"><a href="#how-to-load-rule-module">how to load rule module</a></li>
+    <li class="sidebar-header-2"><a href="#rule-module-interface">Rule module interface</a></li>
+    <li class="sidebar-header-3"><a href="#summary">summary</a></li>
+    <li class="sidebar-header-4"><a href="#summary-1">summary</a></li>
+    <li class="sidebar-header-3"><a href="#beforesendrequest">beforeSendRequest</a></li>
+    <li class="sidebar-header-4"><a href="#beforesendrequest(requestdetail)">beforeSendRequest(requestDetail)</a></li>
+    <li class="sidebar-header-3"><a href="#beforesendresponse">beforeSendResponse</a></li>
+    <li class="sidebar-header-4"><a href="#beforesendresponse(requestdetail,-responsedetail)">beforeSendResponse(requestDetail, responseDetail)</a></li>
+    <li class="sidebar-header-3"><a href="#beforedealhttpsrequest">beforeDealHttpsRequest</a></li>
+    <li class="sidebar-header-4"><a href="#beforedealhttpsrequest(requestdetail)">beforeDealHttpsRequest(requestDetail)</a></li>
+    <li class="sidebar-header-3"><a href="#onerror">onError</a></li>
+    <li class="sidebar-header-4"><a href="#onerror(requestdetail,-error)">onError(requestDetail, error)</a></li>
+    <li class="sidebar-header-3"><a href="#onconnecterror">onConnectError</a></li>
+    <li class="sidebar-header-4"><a href="#onconnecterror(requestdetail,-error)">onConnectError(requestDetail, error)</a></li>
+    <li class="sidebar-header-3"><a href="#faq">FAQ</a></li>
+    <li class="sidebar-header-2"><a href="#rule-samples">Rule Samples</a></li>
+    <li class="sidebar-header-3"><a href="#use-local-response">use local response</a></li>
+    <li class="sidebar-header-3"><a href="#modify-request-header">modify request header</a></li>
+    <li class="sidebar-header-3"><a href="#modify-request-body">modify request body</a></li>
+    <li class="sidebar-header-3"><a href="#modify-the-request-target">modify the request target</a></li>
+    <li class="sidebar-header-3"><a href="#modify-request-protocol">modify request protocol</a></li>
+    <li class="sidebar-header-3"><a href="#modify-response-status-code">modify response status code</a></li>
+    <li class="sidebar-header-3"><a href="#modify-the-response-header">modify the response header</a></li>
+    <li class="sidebar-header-3"><a href="#modify-response-data-and-delay">modify response data and delay</a></li>
+    <li class="sidebar-header-2"><a href="#use-anyproxy-as-an-npm-module">Use AnyProxy as an npm module</a></li>
+    <li class="sidebar-header-2"><a href="#about-anyproxy">About AnyProxy</a></li>
+    <li class="sidebar-header-2"><a href="#appendix">Appendix</a></li>
+    <li class="sidebar-header-3"><a href="#config-root-ca-in-osx">Config root CA in OSX</a></li>
+    <li class="sidebar-header-3"><a href="#trust-root-ca-in-windows">trust root CA in windows</a></li>
+    <li class="sidebar-header-3"><a href="#config-osx-system-proxy">config OSX system proxy</a></li>
+    <li class="sidebar-header-3"><a href="#config-http-proxy-server">config http proxy server</a></li>
+    <li class="sidebar-header-3"><a href="#trust-root-ca-in-ios">trust root CA in iOS</a></li>
+    <li class="sidebar-header-3"><a href="#trust-root-ca-in-ios-&gt;&#x3D;-10.3">trust root CA in iOS &gt;&#x3D; 10.3</a></li>
+    <li class="sidebar-header-3"><a href="#config-ios/android-proxy-server">config iOS/Android proxy server</a></li>
+</ul>
+      </div>
+    </div>
+    <div class="main-content"><h1 id="anyproxy"><a class="header-link" href="#anyproxy"></a>AnyProxy</h1>
+<p>AnyProxy is a fully configurable http/https proxy in NodeJS. Version 4.0 is in beta now.</p>
+<p>Ref: <a href="./cn.html">Chinese Doc 中文文档</a></p>
+<p>Github: </p>
+<ul class="list">
+<li><a href="https://github.com/alibaba/anyproxy/tree/4.x">https://github.com/alibaba/anyproxy/tree/4.x</a></li>
+</ul>
+<p>Features:</p>
+<ul class="list">
+<li>Offer you the ablity to handle http traffic by invoking a js module</li>
+<li>Intercept https</li>
+<li>GUI webinterface</li>
+</ul>
+<p>Change Logs since 3.x:</p>
+<ul class="list">
+<li>Support Promise and Generator in rule module</li>
+<li>Simplified interface in rule module</li>
+<li>A newly designed web interface</li>
+</ul>
+<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/SqVntpzmscXPbSzfcGcr.png" width="500" /></p>
+<h2 id="quick-start"><a class="header-link" href="#quick-start"></a>Quick start</h2>
+<h3 id="install"><a class="header-link" href="#install"></a>install</h3>
+<pre class="hljs"><code>npm install -g anyproxy@beta <span class="hljs-comment"># 4.x is in beta now</span></code></pre><h3 id="launch"><a class="header-link" href="#launch"></a>launch</h3>
+<ul class="list">
+<li>start AnyProxy in command line, with default port 8001</li>
+</ul>
+<pre class="hljs"><code>anyproxy</code></pre><ul class="list">
+<li>now you can use http proxy server by 127.0.0.1:8001</li>
+<li>visit <a href="http://127.0.0.1:8002">http://127.0.0.1:8002</a> to see the http requests</li>
+</ul>
+<h3 id="other-commands"><a class="header-link" href="#other-commands"></a>other commands</h3>
+<ul class="list">
+<li>specify the port of http proxy</li>
+</ul>
+<pre class="hljs"><code>anyproxy --port 1080</code></pre><h2 id="proxy-https-request"><a class="header-link" href="#proxy-https-request"></a>Proxy https request</h2>
+<ul class="list">
+<li>AnyProxy does NOT intercept https requests by default. To view decrypted info, you have to config the CA certificate.</li>
+</ul>
+<blockquote>
+<p>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.</p>
+</blockquote>
+<ul class="list">
+<li>generate certifycates and intercept</li>
+</ul>
+<pre class="hljs"><code>anyproxy-ca <span class="hljs-comment">#generate root CA. manually trust it after that.</span>
+anyproxy --intercept <span class="hljs-comment">#launch anyproxy and intercept all https traffic</span></code></pre><ul class="list">
+<li><a href="#osx系统信任ca证书">Appendix:how to trust CA</a></li>
+</ul>
+<h2 id="use-rule-module"><a class="header-link" href="#use-rule-module"></a>Use rule module</h2>
+<p>AnyProxy provides the ability to load your own rules written in javascript. With rule module, you could customize the logic to handle requests.</p>
+<blockquote>
+<p>Make sure your rule file is got from a trusted source. Otherwise, you may face some unknown security risk.</p>
+</blockquote>
+<p>Rule module could do the following stuff:</p>
+<ul class="list">
+<li>intercept and modify the request which is being sent<ul class="list">
+<li>editable fields include request header, body, target address</li>
+</ul>
+</li>
+<li>intercept and modify the response from server<ul class="list">
+<li>editable fields include response status code, header, body</li>
+</ul>
+</li>
+<li>intercept https requests, modify request and response</li>
+</ul>
+<h3 id="sample"><a class="header-link" href="#sample"></a>sample</h3>
+<ul class="list">
+<li><p>Target</p>
+<ul class="list">
+<li>write a rule module to append some text to the response of GET <a href="http://httpbin.org/user-agent">http://httpbin.org/user-agent</a>, and delay the response for 5 seconds</li>
+</ul>
+</li>
+<li><p>Step 1,Write the rule file, save as sample.js</p>
+<pre class="hljs"><code><span class="hljs-comment">// file: sample.js</span>
+<span class="hljs-built_in">module</span>.exports = {
+  <span class="hljs-attr">summary</span>: <span class="hljs-string">'a rule to modify response'</span>,
+  *beforeSendResponse(requestDetail, responseDetail) {
+    <span class="hljs-keyword">if</span> (requestDetail.url === <span class="hljs-string">'http://httpbin.org/user-agent'</span>) {
+      <span class="hljs-keyword">const</span> newResponse = responseDetail.response;
+      newResponse.body += <span class="hljs-string">'-- AnyProxy Hacked! --'</span>;
+      <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =&gt;</span> {
+        setTimeout(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> { <span class="hljs-comment">// delay</span>
+          resolve({ <span class="hljs-attr">response</span>: newResponse });
+        }, <span class="hljs-number">5000</span>);
+      });
+    }
+  },
+};</code></pre></li>
+<li><p>Step 2, start AnyProxy and load the rule file</p>
+<ul class="list">
+<li>run <code>anyproxy --rule sample.js</code></li>
+</ul>
+</li>
+<li><p>Step 3, test</p>
+<ul class="list">
+<li><p>use curl </p>
+<pre class="hljs"><code>curl http://httpbin.org/user-agent --proxy http://127.0.0.1:8001</code></pre></li>
+<li><p>use browser. Point the http proxy of browser to 127.0.0.1:8001, then visit <a href="http://httpbin.org/user-agent">http://httpbin.org/user-agent</a> </p>
+</li>
+<li><p>the expected response from proxy is </p>
+</li>
+</ul>
+<pre class="hljs"><code>{
+  <span class="hljs-string">"user-agent"</span>: <span class="hljs-string">"curl/7.43.0"</span>
+}
+- AnyProxy Hacked!</code></pre></li>
+<li><p>Step 4, view the request log</p>
+<ul class="list">
+<li>visit <a href="http://127.0.0.1:8002">http://127.0.0.1:8002</a>, the request just sent should be listed here</li>
+</ul>
+</li>
+</ul>
+<h3 id="the-entire-process"><a class="header-link" href="#the-entire-process"></a>the entire process</h3>
+<ul class="list">
+<li>The flow chart is as follows</li>
+</ul>
+<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/TWyNuSJtEZBdrdcOMRjE.png" width="550" /></p>
+<ul class="list">
+<li><p>When got an http request, the entire process of proxy server is</p>
+<ul class="list">
+<li>AnyProxy collects all the quest info, include method, header, body</li>
+<li>AnyProxy calls <code>beforeSendRequest</code> of the rule module. Rule module deal the request, return new request param or response content</li>
+<li>If <code>beforeSendRequest</code> returns the response content, AnyProxy will send the response to client without sending to target server. The process ends here.</li>
+<li>Send request to target server, collect response</li>
+<li>Call <code>beforeSendResponse</code> of the rule module. Rule module deal the response data</li>
+<li>Send response to client</li>
+</ul>
+</li>
+<li><p>When AnyProxy get https request, it could replace the certificate and decrypt the request data</p>
+<ul class="list">
+<li>AnyProxy calls <code>beforeDealHttpsRequest</code> of the rule module</li>
+<li>If the function returns <code>true</code>, AnyProxy will do the man-in-the-middle attack to it. Otherwise, the request will not be dealed.</li>
+</ul>
+</li>
+</ul>
+<h3 id="how-to-load-rule-module"><a class="header-link" href="#how-to-load-rule-module"></a>how to load rule module</h3>
+<ul class="list">
+<li><p>use local file</p>
+<pre class="hljs"><code>anyproxy --rule ./rule.js</code></pre></li>
+<li><p>use an online rule file</p>
+<pre class="hljs"><code>anyproxy --rule https://sample.com/rule.js</code></pre></li>
+<li><p>use an npm module</p>
+<ul class="list">
+<li>AnyProxy uses <code>require()</code> to load rule module. You could either load a local npm module or a global-installed one.</li>
+</ul>
+<pre class="hljs"><code>anyproxy --rule ./myRulePkg/ <span class="hljs-comment">#local module</span>
+npm i -g myRulePkg &amp;&amp; anyproxy --rule myRulePkg <span class="hljs-comment">#global-installed module</span></code></pre></li>
+</ul>
+<h2 id="rule-module-interface"><a class="header-link" href="#rule-module-interface"></a>Rule module interface</h2>
+<p>A typical rule module is as follows. All the functions are optional, just write the part you are interested in.</p>
+<pre class="hljs"><code><span class="hljs-built_in">module</span>.exports = {
+  <span class="hljs-comment">// introduction</span>
+  summary: <span class="hljs-string">'my customized rule for AnyProxy'</span>, 
+  <span class="hljs-comment">// intercept before send request to server</span>
+  *beforeSendRequest(requestDetail) { <span class="hljs-comment">/* ... */</span> }, 
+  <span class="hljs-comment">// deal response before send to client </span>
+  *beforeSendResponse(requestDetail, responseDetail) { <span class="hljs-comment">/* ... */</span> }, 
+  <span class="hljs-comment">// if deal https request</span>
+  *beforeDealHttpsRequest(requestDetail) { <span class="hljs-comment">/* ... */</span> }, 
+  <span class="hljs-comment">// error happened when dealing requests</span>
+  *onError(requestDetail, error) { <span class="hljs-comment">/* ... */</span> }, 
+  <span class="hljs-comment">// error happened when connect to https server</span>
+  *onConnectError(requestDetail, error) { <span class="hljs-comment">/* ... */</span> } 
+};</code></pre><blockquote>
+<p>All functions in your rule file, except summary, are all driven by <a href="https://www.npmjs.com/package/co">co</a> . They should be yieldable, i.e. return a promise or be a generator function.</p>
+</blockquote>
+<h3 id="summary"><a class="header-link" href="#summary"></a>summary</h3>
+<h4 id="summary-1"><a class="header-link" href="#summary-1"></a>summary</h4>
+<ul class="list">
+<li>Introduction of this rule file. AnyProxy will read this field and give some tip to user.</li>
+</ul>
+<h3 id="beforesendrequest"><a class="header-link" href="#beforesendrequest"></a>beforeSendRequest</h3>
+<h4 id="beforesendrequest(requestdetail)"><a class="header-link" href="#beforesendrequest(requestdetail)"></a>beforeSendRequest(requestDetail)</h4>
+<ul class="list">
+<li>Before sending request to server, AnyProxy will call <code>beforeSendRequest</code> with param <code>requestDetail</code></li>
+<li><code>requestDetail</code> <ul class="list">
+<li><code>protocol</code> {string} the protocol to use, http or https</li>
+<li><code>requestOptions</code> {object} the options of the request-to-go, a param of require(&#39;http&#39;).request . ref: <a href="https://nodejs.org/api/http.html#http_http_request_options_callback">https://nodejs.org/api/http.html#http_http_request_options_callback</a></li>
+<li><code>requestData</code> {object} request body</li>
+<li><code>url</code> {string} request url</li>
+<li><code>_req</code> {object} the native node.js request object</li>
+</ul>
+</li>
+<li><p>e.g. When requesting  <em>anyproxy.io</em>, <code>requestDetail</code> is something like the following</p>
+<pre class="hljs"><code>{
+  <span class="hljs-attr">protocol</span>: <span class="hljs-string">'http'</span>,
+  <span class="hljs-attr">url</span>: <span class="hljs-string">'http://anyproxy.io/'</span>,
+  <span class="hljs-attr">requestOptions</span>: {
+    <span class="hljs-attr">hostname</span>: <span class="hljs-string">'anyproxy.io'</span>,
+    <span class="hljs-attr">port</span>: <span class="hljs-number">80</span>,
+    <span class="hljs-attr">path</span>: <span class="hljs-string">'/'</span>,
+    <span class="hljs-attr">method</span>: <span class="hljs-string">'GET'</span>,
+    <span class="hljs-attr">headers</span>: {
+      <span class="hljs-attr">Host</span>: <span class="hljs-string">'anyproxy.io'</span>,
+      <span class="hljs-string">'Proxy-Connection'</span>: <span class="hljs-string">'keep-alive'</span>,
+      <span class="hljs-string">'User-Agent'</span>: <span class="hljs-string">'...'</span>
+    }
+  },
+  <span class="hljs-attr">requestData</span>: <span class="hljs-string">'...'</span>,
+  <span class="hljs-attr">_req</span>: { <span class="hljs-comment">/* ... */</span>}
+}</code></pre></li>
+<li><p>Any of these return values are valid</p>
+<ul class="list">
+<li>do nothing, and return null</li>
+</ul>
+<pre class="hljs"><code><span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;</code></pre><ul class="list">
+<li>modify the request protocol,i.e. force use https</li>
+</ul>
+<pre class="hljs"><code><span class="hljs-keyword">return</span> {
+  <span class="hljs-attr">protocol</span>: <span class="hljs-string">'https'</span>
+};</code></pre><ul class="list">
+<li>modify request param</li>
+</ul>
+<pre class="hljs"><code><span class="hljs-keyword">var</span> newOption = <span class="hljs-built_in">Object</span>.assign({}, requestDetail.requestOptions);
+newOption.path = <span class="hljs-string">'/redirect/to/another/path'</span>;
+<span class="hljs-keyword">return</span> {
+  <span class="hljs-attr">requestOptions</span>: newOption
+};</code></pre><ul class="list">
+<li>modify request body</li>
+</ul>
+<pre class="hljs"><code><span class="hljs-keyword">return</span> {
+  <span class="hljs-attr">requestData</span>: <span class="hljs-string">'my new request data'</span>
+  <span class="hljs-comment">// requestOptions can also be used here</span>
+};</code></pre><ul class="list">
+<li>give response to the client, not sending request any longer. <code>statusCode</code> <code>headers</code>are required is this situation.</li>
+</ul>
+<pre class="hljs"><code><span class="hljs-keyword">return</span> {
+  <span class="hljs-attr">response</span>: {
+    <span class="hljs-attr">statusCode</span>: <span class="hljs-number">200</span>,
+    <span class="hljs-attr">header</span>: { <span class="hljs-string">'content-type'</span>: <span class="hljs-string">'text/html'</span> },
+    <span class="hljs-attr">body</span>: <span class="hljs-string">'this could be a &lt;string&gt; or &lt;buffer&gt;'</span>
+  }
+};</code></pre></li>
+</ul>
+<h3 id="beforesendresponse"><a class="header-link" href="#beforesendresponse"></a>beforeSendResponse</h3>
+<h4 id="beforesendresponse(requestdetail,-responsedetail)"><a class="header-link" href="#beforesendresponse(requestdetail,-responsedetail)"></a>beforeSendResponse(requestDetail, responseDetail)</h4>
+<ul class="list">
+<li>Before sending response to client, AnyProxy will call <code>beforeSendResponse</code> with param <code>requestDetail</code> <code>responseDetail</code></li>
+<li><code>requestDetail</code> is the same param as in <code>beforeSendRequest</code></li>
+<li><code>responseDetail</code> <ul class="list">
+<li><code>response</code> {object} the response from server, includes <code>statusCode</code> <code>header</code> <code>body</code></li>
+<li><code>_res</code> {object} the native node.js response object</li>
+</ul>
+</li>
+<li><p>e.g. When requesting <em>anyproxy.io</em>, <code>responseDetail</code> is something like the following</p>
+<pre class="hljs"><code>{ 
+  <span class="hljs-attr">response</span>: { 
+    <span class="hljs-attr">statusCode</span>: <span class="hljs-number">200</span>,
+    <span class="hljs-attr">header</span>: { 
+      <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'image/gif'</span>,
+      <span class="hljs-attr">Connection</span>: <span class="hljs-string">'close'</span>,
+      <span class="hljs-string">'Cache-Control'</span>: <span class="hljs-string">'...'</span>
+    },
+    <span class="hljs-attr">body</span>: <span class="hljs-string">'...'</span>
+  },
+  <span class="hljs-attr">_res</span>: { <span class="hljs-comment">/* ... */</span> }
+}</code></pre></li>
+<li><p>Any of these return values are valid</p>
+<ul class="list">
+<li>do nothing, and return null</li>
+</ul>
+<pre class="hljs"><code><span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;</code></pre><ul class="list">
+<li>modify the response status code</li>
+</ul>
+<pre class="hljs"><code><span class="hljs-keyword">var</span> newResponse = <span class="hljs-built_in">Object</span>.assign({}, responseDetail.reponse);
+newResponse.statusCode = <span class="hljs-number">404</span>;
+<span class="hljs-keyword">return</span> {
+  <span class="hljs-attr">response</span>: newResponse
+};</code></pre><ul class="list">
+<li>modify the response content</li>
+</ul>
+<pre class="hljs"><code><span class="hljs-keyword">var</span> newResponse = <span class="hljs-built_in">Object</span>.assign({}, responseDetail.reponse);
+newResponse.body += <span class="hljs-string">'--from anyproxy--'</span>;
+<span class="hljs-keyword">return</span> {
+  <span class="hljs-attr">response</span>: newResponse
+};</code></pre></li>
+</ul>
+<h3 id="beforedealhttpsrequest"><a class="header-link" href="#beforedealhttpsrequest"></a>beforeDealHttpsRequest</h3>
+<h4 id="beforedealhttpsrequest(requestdetail)"><a class="header-link" href="#beforedealhttpsrequest(requestdetail)"></a>beforeDealHttpsRequest(requestDetail)</h4>
+<ul class="list">
+<li>When receiving https request, AnyProxy will call <code>beforeDealHttpsRequest</code> with param <code>requestDetail</code></li>
+<li>If configed with <code>forceProxyHttps</code> in launching, AnyProxy will skip calling this method</li>
+<li>Only by returning true, AnyProxy will try to replace the certificate and intercept the https request.</li>
+<li><code>requestDetail</code><ul class="list">
+<li><code>host</code> {string} the target host to request. Due to the request protocol, full url couldn&#39;t be got here</li>
+<li><code>_req</code> {object} the native node.js request object. The <code>_req</code> here refers to the CONNECT request.</li>
+</ul>
+</li>
+<li>return value<ul class="list">
+<li><code>true</code> or <code>false</code>, whether AnyProxy should intercept the https request</li>
+</ul>
+</li>
+</ul>
+<h3 id="onerror"><a class="header-link" href="#onerror"></a>onError</h3>
+<h4 id="onerror(requestdetail,-error)"><a class="header-link" href="#onerror(requestdetail,-error)"></a>onError(requestDetail, error)</h4>
+<ul class="list">
+<li>AnyProxy will call this method when an error happened in request handling.</li>
+<li>Errors usually are issued during requesting, e.g. DNS failure, request timeout</li>
+<li><code>requestDetail</code> is the same one as in <code>beforeSendRequest</code></li>
+<li><p>Any of these return values are valid</p>
+<ul class="list">
+<li>do nothing, and AnyProxy will response a default error page</li>
+</ul>
+<pre class="hljs"><code><span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;</code></pre><ul class="list">
+<li>return a customized error page</li>
+</ul>
+<pre class="hljs"><code><span class="hljs-keyword">return</span> {
+  <span class="hljs-attr">response</span>: {
+    <span class="hljs-attr">statusCode</span>: <span class="hljs-number">200</span>,
+    <span class="hljs-attr">header</span>: { <span class="hljs-string">'content-type'</span>: <span class="hljs-string">'text/html'</span> },
+    <span class="hljs-attr">body</span>: <span class="hljs-string">'this could be a &lt;string&gt; or &lt;buffer&gt;'</span>
+  }
+};</code></pre></li>
+</ul>
+<h3 id="onconnecterror"><a class="header-link" href="#onconnecterror"></a>onConnectError</h3>
+<h4 id="onconnecterror(requestdetail,-error)"><a class="header-link" href="#onconnecterror(requestdetail,-error)"></a>onConnectError(requestDetail, error)</h4>
+<ul class="list">
+<li>AnyProxy will call this method when failed to connect target server in https request</li>
+<li><code>requestDetail</code> is the same one as in <code>beforeDealHttpsRequest</code></li>
+<li>no return value is required </li>
+</ul>
+<h3 id="faq"><a class="header-link" href="#faq"></a>FAQ</h3>
+<ul class="list">
+<li>Q: can not deal https request in rule module.</li>
+<li><p>A: Any of these options could be used to change the way AnyProxy deall https requests </p>
+<ol class="list">
+<li>config <code>--intercept</code> when luanching AnyProxy via cli, or use <code>forceProxyHttps</code> when using as an npm module</li>
+<li>place a <code>beforeDealHttpsRequest</code> function in your rule file and determine which request to intercept by your own.</li>
+</ol>
+</li>
+<li><p>Q: get an error says <em>function is not yieldable</em></p>
+</li>
+<li>A: Rule module is driven by <a href="https://www.npmjs.com/package/co">co</a>. The functions inside should  be yieldable, i.e. return a promise or be a generator function.</li>
+</ul>
+<h2 id="rule-samples"><a class="header-link" href="#rule-samples"></a>Rule Samples</h2>
+<ul class="list">
+<li>here are some samples about frequently used rule file</li>
+<li>try these samples by <code>anyproxy --rule http://....js</code></li>
+<li>how to test with curl:<ul class="list">
+<li>request the server directly <code>curl http://httpbin.org/</code></li>
+<li>request the server via proxy <code>curl http://httpbin.org/ --proxy http://127.0.0.1:8001</code></li>
+</ul>
+</li>
+</ul>
+<h3 id="use-local-response"><a class="header-link" href="#use-local-response"></a>use local response</h3>
+<ul class="list">
+<li>intercept the request towards <a href="http://httpbin.org">http://httpbin.org</a> , return the local-defined response</li>
+</ul>
+<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_use_local_response.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
+  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
+*/</span>
+<span class="hljs-built_in">module</span>.exports = {
+  *beforeSendRequest(requestDetail) {
+    <span class="hljs-keyword">const</span> localResponse = {
+      <span class="hljs-attr">statusCode</span>: <span class="hljs-number">200</span>,
+      <span class="hljs-attr">header</span>: { <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'application/json'</span> },
+      <span class="hljs-attr">body</span>: <span class="hljs-string">'{"hello": "this is local response"}'</span>
+    };
+    <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org'</span>) === <span class="hljs-number">0</span>) {
+      <span class="hljs-keyword">return</span> {
+        <span class="hljs-attr">response</span>: localResponse
+      };
+    }
+  },
+};</code></pre><h3 id="modify-request-header"><a class="header-link" href="#modify-request-header"></a>modify request header</h3>
+<ul class="list">
+<li>modify the user-agent sent to httpbin.org</li>
+</ul>
+<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_request_header.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
+  sample: 
+    modify the user-agent in requests toward httpbin.org
+  test:
+    curl http://httpbin.org/user-agent --proxy http://127.0.0.1:8001
+*/</span>
+<span class="hljs-built_in">module</span>.exports = {
+  *beforeSendRequest(requestDetail) {
+    <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org'</span>) === <span class="hljs-number">0</span>) {
+      <span class="hljs-keyword">const</span> newRequestOptions = requestDetail.requestOptions;
+      newRequestOptions.headers[<span class="hljs-string">'User-Agent'</span>] = <span class="hljs-string">'AnyProxy/0.0.0'</span>;
+      <span class="hljs-keyword">return</span> {
+        <span class="hljs-attr">requestOptions</span>: newRequestOptions
+      };
+    }
+  },
+};</code></pre><h3 id="modify-request-body"><a class="header-link" href="#modify-request-body"></a>modify request body</h3>
+<ul class="list">
+<li>modify the post body of <a href="http://httpbin.org/post">http://httpbin.org/post</a></li>
+</ul>
+<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_request_data.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
+  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" }
+*/</span>
+<span class="hljs-built_in">module</span>.exports = {
+  *beforeSendRequest(requestDetail) {
+    <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org/post'</span>) === <span class="hljs-number">0</span>) {
+      <span class="hljs-keyword">return</span> {
+        <span class="hljs-attr">requestData</span>: <span class="hljs-string">'i-am-anyproxy-modified-post-data'</span>
+      };
+    }
+  },
+};</code></pre><h3 id="modify-the-request-target"><a class="header-link" href="#modify-the-request-target"></a>modify the request target</h3>
+<ul class="list">
+<li>send all the request towards <a href="http://httpbin.org/">http://httpbin.org/</a> to <a href="http://httpbin.org/user-agent">http://httpbin.org/user-agent</a></li>
+</ul>
+<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_request_path.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
+  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" }
+*/</span>
+<span class="hljs-built_in">module</span>.exports = {
+  *beforeSendRequest(requestDetail) {
+    <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org'</span>) === <span class="hljs-number">0</span>) {
+      <span class="hljs-keyword">const</span> newRequestOptions = requestDetail.requestOptions;
+      newRequestOptions.path = <span class="hljs-string">'/user-agent'</span>;
+      newRequestOptions.method = <span class="hljs-string">'GET'</span>;
+      <span class="hljs-keyword">return</span> {
+        <span class="hljs-attr">requestOptions</span>: newRequestOptions
+      };
+    }
+  },
+};</code></pre><h3 id="modify-request-protocol"><a class="header-link" href="#modify-request-protocol"></a>modify request protocol</h3>
+<ul class="list">
+<li>modify the http request towards <a href="http://httpbin.org">http://httpbin.org</a> to https</li>
+</ul>
+<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_request_protocol.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
+  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" }
+*/</span>
+<span class="hljs-built_in">module</span>.exports = {
+  *beforeSendRequest(requestDetail) {
+    <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org'</span>) === <span class="hljs-number">0</span>) {
+      <span class="hljs-keyword">const</span> newOption = requestDetail.requestOptions;
+      newOption.port = <span class="hljs-number">443</span>;
+      <span class="hljs-keyword">return</span> {
+        <span class="hljs-attr">protocol</span>: <span class="hljs-string">'https'</span>,
+        <span class="hljs-attr">requestOptions</span>: newOption
+      };
+    }
+  }
+};</code></pre><h3 id="modify-response-status-code"><a class="header-link" href="#modify-response-status-code"></a>modify response status code</h3>
+<ul class="list">
+<li>modify all status code from <a href="http://httpbin.org">http://httpbin.org</a> to 404</li>
+</ul>
+<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_response_statuscode.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
+  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
+*/</span>
+<span class="hljs-built_in">module</span>.exports = {
+  *beforeSendResponse(requestDetail, responseDetail) {
+    <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org'</span>) === <span class="hljs-number">0</span>) {
+      <span class="hljs-keyword">const</span> newResponse = responseDetail.response;
+      newResponse.statusCode = <span class="hljs-number">404</span>;
+      <span class="hljs-keyword">return</span> {
+        <span class="hljs-attr">response</span>: newResponse
+      };
+    }
+  }
+};</code></pre><h3 id="modify-the-response-header"><a class="header-link" href="#modify-the-response-header"></a>modify the response header</h3>
+<ul class="list">
+<li>add X-Proxy-By:AnyProxy to the response header from <a href="http://httpbin.org/user-agent">http://httpbin.org/user-agent</a></li>
+</ul>
+<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_response_header.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
+  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
+*/</span>
+<span class="hljs-built_in">module</span>.exports = {
+  *beforeSendResponse(requestDetail, responseDetail) {
+    <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org/user-agent'</span>) === <span class="hljs-number">0</span>) {
+      <span class="hljs-keyword">const</span> newResponse = responseDetail.response;
+      newResponse.header[<span class="hljs-string">'X-Proxy-By'</span>] = <span class="hljs-string">'AnyProxy'</span>;
+      <span class="hljs-keyword">return</span> {
+        <span class="hljs-attr">response</span>: newResponse
+      };
+    }
+  }
+};</code></pre><h3 id="modify-response-data-and-delay"><a class="header-link" href="#modify-response-data-and-delay"></a>modify response data and delay</h3>
+<ul class="list">
+<li>append some info to the response of <a href="http://httpbin.org/user-agent">http://httpbin.org/user-agent</a>, then delay the response for 5 seconds.</li>
+</ul>
+<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_response_data.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
+  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! --
+*/</span>
+
+<span class="hljs-built_in">module</span>.exports = {
+  *beforeSendResponse(requestDetail, responseDetail) {
+    <span class="hljs-keyword">if</span> (requestDetail.url === <span class="hljs-string">'http://httpbin.org/user-agent'</span>) {
+      <span class="hljs-keyword">const</span> newResponse = responseDetail.response;
+      newResponse.body += <span class="hljs-string">'-- AnyProxy Hacked! --'</span>;
+      <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =&gt;</span> {
+        setTimeout(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> { <span class="hljs-comment">// delay the response for 5s</span>
+          resolve({ <span class="hljs-attr">response</span>: newResponse });
+        }, <span class="hljs-number">5000</span>);
+      });
+    }
+  },
+};</code></pre><h2 id="use-anyproxy-as-an-npm-module"><a class="header-link" href="#use-anyproxy-as-an-npm-module"></a>Use AnyProxy as an npm module</h2>
+<p>AnyProxy can be used as an npm module</p>
+<blockquote>
+<p>To enable https feature, please guide users to use <code>anyproxy-ca</code> in cli. Or use methods under <code>AnyProxy.utils.certMgr</code> to generate certificates.</p>
+</blockquote>
+<ul class="list">
+<li>install</li>
+</ul>
+<pre class="hljs"><code>npm i anyproxy@beta --save <span class="hljs-comment"># 4.0 is in beta now</span></code></pre><ul class="list">
+<li>sample</li>
+</ul>
+<pre class="hljs"><code><span class="hljs-keyword">const</span> AnyProxy = <span class="hljs-built_in">require</span>(<span class="hljs-string">'anyproxy'</span>);
+<span class="hljs-keyword">const</span> options = {
+  <span class="hljs-attr">port</span>: <span class="hljs-number">8001</span>,
+  <span class="hljs-attr">rule</span>: <span class="hljs-built_in">require</span>(<span class="hljs-string">'myRuleModule'</span>),
+  <span class="hljs-attr">webInterface</span>: {
+    <span class="hljs-attr">enable</span>: <span class="hljs-literal">true</span>,
+    <span class="hljs-attr">webPort</span>: <span class="hljs-number">8002</span>,
+    <span class="hljs-attr">wsPort</span>: <span class="hljs-number">8003</span>,
+  },
+  <span class="hljs-attr">throttle</span>: <span class="hljs-number">10000</span>,
+  <span class="hljs-attr">forceProxyHttps</span>: <span class="hljs-literal">false</span>,
+  <span class="hljs-attr">silent</span>: <span class="hljs-literal">false</span>
+};
+<span class="hljs-keyword">const</span> proxyServer = <span class="hljs-keyword">new</span> AnyProxy.ProxyServer(options);
+
+proxyServer.on(<span class="hljs-string">'ready'</span>, () =&gt; { <span class="hljs-comment">/* */</span> });
+proxyServer.on(<span class="hljs-string">'error'</span>, (e) =&gt; { <span class="hljs-comment">/* */</span> });
+proxyServer.start();
+
+<span class="hljs-comment">//when finished</span>
+proxyServer.close();</code></pre><ul class="list">
+<li><p>Class: AnyProxy.proxyServer</p>
+<ul class="list">
+<li><p>create a proxy server</p>
+<pre class="hljs"><code><span class="hljs-keyword">const</span> proxy = <span class="hljs-keyword">new</span> AnyProxy.proxyServer(options)</code></pre></li>
+<li><p><code>options</code></p>
+<ul class="list">
+<li><code>port</code> {number} required, port number of proxy server</li>
+<li><code>rule</code> {object} your rule module</li>
+<li><code>throttle</code> {number} throttle in kb/s, unlimited for default</li>
+<li><code>forceProxyHttps</code> {boolean} in force intercept all https request, false for default</li>
+<li><code>silent</code> {boolean} if keep silent in console, false for default<code>false</code></li>
+<li><code>dangerouslyIgnoreUnauthorized</code> {boolean} if ignore certificate error in request, false for default</li>
+<li><code>webInterface</code> {object} config for web interface<ul class="list">
+<li><code>enable</code> {boolean} if enable web interface, false for default</li>
+<li><code>webPort</code> {number} port number for web interface</li>
+</ul>
+</li>
+</ul>
+</li>
+<li><p>Event: <code>ready</code></p>
+<ul class="list">
+<li>emit when proxy server is ready</li>
+<li>sample</li>
+</ul>
+<pre class="hljs"><code>proxy.on(<span class="hljs-string">'ready'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{ })</code></pre></li>
+<li><p>Event: <code>error</code></p>
+<ul class="list">
+<li>emit when error happened inside proxy server</li>
+<li>sample</li>
+</ul>
+<pre class="hljs"><code>proxy.on(<span class="hljs-string">'error'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{ })</code></pre></li>
+<li><p>Method: <code>start</code></p>
+<ul class="list">
+<li>start proxy server</li>
+<li>sample</li>
+</ul>
+<pre class="hljs"><code>proxy.start();</code></pre></li>
+<li><p>Method: <code>close</code></p>
+<ul class="list">
+<li>close proxy server</li>
+<li>sample</li>
+</ul>
+<pre class="hljs"><code>proxy.close();</code></pre></li>
+</ul>
+</li>
+<li><p>AnyProxy.utils.systemProxyMgr</p>
+<ul class="list">
+<li>manage the system proxy config. sudo password may be required</li>
+<li>sample</li>
+</ul>
+<pre class="hljs"><code><span class="hljs-comment">// set 127.0.0.1:8001 as system http server</span>
+AnyProxy.utils.systemProxyMgr.enableGlobalProxy(<span class="hljs-string">'127.0.0.1'</span>, <span class="hljs-string">'8001'</span>);    
+
+<span class="hljs-comment">// disable global proxy server</span>
+AnyProxy.utils.systemProxyMgr.disableGlobalProxy();</code></pre></li>
+<li><p>AnyProxy.utils.certMgr</p>
+<ul class="list">
+<li>Manage certificates of AnyProxy</li>
+<li><code>AnyProxy.utils.certMgr.ifRootCAFileExists()</code><ul class="list">
+<li>detect if AnyProx rootCA exists</li>
+</ul>
+</li>
+<li><code>AnyProxy.utils.certMgr.generateRootCA(callback)</code><ul class="list">
+<li>generate a rootCA</li>
+</ul>
+</li>
+<li>Sample</li>
+</ul>
+<pre class="hljs"><code>  <span class="hljs-keyword">const</span> AnyProxy = <span class="hljs-built_in">require</span>(<span class="hljs-string">'AnyProxy'</span>);
+  <span class="hljs-keyword">const</span> exec = <span class="hljs-built_in">require</span>(<span class="hljs-string">'child_process'</span>).exec;
+
+  <span class="hljs-keyword">if</span> (!AnyProxy.utils.certMgr.ifRootCAFileExists()) {
+    AnyProxy.utils.certMgr.generateRootCA(<span class="hljs-function">(<span class="hljs-params">error, keyPath</span>) =&gt;</span> {
+      <span class="hljs-comment">// let users to trust this CA before using proxy</span>
+      <span class="hljs-keyword">if</span> (!error) {
+        <span class="hljs-keyword">const</span> certDir = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>).dirname(keyPath);
+        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'The cert is generated at'</span>, certDir);
+        <span class="hljs-keyword">const</span> isWin = <span class="hljs-regexp">/^win/</span>.test(process.platform);
+        <span class="hljs-keyword">if</span> (isWin) {
+          exec(<span class="hljs-string">'start .'</span>, { <span class="hljs-attr">cwd</span>: certDir });
+        } <span class="hljs-keyword">else</span> {
+          exec(<span class="hljs-string">'open .'</span>, { <span class="hljs-attr">cwd</span>: certDir });
+        }
+      } <span class="hljs-keyword">else</span> {
+        <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'error when generating rootCA'</span>, error);
+      }
+    });
+  }</code></pre></li>
+</ul>
+<h2 id="about-anyproxy"><a class="header-link" href="#about-anyproxy"></a>About AnyProxy</h2>
+<ul class="list">
+<li>Change Log: <a href="https://github.com/alibaba/anyproxy/blob/master/CHANGELOG">https://github.com/alibaba/anyproxy/blob/master/CHANGELOG</a></li>
+<li>Github:<a href="https://github.com/alibaba/anyproxy">https://github.com/alibaba/anyproxy</a></li>
+<li>issue:<a href="https://github.com/alibaba/anyproxy/issues">https://github.com/alibaba/anyproxy/issues</a></li>
+</ul>
+<h2 id="appendix"><a class="header-link" href="#appendix"></a>Appendix</h2>
+<h3 id="config-root-ca-in-osx"><a class="header-link" href="#config-root-ca-in-osx"></a>Config root CA in OSX</h3>
+<ul class="list">
+<li>this kind of errors is usually caused by untrusted root CA</li>
+</ul>
+<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/CBkLGYgvoHAYwNVAYkpk.png" width="450" /></p>
+<blockquote>
+<p>Warning: please keep your root CA safe since it may influence your system security.</p>
+</blockquote>
+<p>install :</p>
+<ul class="list">
+<li><p>double click <em>rootCA.crt</em></p>
+</li>
+<li><p>add cert into login or system</p>
+</li>
+</ul>
+<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/bCwNUFFpvsmVuljQKrIk.png" width="350" /></p>
+<ul class="list">
+<li>find the newly imported AnyProxy certificates, configured as <strong>Always Trust</strong></li>
+</ul>
+<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/HOmEElNGdoZEWFMLsTNT.png" width="700" /></p>
+<h3 id="trust-root-ca-in-windows"><a class="header-link" href="#trust-root-ca-in-windows"></a>trust root CA in windows</h3>
+<p class="img-container"><img src="https://t.alipayobjects.com/tfscom/T1D3hfXeFtXXXXXXXX.jpg" width="700" /></p>
+<h3 id="config-osx-system-proxy"><a class="header-link" href="#config-osx-system-proxy"></a>config OSX system proxy</h3>
+<ul class="list">
+<li>the config is in wifi - advanced</li>
+</ul>
+<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/vduwhobSTypTfgniBvoa.png" width="500" /></p>
+<h3 id="config-http-proxy-server"><a class="header-link" href="#config-http-proxy-server"></a>config http proxy server</h3>
+<ul class="list">
+<li>take Chrome extent [SwitchyOmega] as an example(<a href="https://chrome.google.com/webstore/detail/padekgcemlokbadohgkifijomclgjgif)为例">https://chrome.google.com/webstore/detail/padekgcemlokbadohgkifijomclgjgif)为例</a></li>
+</ul>
+<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/jIPZrKmqXRaSledQeJUJ.png" width="500" /></p>
+<h3 id="trust-root-ca-in-ios"><a class="header-link" href="#trust-root-ca-in-ios"></a>trust root CA in iOS</h3>
+<ul class="list">
+<li>Click <em>Root CA</em> in web ui, and follow the instruction to install</li>
+</ul>
+<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/BrugmMelGVysLDOIBblj.png" width="260" /></p>
+<h3 id="trust-root-ca-in-ios->=-10.3"><a class="header-link" href="#trust-root-ca-in-ios->=-10.3"></a>trust root CA in iOS &gt;= 10.3</h3>
+<ul class="list">
+<li>Besides installing root CA, you have to &quot;turn on&quot; the certificate for web manually in <em>settings - general - about - Certificate Trust Settings</em>. Otherwire, safari will not trust the root CA generated by AnyProxy.</li>
+</ul>
+<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/hVWkXHrzHmOKOtCKGUWx.png" width="500" /></p>
+<h3 id="config-ios/android-proxy-server"><a class="header-link" href="#config-ios/android-proxy-server"></a>config iOS/Android proxy server</h3>
+<ul class="list">
+<li><p>proxy settings are placed in wifi setting</p>
+</li>
+<li><p>iOS</p>
+</li>
+</ul>
+<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/tLGqIozhffTccUgPakuw.png" width="260" /></p>
+<ul class="list">
+<li>Android</li>
+</ul>
+<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/YQtbQYVNuOszZGdAOauU.png" width="260" /></p>
+    </div>
+  </article>
+
+  <script src="//cdn.bootcss.com/zepto/1.2.0/zepto.min.js"></script>
+  <script>
+  window.onload = function(){
+    var itemList = [];
+    var targetMap = {};
+    $("[id]", ".main-content").map(function (index, heading) {
+      targetMap[heading.getAttribute('id')] = heading;
+    });
+
+    $("#j_toc li").map(function (index, item) {
+      if (item.className.indexOf('sidebar-header-2') >= 0 || item.className.indexOf('sidebar-header-3') >= 0) {
+        var targetName = item.firstChild.getAttribute('href').replace('#', '');
+        var targetItem = targetMap[targetName];
+        itemList.push({ target: targetItem, tocItem: item, top: $(targetItem).position().top });
+      }
+    });
+
+    var updateTocActive = function (e) {
+      var windowHeight = window.innerHeight;
+      //find the first item to match
+      var scrollYThres = window.scrollY + 200;
+      var target;
+      if (scrollYThres < 100) {
+        target = itemList[0].tocItem;
+      } else {
+        itemList.forEach(function (item, index) {
+          if (target) return;
+          if (index > 0) {
+            if (item.top >= scrollYThres) {
+              target = itemList[index - 1].tocItem;
+            }
+          }
+        });
+      }
+
+      $('.toc-active').removeClass('toc-active');
+      $(target).addClass('toc-active');
+    };
+
+    window.onscroll = updateTocActive;
+    updateTocActive();
+  }
+  </script>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/en/index.html b/en/index.html
deleted file mode 100644
index 5b6dad1..0000000
--- a/en/index.html
+++ /dev/null
@@ -1,243 +0,0 @@
-<html>
-<head>
-    <title>AnyProxy</title>
-    <link rel="stylesheet" type="text/css" href="/dest/index.css">
-    <link rel="shortcut icon" type="image/png" href="/favico.png?t=2" />
-    <meta name="description" content="A fully configurable proxy in NodeJS, which can handle HTTPS requests perfectly.">
-    <meta name="description" content="AnyProxy - 开放式的HTTP/HTTPS代理,你可以灵活控制各种网络数据">
-    <meta name="keywords" content="代理服务器 Proxy HTTP HTTPS">
-    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
-    <script> 
-        //redirect to Chinese version if in China
-        if(new Date().getTimezoneOffset() == "-480" && !(/(cn|en)/i.test(location.href))){
-            location.href = "/cn";
-        }else{
-            var _hmt = _hmt || []; (function() {var hm = document.createElement("script"); hm.src = "//hm.baidu.com/hm.js?4e51565b7d471fd6623c163a8fd79e07"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })();
-        }
-    </script>
-
-</head>
-<body>
-
-    <div class="wrapper">
-        <div class="cornerBtnWrapper">
-            <a href="/cn">中文</a>|
-            <a href="/en">English</a>|
-            <a href="https://github.com/alibaba/anyproxy" target="_blank">View on Github</a>
-        </div>
-
-        <div class="brief">
-            <div class="logo">
-                <img src="http://gtms04.alicdn.com/tps/i4/TB1XfxDHpXXXXXpapXX20ySQVXX-512-512.png" width="250" height="250" alt="anyproxy logo" />
-            </div>
-            <h2 class="slogan">AnyProxy 4.x is in beta release. <a href="/4.x/">Have a try.</a></h2>
-            <div class="action">
-                <iframe src="https://ghbtns.com/github-btn.html?user=alibaba&repo=anyproxy&type=star&count=true" frameborder="0" scrolling="0" width="100px" height="20px"></iframe>&nbsp;&nbsp;&nbsp;
-                <iframe src="https://ghbtns.com/github-btn.html?user=alibaba&repo=anyproxy&type=fork&count=true" frameborder="0" scrolling="0" width="100px" height="20px"></iframe>
-            </div>
-        </div>
-
-        <div class="feature">
-            <div class="featureContent">
-                <div class="item">
-                    <span class="iconWrapper">
-                        <i class="iconfont">&#xe602;</i>
-                    </span>
-                    <h4>Based on Node.js</h4>
-                    <h5>It&#x27;s all javascript and easy to learn.</h5>
-                </div>
-                <div class="item">
-                    <span class="iconWrapper">
-                        <i class="iconfont">&#xe601;</i>
-                    </span>
-                    <h4>HTTPS supported</h4>
-                    <h5>help to decrypted HTTPS data<a href="https://github.com/alibaba/anyproxy/wiki/HTTPS%E7%9B%B8%E5%85%B3%E6%95%99%E7%A8%8B" target="_blank"><br>How to config&nbsp;&gt;&gt;</a></h5>
-                </div>
-                <div class="item">
-                    <span class="iconWrapper">
-                        <i class="iconfont bigger">&#xe600;</i>
-                    </span>
-                    <h4>Web UI</h4>
-                    <h5>Web based interface to view requests</h5>
-                </div>
-                <div class="item">
-                    <span class="iconWrapper">
-                        <i class="iconfont">&#xe604;</i>
-                    </span>
-                    <h4>Customed Rule File</h4>
-                    <h5>Make your own debugging tool by writing rule files</h5>
-                </div>
-                <div style="clear:both"></div>
-            </div>
-        </div>
-
-        <div class="quickstart listSection">
-            <div class="quickstartContent listContent">
-                <h4 class="subtitle" id="install">Installation</h4>
-                <ul>
-                    <li>install <a href="http://nodejs.org/" target="_blank">Node.js</a> &gt;= v0.12</li>
-                    <li><code class="simpleBash">npm install -g anyproxy</code>, may require<code class="simpleBash">sudo</code></li>
-                    <li><a href="https://github.com/alibaba/anyproxy#quick-start" target="_blank">More&gt;&gt;</a></li>
-                </ul>
-                <h4 class="subtitle" id="quickstart">Quick Start</h4>
-                <ul>
-                    <li>run&nbsp;&nbsp;<code class="simpleBash">anyproxy</code></li>
-                    <li>set proxy to 127.0.0.1:8001 on your browser or device</li>
-                    <li>view web interface at http://127.0.0.1:8002</li>
-                    <li><a href="https://github.com/alibaba/anyproxy#quick-start" target="_blank">More Usage&nbsp;&gt;&gt;</a></li>
-                </ul>
-                <a href="https://github.com/alibaba/anyproxy#step-4---launch-web-interface" target="_blank"><img class="screenshot" src="http://gtms01.alicdn.com/tps/i1/TB1IdgqGXXXXXa9apXXLExM2pXX-854-480.gif" width="350"/></a>
-            </div>
-        </div>
-
-        <div class="sample">
-
-            <div class="sampleContent">
-                <h4 class="subtitle" id="sample ">Sample of Rule Files</h4>
-
-                <div class="item">
-                    <h5 class="itemTitle">Append &quot;hello world&quot; on HTML response</h5>
-                    <pre>
-<code class="javascript">
-//append "hello world" to all web pages
-//file : rule_replace_response_data.js
-//run  : anyproxy --rule rule_replace_response_data.js
-module.exports = {
-    replaceServerResDataAsync: function(req,res,serverRes,cb){
-
-        if(/html/i.test(res.headers['content-type'])){
-            var newDataStr = serverRes.toString();
-            newDataStr += "hello world!";
-            cb(newDataStr);
-        }
-    }
-};
-</code>
-                    </pre>
-                    <span class="figure">
-                        <img src="https://t.alipayobjects.com/images/rmsweb/T1LcphXf0eXXXXXXXX.png" width="350"/>
-                    </span>
-                    <hr />
-                </div>              
-                <div class="item">
-                    <h5 class="itemTitle">remove if-modified-since from http request header</h5>
-                    <pre>
-<code class="javascript">
-//remove cache related header
-//file : rule_remove_cache_header.js
-//run  : anyproxy --rule rule_remove_cache_header.js
-module.exports = {
-    replaceRequestOption : function(req,option){
-        var newOption = option;
-        delete newOption.headers['if-modified-since'];
-
-        return newOption;
-    }
-};
-</code>
-                    </pre>
-                    <span class="figure">
-                        <img src="https://t.alipayobjects.com/images/rmsweb/T1ecFhXjxcXXXXXXXX.png" width="350"/>
-                    </span>
-                    <hr />
-                </div>
-
-                <div class="item">
-                    <h5 class="itemTitle">assign a specified ip address for some requests</h5>
-                    <pre>
-<code class="javascript">
-//assign a specific IP adress for some request
-//file : rule_reverse_proxy.js
-//run  : anyproxy --rule anyproxy --rule rule_reverse_proxy.js
-module.exports = {
-    replaceRequestOption : function(req,option){
-        var newOption = option;
-        if(newOption.headers.host == "www.taobao.com"){
-            newOption.hostname = "192.168.1.3";
-            newOption.port     = "80";
-        }
-
-        return newOption;
-    }
-};
-</code>
-                    </pre>
-                    <span class="figure">
-                        <img src="https://t.alipayobjects.com/images/rmsweb/T1hsxhXeddXXXXXXXX.png" width="350"/>
-                    </span>
-                    <hr />
-                </div>
-
-                <div class="item">
-                    <h5 class="itemTitle">replace all image response by local one</h5>
-                    <pre>
-<code class="javascript">
-//replace all the images with local one
-//file : rule_use_local_data.js
-//run  : anyproxy --rule anyproxy --rule rule_use_local_data.js
-var fs  = require("fs"),
-    img = fs.readFileSync("sample.jpg");
-
-module.exports = {
-    shouldUseLocalResponse : function(req,reqBody){
-        if(/\.(png|gif|jpg|jpeg)$/.test(req.url)){
-            req.replaceLocalFile = true;
-            return true;
-        }else{
-            return false;
-        }
-    },
-
-    dealLocalResponse : function(req,reqBody,callback){
-        if(req.replaceLocalFile){
-            callback(200, {"content-type":"image/png"},img );
-        }
-    }
-};
-</code>
-                    </pre>
-                    <span class="figure">
-                        <img src="https://t.alipayobjects.com/images/rmsweb/T1Zr4hXeXhXXXXXXXX.png" width="350"/>
-                    </span>
-                </div>
-
-                <div class="readmoreBtn">
-                    <a href="https://github.com/alibaba/anyproxy/wiki/What-is-rule-file-and-how-to-write-one" target="_blank">&gt;&gt;&nbsp;Ref : Guide of Rule file</a>
-                </div>
-
-            </div>
-        </div>
-
-        <div class="readMore listSection">
-            <div class="listContent">
-                <h4 class="subtitle" id="otherfeature">Other Features</h4>
-                <ul>
-                    <li>Map file to local , filter your logs</li>
-                    <li><a href="https://github.com/alibaba/anyproxy#throttling">Simulate a low-speed network</a> , help to test the performance of your app on poor network</li>
-                    <li><a href="https://github.com/alibaba/anyproxy#work-as-a-module-for-nodejs" target="_blank">Using AnyProxy as an npm module</a> , to deploy your own debugging tools</li>
-                </ul>
-            </div>
-        </div>
-
-        <div class="learnMore listSection">
-            <div class="btnWrapper">
-                <h4 class="subtitle white" id="readmore">Read More</h4>
-                <a class="actionBtn actionBtnWhite" href="https://github.com/alibaba/anyproxy" target="_blank">https://github.com/alibaba/anyproxy</a>
-            </div>
-        </div>
-
-        <div class="footer"></div>
-
-    </div>
-
-    <link rel="stylesheet" type="text/css" href="/dest/github.css" />
-    <script src="/dest/lib.js"></script>
-    <script type="text/javascript">
-        Zepto(document).ready(function() {
-            Zepto('.sample code').each(function(i, block) {
-                hljs.highlightBlock(block);
-            });
-        });
-    </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/gulpfile.js b/gulpfile.js
deleted file mode 100644
index 407ea12..0000000
--- a/gulpfile.js
+++ /dev/null
@@ -1,35 +0,0 @@
-var fs     = require("fs"),
-	Juicer = require("juicer"),
-	gulp   = require("gulp"),
-	less   = require("gulp-less"),
-	path   = require('path');
- 
-Juicer.set('strip',false);
-
-gulp.task('less', function(){
- 	return gulp.src('./src/*.less')
-	    .pipe(less())
-	    .pipe(gulp.dest('./dest/'));
-});
-
-gulp.task("page",function(){
-	var i18nConfig = JSON.parse(fs.readFileSync("./src/i18n.json",{encoding :"utf8"})),
-		pageTpl    = Juicer(fs.readFileSync("./src/index.html",{encoding : "utf8"}) );
-
-	// console.log(pageTpl);
-	var pageCN = pageTpl.render(i18nConfig.cn),
-		pageEN = pageTpl.render(i18nConfig.en);
-
-	fs.writeFileSync("./cn/index.html",pageCN);
-	fs.writeFileSync("./en/index.html",pageEN);
-
-	fs.writeFileSync("./index.html",pageEN);
-});
-
-gulp.task("watch",function(){
-	gulp.watch('./src/*', ['less','page']);
-});
-
-gulp.task("default",["less","page"],function(){
-
-});
\ No newline at end of file
diff --git a/index.html b/index.html
index 5b6dad1..3ee6ab7 100644
--- a/index.html
+++ b/index.html
@@ -1,243 +1,832 @@
+<!doctype html>
 <html>
+
 <head>
-    <title>AnyProxy</title>
-    <link rel="stylesheet" type="text/css" href="/dest/index.css">
-    <link rel="shortcut icon" type="image/png" href="/favico.png?t=2" />
-    <meta name="description" content="A fully configurable proxy in NodeJS, which can handle HTTPS requests perfectly.">
-    <meta name="description" content="AnyProxy - 开放式的HTTP/HTTPS代理,你可以灵活控制各种网络数据">
-    <meta name="keywords" content="代理服务器 Proxy HTTP HTTPS">
-    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
-    <script> 
-        //redirect to Chinese version if in China
-        if(new Date().getTimezoneOffset() == "-480" && !(/(cn|en)/i.test(location.href))){
-            location.href = "/cn";
-        }else{
-            var _hmt = _hmt || []; (function() {var hm = document.createElement("script"); hm.src = "//hm.baidu.com/hm.js?4e51565b7d471fd6623c163a8fd79e07"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })();
-        }
-    </script>
-
+  <meta charset="utf-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1, minimal-ui">
+  <title>AnyProxy</title>
+  <link type="text/css" rel="stylesheet" href="assets/css/github-markdown.css">
+  <link type="text/css" rel="stylesheet" href="assets/css/pilcrow.css">
+  <link type="text/css" rel="stylesheet" href="assets/css/atom-one-light.css" />
+  <link type="text/css" rel="stylesheet" href="assets/css/custom.css" />
+  <meta name="description" content="A fully configurable proxy in NodeJS, which can handle HTTPS requests perfectly.">
+  <meta name="description" content="AnyProxy - 开放式的HTTP/HTTPS代理,你可以灵活控制各种网络数据">
+  <meta name="keywords" content="代理服务器 Proxy HTTP HTTPS">
+  <script>
+    //redirect to Chinese version if in China
+    if (new Date().getTimezoneOffset() == "-480" && !(/(cn|en)/i.test(location.href))) {
+      location.href = "./cn.html";
+    } else {
+      var _hmt = _hmt || []; (function () { var hm = document.createElement("script"); hm.src = "//hm.baidu.com/hm.js?4e51565b7d471fd6623c163a8fd79e07"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })();
+    }
+  </script>
 </head>
+
 <body>
+  <a href="https://github.com/alibaba/anyproxy/tree/4.x" target="_blank">
+    <img style="position: fixed; top: 0; right: 0; border: 0;z-index: 1;" src="https://camo.githubusercontent.com/a6677b08c955af8400f44c6298f40e7d19cc5b2d/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f677261795f3664366436642e706e67"
+      alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_gray_6d6d6d.png">
+  </a>
 
-    <div class="wrapper">
-        <div class="cornerBtnWrapper">
-            <a href="/cn">中文</a>|
-            <a href="/en">English</a>|
-            <a href="https://github.com/alibaba/anyproxy" target="_blank">View on Github</a>
-        </div>
-
-        <div class="brief">
-            <div class="logo">
-                <img src="http://gtms04.alicdn.com/tps/i4/TB1XfxDHpXXXXXpapXX20ySQVXX-512-512.png" width="250" height="250" alt="anyproxy logo" />
-            </div>
-            <h2 class="slogan">AnyProxy 4.x is in beta release. <a href="/4.x/">Have a try.</a></h2>
-            <div class="action">
-                <iframe src="https://ghbtns.com/github-btn.html?user=alibaba&repo=anyproxy&type=star&count=true" frameborder="0" scrolling="0" width="100px" height="20px"></iframe>&nbsp;&nbsp;&nbsp;
-                <iframe src="https://ghbtns.com/github-btn.html?user=alibaba&repo=anyproxy&type=fork&count=true" frameborder="0" scrolling="0" width="100px" height="20px"></iframe>
-            </div>
-        </div>
-
-        <div class="feature">
-            <div class="featureContent">
-                <div class="item">
-                    <span class="iconWrapper">
-                        <i class="iconfont">&#xe602;</i>
-                    </span>
-                    <h4>Based on Node.js</h4>
-                    <h5>It&#x27;s all javascript and easy to learn.</h5>
-                </div>
-                <div class="item">
-                    <span class="iconWrapper">
-                        <i class="iconfont">&#xe601;</i>
-                    </span>
-                    <h4>HTTPS supported</h4>
-                    <h5>help to decrypted HTTPS data<a href="https://github.com/alibaba/anyproxy/wiki/HTTPS%E7%9B%B8%E5%85%B3%E6%95%99%E7%A8%8B" target="_blank"><br>How to config&nbsp;&gt;&gt;</a></h5>
-                </div>
-                <div class="item">
-                    <span class="iconWrapper">
-                        <i class="iconfont bigger">&#xe600;</i>
-                    </span>
-                    <h4>Web UI</h4>
-                    <h5>Web based interface to view requests</h5>
-                </div>
-                <div class="item">
-                    <span class="iconWrapper">
-                        <i class="iconfont">&#xe604;</i>
-                    </span>
-                    <h4>Customed Rule File</h4>
-                    <h5>Make your own debugging tool by writing rule files</h5>
-                </div>
-                <div style="clear:both"></div>
-            </div>
-        </div>
-
-        <div class="quickstart listSection">
-            <div class="quickstartContent listContent">
-                <h4 class="subtitle" id="install">Installation</h4>
-                <ul>
-                    <li>install <a href="http://nodejs.org/" target="_blank">Node.js</a> &gt;= v0.12</li>
-                    <li><code class="simpleBash">npm install -g anyproxy</code>, may require<code class="simpleBash">sudo</code></li>
-                    <li><a href="https://github.com/alibaba/anyproxy#quick-start" target="_blank">More&gt;&gt;</a></li>
-                </ul>
-                <h4 class="subtitle" id="quickstart">Quick Start</h4>
-                <ul>
-                    <li>run&nbsp;&nbsp;<code class="simpleBash">anyproxy</code></li>
-                    <li>set proxy to 127.0.0.1:8001 on your browser or device</li>
-                    <li>view web interface at http://127.0.0.1:8002</li>
-                    <li><a href="https://github.com/alibaba/anyproxy#quick-start" target="_blank">More Usage&nbsp;&gt;&gt;</a></li>
-                </ul>
-                <a href="https://github.com/alibaba/anyproxy#step-4---launch-web-interface" target="_blank"><img class="screenshot" src="http://gtms01.alicdn.com/tps/i1/TB1IdgqGXXXXXa9apXXLExM2pXX-854-480.gif" width="350"/></a>
-            </div>
-        </div>
-
-        <div class="sample">
-
-            <div class="sampleContent">
-                <h4 class="subtitle" id="sample ">Sample of Rule Files</h4>
-
-                <div class="item">
-                    <h5 class="itemTitle">Append &quot;hello world&quot; on HTML response</h5>
-                    <pre>
-<code class="javascript">
-//append "hello world" to all web pages
-//file : rule_replace_response_data.js
-//run  : anyproxy --rule rule_replace_response_data.js
-module.exports = {
-    replaceServerResDataAsync: function(req,res,serverRes,cb){
-
-        if(/html/i.test(res.headers['content-type'])){
-            var newDataStr = serverRes.toString();
-            newDataStr += "hello world!";
-            cb(newDataStr);
-        }
-    }
-};
-</code>
-                    </pre>
-                    <span class="figure">
-                        <img src="https://t.alipayobjects.com/images/rmsweb/T1LcphXf0eXXXXXXXX.png" width="350"/>
-                    </span>
-                    <hr />
-                </div>              
-                <div class="item">
-                    <h5 class="itemTitle">remove if-modified-since from http request header</h5>
-                    <pre>
-<code class="javascript">
-//remove cache related header
-//file : rule_remove_cache_header.js
-//run  : anyproxy --rule rule_remove_cache_header.js
-module.exports = {
-    replaceRequestOption : function(req,option){
-        var newOption = option;
-        delete newOption.headers['if-modified-since'];
-
-        return newOption;
-    }
-};
-</code>
-                    </pre>
-                    <span class="figure">
-                        <img src="https://t.alipayobjects.com/images/rmsweb/T1ecFhXjxcXXXXXXXX.png" width="350"/>
-                    </span>
-                    <hr />
-                </div>
-
-                <div class="item">
-                    <h5 class="itemTitle">assign a specified ip address for some requests</h5>
-                    <pre>
-<code class="javascript">
-//assign a specific IP adress for some request
-//file : rule_reverse_proxy.js
-//run  : anyproxy --rule anyproxy --rule rule_reverse_proxy.js
-module.exports = {
-    replaceRequestOption : function(req,option){
-        var newOption = option;
-        if(newOption.headers.host == "www.taobao.com"){
-            newOption.hostname = "192.168.1.3";
-            newOption.port     = "80";
-        }
-
-        return newOption;
-    }
-};
-</code>
-                    </pre>
-                    <span class="figure">
-                        <img src="https://t.alipayobjects.com/images/rmsweb/T1hsxhXeddXXXXXXXX.png" width="350"/>
-                    </span>
-                    <hr />
-                </div>
-
-                <div class="item">
-                    <h5 class="itemTitle">replace all image response by local one</h5>
-                    <pre>
-<code class="javascript">
-//replace all the images with local one
-//file : rule_use_local_data.js
-//run  : anyproxy --rule anyproxy --rule rule_use_local_data.js
-var fs  = require("fs"),
-    img = fs.readFileSync("sample.jpg");
-
-module.exports = {
-    shouldUseLocalResponse : function(req,reqBody){
-        if(/\.(png|gif|jpg|jpeg)$/.test(req.url)){
-            req.replaceLocalFile = true;
-            return true;
-        }else{
-            return false;
-        }
-    },
-
-    dealLocalResponse : function(req,reqBody,callback){
-        if(req.replaceLocalFile){
-            callback(200, {"content-type":"image/png"},img );
-        }
-    }
-};
-</code>
-                    </pre>
-                    <span class="figure">
-                        <img src="https://t.alipayobjects.com/images/rmsweb/T1Zr4hXeXhXXXXXXXX.png" width="350"/>
-                    </span>
-                </div>
-
-                <div class="readmoreBtn">
-                    <a href="https://github.com/alibaba/anyproxy/wiki/What-is-rule-file-and-how-to-write-one" target="_blank">&gt;&gt;&nbsp;Ref : Guide of Rule file</a>
-                </div>
-
-            </div>
-        </div>
-
-        <div class="readMore listSection">
-            <div class="listContent">
-                <h4 class="subtitle" id="otherfeature">Other Features</h4>
-                <ul>
-                    <li>Map file to local , filter your logs</li>
-                    <li><a href="https://github.com/alibaba/anyproxy#throttling">Simulate a low-speed network</a> , help to test the performance of your app on poor network</li>
-                    <li><a href="https://github.com/alibaba/anyproxy#work-as-a-module-for-nodejs" target="_blank">Using AnyProxy as an npm module</a> , to deploy your own debugging tools</li>
-                </ul>
-            </div>
-        </div>
-
-        <div class="learnMore listSection">
-            <div class="btnWrapper">
-                <h4 class="subtitle white" id="readmore">Read More</h4>
-                <a class="actionBtn actionBtnWhite" href="https://github.com/alibaba/anyproxy" target="_blank">https://github.com/alibaba/anyproxy</a>
-            </div>
-        </div>
-
-        <div class="footer"></div>
-
+  <article class="markdown-body">
+    <div class="toc-container" id="j_toc">
+      <div class="toc-content"><ul class="nav nav-list">
+    <li class="sidebar-header-1"><a href="#anyproxy">AnyProxy</a></li>
+    <li class="sidebar-header-2"><a href="#quick-start">Quick start</a></li>
+    <li class="sidebar-header-3"><a href="#install">install</a></li>
+    <li class="sidebar-header-3"><a href="#launch">launch</a></li>
+    <li class="sidebar-header-3"><a href="#other-commands">other commands</a></li>
+    <li class="sidebar-header-2"><a href="#proxy-https-request">Proxy https request</a></li>
+    <li class="sidebar-header-2"><a href="#use-rule-module">Use rule module</a></li>
+    <li class="sidebar-header-3"><a href="#sample">sample</a></li>
+    <li class="sidebar-header-3"><a href="#the-entire-process">the entire process</a></li>
+    <li class="sidebar-header-3"><a href="#how-to-load-rule-module">how to load rule module</a></li>
+    <li class="sidebar-header-2"><a href="#rule-module-interface">Rule module interface</a></li>
+    <li class="sidebar-header-3"><a href="#summary">summary</a></li>
+    <li class="sidebar-header-4"><a href="#summary-1">summary</a></li>
+    <li class="sidebar-header-3"><a href="#beforesendrequest">beforeSendRequest</a></li>
+    <li class="sidebar-header-4"><a href="#beforesendrequest(requestdetail)">beforeSendRequest(requestDetail)</a></li>
+    <li class="sidebar-header-3"><a href="#beforesendresponse">beforeSendResponse</a></li>
+    <li class="sidebar-header-4"><a href="#beforesendresponse(requestdetail,-responsedetail)">beforeSendResponse(requestDetail, responseDetail)</a></li>
+    <li class="sidebar-header-3"><a href="#beforedealhttpsrequest">beforeDealHttpsRequest</a></li>
+    <li class="sidebar-header-4"><a href="#beforedealhttpsrequest(requestdetail)">beforeDealHttpsRequest(requestDetail)</a></li>
+    <li class="sidebar-header-3"><a href="#onerror">onError</a></li>
+    <li class="sidebar-header-4"><a href="#onerror(requestdetail,-error)">onError(requestDetail, error)</a></li>
+    <li class="sidebar-header-3"><a href="#onconnecterror">onConnectError</a></li>
+    <li class="sidebar-header-4"><a href="#onconnecterror(requestdetail,-error)">onConnectError(requestDetail, error)</a></li>
+    <li class="sidebar-header-3"><a href="#faq">FAQ</a></li>
+    <li class="sidebar-header-2"><a href="#rule-samples">Rule Samples</a></li>
+    <li class="sidebar-header-3"><a href="#use-local-response">use local response</a></li>
+    <li class="sidebar-header-3"><a href="#modify-request-header">modify request header</a></li>
+    <li class="sidebar-header-3"><a href="#modify-request-body">modify request body</a></li>
+    <li class="sidebar-header-3"><a href="#modify-the-request-target">modify the request target</a></li>
+    <li class="sidebar-header-3"><a href="#modify-request-protocol">modify request protocol</a></li>
+    <li class="sidebar-header-3"><a href="#modify-response-status-code">modify response status code</a></li>
+    <li class="sidebar-header-3"><a href="#modify-the-response-header">modify the response header</a></li>
+    <li class="sidebar-header-3"><a href="#modify-response-data-and-delay">modify response data and delay</a></li>
+    <li class="sidebar-header-2"><a href="#use-anyproxy-as-an-npm-module">Use AnyProxy as an npm module</a></li>
+    <li class="sidebar-header-2"><a href="#about-anyproxy">About AnyProxy</a></li>
+    <li class="sidebar-header-2"><a href="#appendix">Appendix</a></li>
+    <li class="sidebar-header-3"><a href="#config-root-ca-in-osx">Config root CA in OSX</a></li>
+    <li class="sidebar-header-3"><a href="#trust-root-ca-in-windows">trust root CA in windows</a></li>
+    <li class="sidebar-header-3"><a href="#config-osx-system-proxy">config OSX system proxy</a></li>
+    <li class="sidebar-header-3"><a href="#config-http-proxy-server">config http proxy server</a></li>
+    <li class="sidebar-header-3"><a href="#trust-root-ca-in-ios">trust root CA in iOS</a></li>
+    <li class="sidebar-header-3"><a href="#trust-root-ca-in-ios-&gt;&#x3D;-10.3">trust root CA in iOS &gt;&#x3D; 10.3</a></li>
+    <li class="sidebar-header-3"><a href="#config-ios/android-proxy-server">config iOS/Android proxy server</a></li>
+</ul>
+      </div>
     </div>
+    <div class="main-content"><h1 id="anyproxy"><a class="header-link" href="#anyproxy"></a>AnyProxy</h1>
+<p>AnyProxy is a fully configurable http/https proxy in NodeJS. Version 4.0 is in beta now.</p>
+<p>Ref: <a href="./cn.html">Chinese Doc 中文文档</a></p>
+<p>Github: </p>
+<ul class="list">
+<li><a href="https://github.com/alibaba/anyproxy/tree/4.x">https://github.com/alibaba/anyproxy/tree/4.x</a></li>
+</ul>
+<p>Features:</p>
+<ul class="list">
+<li>Offer you the ablity to handle http traffic by invoking a js module</li>
+<li>Intercept https</li>
+<li>GUI webinterface</li>
+</ul>
+<p>Change Logs since 3.x:</p>
+<ul class="list">
+<li>Support Promise and Generator in rule module</li>
+<li>Simplified interface in rule module</li>
+<li>A newly designed web interface</li>
+</ul>
+<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/SqVntpzmscXPbSzfcGcr.png" width="500" /></p>
+<h2 id="quick-start"><a class="header-link" href="#quick-start"></a>Quick start</h2>
+<h3 id="install"><a class="header-link" href="#install"></a>install</h3>
+<pre class="hljs"><code>npm install -g anyproxy@beta <span class="hljs-comment"># 4.x is in beta now</span></code></pre><h3 id="launch"><a class="header-link" href="#launch"></a>launch</h3>
+<ul class="list">
+<li>start AnyProxy in command line, with default port 8001</li>
+</ul>
+<pre class="hljs"><code>anyproxy</code></pre><ul class="list">
+<li>now you can use http proxy server by 127.0.0.1:8001</li>
+<li>visit <a href="http://127.0.0.1:8002">http://127.0.0.1:8002</a> to see the http requests</li>
+</ul>
+<h3 id="other-commands"><a class="header-link" href="#other-commands"></a>other commands</h3>
+<ul class="list">
+<li>specify the port of http proxy</li>
+</ul>
+<pre class="hljs"><code>anyproxy --port 1080</code></pre><h2 id="proxy-https-request"><a class="header-link" href="#proxy-https-request"></a>Proxy https request</h2>
+<ul class="list">
+<li>AnyProxy does NOT intercept https requests by default. To view decrypted info, you have to config the CA certificate.</li>
+</ul>
+<blockquote>
+<p>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.</p>
+</blockquote>
+<ul class="list">
+<li>generate certifycates and intercept</li>
+</ul>
+<pre class="hljs"><code>anyproxy-ca <span class="hljs-comment">#generate root CA. manually trust it after that.</span>
+anyproxy --intercept <span class="hljs-comment">#launch anyproxy and intercept all https traffic</span></code></pre><ul class="list">
+<li><a href="#osx系统信任ca证书">Appendix:how to trust CA</a></li>
+</ul>
+<h2 id="use-rule-module"><a class="header-link" href="#use-rule-module"></a>Use rule module</h2>
+<p>AnyProxy provides the ability to load your own rules written in javascript. With rule module, you could customize the logic to handle requests.</p>
+<blockquote>
+<p>Make sure your rule file is got from a trusted source. Otherwise, you may face some unknown security risk.</p>
+</blockquote>
+<p>Rule module could do the following stuff:</p>
+<ul class="list">
+<li>intercept and modify the request which is being sent<ul class="list">
+<li>editable fields include request header, body, target address</li>
+</ul>
+</li>
+<li>intercept and modify the response from server<ul class="list">
+<li>editable fields include response status code, header, body</li>
+</ul>
+</li>
+<li>intercept https requests, modify request and response</li>
+</ul>
+<h3 id="sample"><a class="header-link" href="#sample"></a>sample</h3>
+<ul class="list">
+<li><p>Target</p>
+<ul class="list">
+<li>write a rule module to append some text to the response of GET <a href="http://httpbin.org/user-agent">http://httpbin.org/user-agent</a>, and delay the response for 5 seconds</li>
+</ul>
+</li>
+<li><p>Step 1,Write the rule file, save as sample.js</p>
+<pre class="hljs"><code><span class="hljs-comment">// file: sample.js</span>
+<span class="hljs-built_in">module</span>.exports = {
+  <span class="hljs-attr">summary</span>: <span class="hljs-string">'a rule to modify response'</span>,
+  *beforeSendResponse(requestDetail, responseDetail) {
+    <span class="hljs-keyword">if</span> (requestDetail.url === <span class="hljs-string">'http://httpbin.org/user-agent'</span>) {
+      <span class="hljs-keyword">const</span> newResponse = responseDetail.response;
+      newResponse.body += <span class="hljs-string">'-- AnyProxy Hacked! --'</span>;
+      <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =&gt;</span> {
+        setTimeout(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> { <span class="hljs-comment">// delay</span>
+          resolve({ <span class="hljs-attr">response</span>: newResponse });
+        }, <span class="hljs-number">5000</span>);
+      });
+    }
+  },
+};</code></pre></li>
+<li><p>Step 2, start AnyProxy and load the rule file</p>
+<ul class="list">
+<li>run <code>anyproxy --rule sample.js</code></li>
+</ul>
+</li>
+<li><p>Step 3, test</p>
+<ul class="list">
+<li><p>use curl </p>
+<pre class="hljs"><code>curl http://httpbin.org/user-agent --proxy http://127.0.0.1:8001</code></pre></li>
+<li><p>use browser. Point the http proxy of browser to 127.0.0.1:8001, then visit <a href="http://httpbin.org/user-agent">http://httpbin.org/user-agent</a> </p>
+</li>
+<li><p>the expected response from proxy is </p>
+</li>
+</ul>
+<pre class="hljs"><code>{
+  <span class="hljs-string">"user-agent"</span>: <span class="hljs-string">"curl/7.43.0"</span>
+}
+- AnyProxy Hacked!</code></pre></li>
+<li><p>Step 4, view the request log</p>
+<ul class="list">
+<li>visit <a href="http://127.0.0.1:8002">http://127.0.0.1:8002</a>, the request just sent should be listed here</li>
+</ul>
+</li>
+</ul>
+<h3 id="the-entire-process"><a class="header-link" href="#the-entire-process"></a>the entire process</h3>
+<ul class="list">
+<li>The flow chart is as follows</li>
+</ul>
+<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/TWyNuSJtEZBdrdcOMRjE.png" width="550" /></p>
+<ul class="list">
+<li><p>When got an http request, the entire process of proxy server is</p>
+<ul class="list">
+<li>AnyProxy collects all the quest info, include method, header, body</li>
+<li>AnyProxy calls <code>beforeSendRequest</code> of the rule module. Rule module deal the request, return new request param or response content</li>
+<li>If <code>beforeSendRequest</code> returns the response content, AnyProxy will send the response to client without sending to target server. The process ends here.</li>
+<li>Send request to target server, collect response</li>
+<li>Call <code>beforeSendResponse</code> of the rule module. Rule module deal the response data</li>
+<li>Send response to client</li>
+</ul>
+</li>
+<li><p>When AnyProxy get https request, it could replace the certificate and decrypt the request data</p>
+<ul class="list">
+<li>AnyProxy calls <code>beforeDealHttpsRequest</code> of the rule module</li>
+<li>If the function returns <code>true</code>, AnyProxy will do the man-in-the-middle attack to it. Otherwise, the request will not be dealed.</li>
+</ul>
+</li>
+</ul>
+<h3 id="how-to-load-rule-module"><a class="header-link" href="#how-to-load-rule-module"></a>how to load rule module</h3>
+<ul class="list">
+<li><p>use local file</p>
+<pre class="hljs"><code>anyproxy --rule ./rule.js</code></pre></li>
+<li><p>use an online rule file</p>
+<pre class="hljs"><code>anyproxy --rule https://sample.com/rule.js</code></pre></li>
+<li><p>use an npm module</p>
+<ul class="list">
+<li>AnyProxy uses <code>require()</code> to load rule module. You could either load a local npm module or a global-installed one.</li>
+</ul>
+<pre class="hljs"><code>anyproxy --rule ./myRulePkg/ <span class="hljs-comment">#local module</span>
+npm i -g myRulePkg &amp;&amp; anyproxy --rule myRulePkg <span class="hljs-comment">#global-installed module</span></code></pre></li>
+</ul>
+<h2 id="rule-module-interface"><a class="header-link" href="#rule-module-interface"></a>Rule module interface</h2>
+<p>A typical rule module is as follows. All the functions are optional, just write the part you are interested in.</p>
+<pre class="hljs"><code><span class="hljs-built_in">module</span>.exports = {
+  <span class="hljs-comment">// introduction</span>
+  summary: <span class="hljs-string">'my customized rule for AnyProxy'</span>, 
+  <span class="hljs-comment">// intercept before send request to server</span>
+  *beforeSendRequest(requestDetail) { <span class="hljs-comment">/* ... */</span> }, 
+  <span class="hljs-comment">// deal response before send to client </span>
+  *beforeSendResponse(requestDetail, responseDetail) { <span class="hljs-comment">/* ... */</span> }, 
+  <span class="hljs-comment">// if deal https request</span>
+  *beforeDealHttpsRequest(requestDetail) { <span class="hljs-comment">/* ... */</span> }, 
+  <span class="hljs-comment">// error happened when dealing requests</span>
+  *onError(requestDetail, error) { <span class="hljs-comment">/* ... */</span> }, 
+  <span class="hljs-comment">// error happened when connect to https server</span>
+  *onConnectError(requestDetail, error) { <span class="hljs-comment">/* ... */</span> } 
+};</code></pre><blockquote>
+<p>All functions in your rule file, except summary, are all driven by <a href="https://www.npmjs.com/package/co">co</a> . They should be yieldable, i.e. return a promise or be a generator function.</p>
+</blockquote>
+<h3 id="summary"><a class="header-link" href="#summary"></a>summary</h3>
+<h4 id="summary-1"><a class="header-link" href="#summary-1"></a>summary</h4>
+<ul class="list">
+<li>Introduction of this rule file. AnyProxy will read this field and give some tip to user.</li>
+</ul>
+<h3 id="beforesendrequest"><a class="header-link" href="#beforesendrequest"></a>beforeSendRequest</h3>
+<h4 id="beforesendrequest(requestdetail)"><a class="header-link" href="#beforesendrequest(requestdetail)"></a>beforeSendRequest(requestDetail)</h4>
+<ul class="list">
+<li>Before sending request to server, AnyProxy will call <code>beforeSendRequest</code> with param <code>requestDetail</code></li>
+<li><code>requestDetail</code> <ul class="list">
+<li><code>protocol</code> {string} the protocol to use, http or https</li>
+<li><code>requestOptions</code> {object} the options of the request-to-go, a param of require(&#39;http&#39;).request . ref: <a href="https://nodejs.org/api/http.html#http_http_request_options_callback">https://nodejs.org/api/http.html#http_http_request_options_callback</a></li>
+<li><code>requestData</code> {object} request body</li>
+<li><code>url</code> {string} request url</li>
+<li><code>_req</code> {object} the native node.js request object</li>
+</ul>
+</li>
+<li><p>e.g. When requesting  <em>anyproxy.io</em>, <code>requestDetail</code> is something like the following</p>
+<pre class="hljs"><code>{
+  <span class="hljs-attr">protocol</span>: <span class="hljs-string">'http'</span>,
+  <span class="hljs-attr">url</span>: <span class="hljs-string">'http://anyproxy.io/'</span>,
+  <span class="hljs-attr">requestOptions</span>: {
+    <span class="hljs-attr">hostname</span>: <span class="hljs-string">'anyproxy.io'</span>,
+    <span class="hljs-attr">port</span>: <span class="hljs-number">80</span>,
+    <span class="hljs-attr">path</span>: <span class="hljs-string">'/'</span>,
+    <span class="hljs-attr">method</span>: <span class="hljs-string">'GET'</span>,
+    <span class="hljs-attr">headers</span>: {
+      <span class="hljs-attr">Host</span>: <span class="hljs-string">'anyproxy.io'</span>,
+      <span class="hljs-string">'Proxy-Connection'</span>: <span class="hljs-string">'keep-alive'</span>,
+      <span class="hljs-string">'User-Agent'</span>: <span class="hljs-string">'...'</span>
+    }
+  },
+  <span class="hljs-attr">requestData</span>: <span class="hljs-string">'...'</span>,
+  <span class="hljs-attr">_req</span>: { <span class="hljs-comment">/* ... */</span>}
+}</code></pre></li>
+<li><p>Any of these return values are valid</p>
+<ul class="list">
+<li>do nothing, and return null</li>
+</ul>
+<pre class="hljs"><code><span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;</code></pre><ul class="list">
+<li>modify the request protocol,i.e. force use https</li>
+</ul>
+<pre class="hljs"><code><span class="hljs-keyword">return</span> {
+  <span class="hljs-attr">protocol</span>: <span class="hljs-string">'https'</span>
+};</code></pre><ul class="list">
+<li>modify request param</li>
+</ul>
+<pre class="hljs"><code><span class="hljs-keyword">var</span> newOption = <span class="hljs-built_in">Object</span>.assign({}, requestDetail.requestOptions);
+newOption.path = <span class="hljs-string">'/redirect/to/another/path'</span>;
+<span class="hljs-keyword">return</span> {
+  <span class="hljs-attr">requestOptions</span>: newOption
+};</code></pre><ul class="list">
+<li>modify request body</li>
+</ul>
+<pre class="hljs"><code><span class="hljs-keyword">return</span> {
+  <span class="hljs-attr">requestData</span>: <span class="hljs-string">'my new request data'</span>
+  <span class="hljs-comment">// requestOptions can also be used here</span>
+};</code></pre><ul class="list">
+<li>give response to the client, not sending request any longer. <code>statusCode</code> <code>headers</code>are required is this situation.</li>
+</ul>
+<pre class="hljs"><code><span class="hljs-keyword">return</span> {
+  <span class="hljs-attr">response</span>: {
+    <span class="hljs-attr">statusCode</span>: <span class="hljs-number">200</span>,
+    <span class="hljs-attr">header</span>: { <span class="hljs-string">'content-type'</span>: <span class="hljs-string">'text/html'</span> },
+    <span class="hljs-attr">body</span>: <span class="hljs-string">'this could be a &lt;string&gt; or &lt;buffer&gt;'</span>
+  }
+};</code></pre></li>
+</ul>
+<h3 id="beforesendresponse"><a class="header-link" href="#beforesendresponse"></a>beforeSendResponse</h3>
+<h4 id="beforesendresponse(requestdetail,-responsedetail)"><a class="header-link" href="#beforesendresponse(requestdetail,-responsedetail)"></a>beforeSendResponse(requestDetail, responseDetail)</h4>
+<ul class="list">
+<li>Before sending response to client, AnyProxy will call <code>beforeSendResponse</code> with param <code>requestDetail</code> <code>responseDetail</code></li>
+<li><code>requestDetail</code> is the same param as in <code>beforeSendRequest</code></li>
+<li><code>responseDetail</code> <ul class="list">
+<li><code>response</code> {object} the response from server, includes <code>statusCode</code> <code>header</code> <code>body</code></li>
+<li><code>_res</code> {object} the native node.js response object</li>
+</ul>
+</li>
+<li><p>e.g. When requesting <em>anyproxy.io</em>, <code>responseDetail</code> is something like the following</p>
+<pre class="hljs"><code>{ 
+  <span class="hljs-attr">response</span>: { 
+    <span class="hljs-attr">statusCode</span>: <span class="hljs-number">200</span>,
+    <span class="hljs-attr">header</span>: { 
+      <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'image/gif'</span>,
+      <span class="hljs-attr">Connection</span>: <span class="hljs-string">'close'</span>,
+      <span class="hljs-string">'Cache-Control'</span>: <span class="hljs-string">'...'</span>
+    },
+    <span class="hljs-attr">body</span>: <span class="hljs-string">'...'</span>
+  },
+  <span class="hljs-attr">_res</span>: { <span class="hljs-comment">/* ... */</span> }
+}</code></pre></li>
+<li><p>Any of these return values are valid</p>
+<ul class="list">
+<li>do nothing, and return null</li>
+</ul>
+<pre class="hljs"><code><span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;</code></pre><ul class="list">
+<li>modify the response status code</li>
+</ul>
+<pre class="hljs"><code><span class="hljs-keyword">var</span> newResponse = <span class="hljs-built_in">Object</span>.assign({}, responseDetail.reponse);
+newResponse.statusCode = <span class="hljs-number">404</span>;
+<span class="hljs-keyword">return</span> {
+  <span class="hljs-attr">response</span>: newResponse
+};</code></pre><ul class="list">
+<li>modify the response content</li>
+</ul>
+<pre class="hljs"><code><span class="hljs-keyword">var</span> newResponse = <span class="hljs-built_in">Object</span>.assign({}, responseDetail.reponse);
+newResponse.body += <span class="hljs-string">'--from anyproxy--'</span>;
+<span class="hljs-keyword">return</span> {
+  <span class="hljs-attr">response</span>: newResponse
+};</code></pre></li>
+</ul>
+<h3 id="beforedealhttpsrequest"><a class="header-link" href="#beforedealhttpsrequest"></a>beforeDealHttpsRequest</h3>
+<h4 id="beforedealhttpsrequest(requestdetail)"><a class="header-link" href="#beforedealhttpsrequest(requestdetail)"></a>beforeDealHttpsRequest(requestDetail)</h4>
+<ul class="list">
+<li>When receiving https request, AnyProxy will call <code>beforeDealHttpsRequest</code> with param <code>requestDetail</code></li>
+<li>If configed with <code>forceProxyHttps</code> in launching, AnyProxy will skip calling this method</li>
+<li>Only by returning true, AnyProxy will try to replace the certificate and intercept the https request.</li>
+<li><code>requestDetail</code><ul class="list">
+<li><code>host</code> {string} the target host to request. Due to the request protocol, full url couldn&#39;t be got here</li>
+<li><code>_req</code> {object} the native node.js request object. The <code>_req</code> here refers to the CONNECT request.</li>
+</ul>
+</li>
+<li>return value<ul class="list">
+<li><code>true</code> or <code>false</code>, whether AnyProxy should intercept the https request</li>
+</ul>
+</li>
+</ul>
+<h3 id="onerror"><a class="header-link" href="#onerror"></a>onError</h3>
+<h4 id="onerror(requestdetail,-error)"><a class="header-link" href="#onerror(requestdetail,-error)"></a>onError(requestDetail, error)</h4>
+<ul class="list">
+<li>AnyProxy will call this method when an error happened in request handling.</li>
+<li>Errors usually are issued during requesting, e.g. DNS failure, request timeout</li>
+<li><code>requestDetail</code> is the same one as in <code>beforeSendRequest</code></li>
+<li><p>Any of these return values are valid</p>
+<ul class="list">
+<li>do nothing, and AnyProxy will response a default error page</li>
+</ul>
+<pre class="hljs"><code><span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;</code></pre><ul class="list">
+<li>return a customized error page</li>
+</ul>
+<pre class="hljs"><code><span class="hljs-keyword">return</span> {
+  <span class="hljs-attr">response</span>: {
+    <span class="hljs-attr">statusCode</span>: <span class="hljs-number">200</span>,
+    <span class="hljs-attr">header</span>: { <span class="hljs-string">'content-type'</span>: <span class="hljs-string">'text/html'</span> },
+    <span class="hljs-attr">body</span>: <span class="hljs-string">'this could be a &lt;string&gt; or &lt;buffer&gt;'</span>
+  }
+};</code></pre></li>
+</ul>
+<h3 id="onconnecterror"><a class="header-link" href="#onconnecterror"></a>onConnectError</h3>
+<h4 id="onconnecterror(requestdetail,-error)"><a class="header-link" href="#onconnecterror(requestdetail,-error)"></a>onConnectError(requestDetail, error)</h4>
+<ul class="list">
+<li>AnyProxy will call this method when failed to connect target server in https request</li>
+<li><code>requestDetail</code> is the same one as in <code>beforeDealHttpsRequest</code></li>
+<li>no return value is required </li>
+</ul>
+<h3 id="faq"><a class="header-link" href="#faq"></a>FAQ</h3>
+<ul class="list">
+<li>Q: can not deal https request in rule module.</li>
+<li><p>A: Any of these options could be used to change the way AnyProxy deall https requests </p>
+<ol class="list">
+<li>config <code>--intercept</code> when luanching AnyProxy via cli, or use <code>forceProxyHttps</code> when using as an npm module</li>
+<li>place a <code>beforeDealHttpsRequest</code> function in your rule file and determine which request to intercept by your own.</li>
+</ol>
+</li>
+<li><p>Q: get an error says <em>function is not yieldable</em></p>
+</li>
+<li>A: Rule module is driven by <a href="https://www.npmjs.com/package/co">co</a>. The functions inside should  be yieldable, i.e. return a promise or be a generator function.</li>
+</ul>
+<h2 id="rule-samples"><a class="header-link" href="#rule-samples"></a>Rule Samples</h2>
+<ul class="list">
+<li>here are some samples about frequently used rule file</li>
+<li>try these samples by <code>anyproxy --rule http://....js</code></li>
+<li>how to test with curl:<ul class="list">
+<li>request the server directly <code>curl http://httpbin.org/</code></li>
+<li>request the server via proxy <code>curl http://httpbin.org/ --proxy http://127.0.0.1:8001</code></li>
+</ul>
+</li>
+</ul>
+<h3 id="use-local-response"><a class="header-link" href="#use-local-response"></a>use local response</h3>
+<ul class="list">
+<li>intercept the request towards <a href="http://httpbin.org">http://httpbin.org</a> , return the local-defined response</li>
+</ul>
+<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_use_local_response.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
+  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
+*/</span>
+<span class="hljs-built_in">module</span>.exports = {
+  *beforeSendRequest(requestDetail) {
+    <span class="hljs-keyword">const</span> localResponse = {
+      <span class="hljs-attr">statusCode</span>: <span class="hljs-number">200</span>,
+      <span class="hljs-attr">header</span>: { <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'application/json'</span> },
+      <span class="hljs-attr">body</span>: <span class="hljs-string">'{"hello": "this is local response"}'</span>
+    };
+    <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org'</span>) === <span class="hljs-number">0</span>) {
+      <span class="hljs-keyword">return</span> {
+        <span class="hljs-attr">response</span>: localResponse
+      };
+    }
+  },
+};</code></pre><h3 id="modify-request-header"><a class="header-link" href="#modify-request-header"></a>modify request header</h3>
+<ul class="list">
+<li>modify the user-agent sent to httpbin.org</li>
+</ul>
+<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_request_header.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
+  sample: 
+    modify the user-agent in requests toward httpbin.org
+  test:
+    curl http://httpbin.org/user-agent --proxy http://127.0.0.1:8001
+*/</span>
+<span class="hljs-built_in">module</span>.exports = {
+  *beforeSendRequest(requestDetail) {
+    <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org'</span>) === <span class="hljs-number">0</span>) {
+      <span class="hljs-keyword">const</span> newRequestOptions = requestDetail.requestOptions;
+      newRequestOptions.headers[<span class="hljs-string">'User-Agent'</span>] = <span class="hljs-string">'AnyProxy/0.0.0'</span>;
+      <span class="hljs-keyword">return</span> {
+        <span class="hljs-attr">requestOptions</span>: newRequestOptions
+      };
+    }
+  },
+};</code></pre><h3 id="modify-request-body"><a class="header-link" href="#modify-request-body"></a>modify request body</h3>
+<ul class="list">
+<li>modify the post body of <a href="http://httpbin.org/post">http://httpbin.org/post</a></li>
+</ul>
+<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_request_data.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
+  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" }
+*/</span>
+<span class="hljs-built_in">module</span>.exports = {
+  *beforeSendRequest(requestDetail) {
+    <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org/post'</span>) === <span class="hljs-number">0</span>) {
+      <span class="hljs-keyword">return</span> {
+        <span class="hljs-attr">requestData</span>: <span class="hljs-string">'i-am-anyproxy-modified-post-data'</span>
+      };
+    }
+  },
+};</code></pre><h3 id="modify-the-request-target"><a class="header-link" href="#modify-the-request-target"></a>modify the request target</h3>
+<ul class="list">
+<li>send all the request towards <a href="http://httpbin.org/">http://httpbin.org/</a> to <a href="http://httpbin.org/user-agent">http://httpbin.org/user-agent</a></li>
+</ul>
+<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_request_path.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
+  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" }
+*/</span>
+<span class="hljs-built_in">module</span>.exports = {
+  *beforeSendRequest(requestDetail) {
+    <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org'</span>) === <span class="hljs-number">0</span>) {
+      <span class="hljs-keyword">const</span> newRequestOptions = requestDetail.requestOptions;
+      newRequestOptions.path = <span class="hljs-string">'/user-agent'</span>;
+      newRequestOptions.method = <span class="hljs-string">'GET'</span>;
+      <span class="hljs-keyword">return</span> {
+        <span class="hljs-attr">requestOptions</span>: newRequestOptions
+      };
+    }
+  },
+};</code></pre><h3 id="modify-request-protocol"><a class="header-link" href="#modify-request-protocol"></a>modify request protocol</h3>
+<ul class="list">
+<li>modify the http request towards <a href="http://httpbin.org">http://httpbin.org</a> to https</li>
+</ul>
+<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_request_protocol.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
+  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" }
+*/</span>
+<span class="hljs-built_in">module</span>.exports = {
+  *beforeSendRequest(requestDetail) {
+    <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org'</span>) === <span class="hljs-number">0</span>) {
+      <span class="hljs-keyword">const</span> newOption = requestDetail.requestOptions;
+      newOption.port = <span class="hljs-number">443</span>;
+      <span class="hljs-keyword">return</span> {
+        <span class="hljs-attr">protocol</span>: <span class="hljs-string">'https'</span>,
+        <span class="hljs-attr">requestOptions</span>: newOption
+      };
+    }
+  }
+};</code></pre><h3 id="modify-response-status-code"><a class="header-link" href="#modify-response-status-code"></a>modify response status code</h3>
+<ul class="list">
+<li>modify all status code from <a href="http://httpbin.org">http://httpbin.org</a> to 404</li>
+</ul>
+<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_response_statuscode.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
+  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
+*/</span>
+<span class="hljs-built_in">module</span>.exports = {
+  *beforeSendResponse(requestDetail, responseDetail) {
+    <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org'</span>) === <span class="hljs-number">0</span>) {
+      <span class="hljs-keyword">const</span> newResponse = responseDetail.response;
+      newResponse.statusCode = <span class="hljs-number">404</span>;
+      <span class="hljs-keyword">return</span> {
+        <span class="hljs-attr">response</span>: newResponse
+      };
+    }
+  }
+};</code></pre><h3 id="modify-the-response-header"><a class="header-link" href="#modify-the-response-header"></a>modify the response header</h3>
+<ul class="list">
+<li>add X-Proxy-By:AnyProxy to the response header from <a href="http://httpbin.org/user-agent">http://httpbin.org/user-agent</a></li>
+</ul>
+<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_response_header.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
+  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
+*/</span>
+<span class="hljs-built_in">module</span>.exports = {
+  *beforeSendResponse(requestDetail, responseDetail) {
+    <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org/user-agent'</span>) === <span class="hljs-number">0</span>) {
+      <span class="hljs-keyword">const</span> newResponse = responseDetail.response;
+      newResponse.header[<span class="hljs-string">'X-Proxy-By'</span>] = <span class="hljs-string">'AnyProxy'</span>;
+      <span class="hljs-keyword">return</span> {
+        <span class="hljs-attr">response</span>: newResponse
+      };
+    }
+  }
+};</code></pre><h3 id="modify-response-data-and-delay"><a class="header-link" href="#modify-response-data-and-delay"></a>modify response data and delay</h3>
+<ul class="list">
+<li>append some info to the response of <a href="http://httpbin.org/user-agent">http://httpbin.org/user-agent</a>, then delay the response for 5 seconds.</li>
+</ul>
+<pre class="hljs"><code>anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_response_data.js</code></pre><pre class="hljs"><code><span class="hljs-comment">/* 
+  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! --
+*/</span>
 
-    <link rel="stylesheet" type="text/css" href="/dest/github.css" />
-    <script src="/dest/lib.js"></script>
-    <script type="text/javascript">
-        Zepto(document).ready(function() {
-            Zepto('.sample code').each(function(i, block) {
-                hljs.highlightBlock(block);
-            });
+<span class="hljs-built_in">module</span>.exports = {
+  *beforeSendResponse(requestDetail, responseDetail) {
+    <span class="hljs-keyword">if</span> (requestDetail.url === <span class="hljs-string">'http://httpbin.org/user-agent'</span>) {
+      <span class="hljs-keyword">const</span> newResponse = responseDetail.response;
+      newResponse.body += <span class="hljs-string">'-- AnyProxy Hacked! --'</span>;
+      <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =&gt;</span> {
+        setTimeout(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> { <span class="hljs-comment">// delay the response for 5s</span>
+          resolve({ <span class="hljs-attr">response</span>: newResponse });
+        }, <span class="hljs-number">5000</span>);
+      });
+    }
+  },
+};</code></pre><h2 id="use-anyproxy-as-an-npm-module"><a class="header-link" href="#use-anyproxy-as-an-npm-module"></a>Use AnyProxy as an npm module</h2>
+<p>AnyProxy can be used as an npm module</p>
+<blockquote>
+<p>To enable https feature, please guide users to use <code>anyproxy-ca</code> in cli. Or use methods under <code>AnyProxy.utils.certMgr</code> to generate certificates.</p>
+</blockquote>
+<ul class="list">
+<li>install</li>
+</ul>
+<pre class="hljs"><code>npm i anyproxy@beta --save <span class="hljs-comment"># 4.0 is in beta now</span></code></pre><ul class="list">
+<li>sample</li>
+</ul>
+<pre class="hljs"><code><span class="hljs-keyword">const</span> AnyProxy = <span class="hljs-built_in">require</span>(<span class="hljs-string">'anyproxy'</span>);
+<span class="hljs-keyword">const</span> options = {
+  <span class="hljs-attr">port</span>: <span class="hljs-number">8001</span>,
+  <span class="hljs-attr">rule</span>: <span class="hljs-built_in">require</span>(<span class="hljs-string">'myRuleModule'</span>),
+  <span class="hljs-attr">webInterface</span>: {
+    <span class="hljs-attr">enable</span>: <span class="hljs-literal">true</span>,
+    <span class="hljs-attr">webPort</span>: <span class="hljs-number">8002</span>,
+    <span class="hljs-attr">wsPort</span>: <span class="hljs-number">8003</span>,
+  },
+  <span class="hljs-attr">throttle</span>: <span class="hljs-number">10000</span>,
+  <span class="hljs-attr">forceProxyHttps</span>: <span class="hljs-literal">false</span>,
+  <span class="hljs-attr">silent</span>: <span class="hljs-literal">false</span>
+};
+<span class="hljs-keyword">const</span> proxyServer = <span class="hljs-keyword">new</span> AnyProxy.ProxyServer(options);
+
+proxyServer.on(<span class="hljs-string">'ready'</span>, () =&gt; { <span class="hljs-comment">/* */</span> });
+proxyServer.on(<span class="hljs-string">'error'</span>, (e) =&gt; { <span class="hljs-comment">/* */</span> });
+proxyServer.start();
+
+<span class="hljs-comment">//when finished</span>
+proxyServer.close();</code></pre><ul class="list">
+<li><p>Class: AnyProxy.proxyServer</p>
+<ul class="list">
+<li><p>create a proxy server</p>
+<pre class="hljs"><code><span class="hljs-keyword">const</span> proxy = <span class="hljs-keyword">new</span> AnyProxy.proxyServer(options)</code></pre></li>
+<li><p><code>options</code></p>
+<ul class="list">
+<li><code>port</code> {number} required, port number of proxy server</li>
+<li><code>rule</code> {object} your rule module</li>
+<li><code>throttle</code> {number} throttle in kb/s, unlimited for default</li>
+<li><code>forceProxyHttps</code> {boolean} in force intercept all https request, false for default</li>
+<li><code>silent</code> {boolean} if keep silent in console, false for default<code>false</code></li>
+<li><code>dangerouslyIgnoreUnauthorized</code> {boolean} if ignore certificate error in request, false for default</li>
+<li><code>webInterface</code> {object} config for web interface<ul class="list">
+<li><code>enable</code> {boolean} if enable web interface, false for default</li>
+<li><code>webPort</code> {number} port number for web interface</li>
+</ul>
+</li>
+</ul>
+</li>
+<li><p>Event: <code>ready</code></p>
+<ul class="list">
+<li>emit when proxy server is ready</li>
+<li>sample</li>
+</ul>
+<pre class="hljs"><code>proxy.on(<span class="hljs-string">'ready'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{ })</code></pre></li>
+<li><p>Event: <code>error</code></p>
+<ul class="list">
+<li>emit when error happened inside proxy server</li>
+<li>sample</li>
+</ul>
+<pre class="hljs"><code>proxy.on(<span class="hljs-string">'error'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{ })</code></pre></li>
+<li><p>Method: <code>start</code></p>
+<ul class="list">
+<li>start proxy server</li>
+<li>sample</li>
+</ul>
+<pre class="hljs"><code>proxy.start();</code></pre></li>
+<li><p>Method: <code>close</code></p>
+<ul class="list">
+<li>close proxy server</li>
+<li>sample</li>
+</ul>
+<pre class="hljs"><code>proxy.close();</code></pre></li>
+</ul>
+</li>
+<li><p>AnyProxy.utils.systemProxyMgr</p>
+<ul class="list">
+<li>manage the system proxy config. sudo password may be required</li>
+<li>sample</li>
+</ul>
+<pre class="hljs"><code><span class="hljs-comment">// set 127.0.0.1:8001 as system http server</span>
+AnyProxy.utils.systemProxyMgr.enableGlobalProxy(<span class="hljs-string">'127.0.0.1'</span>, <span class="hljs-string">'8001'</span>);    
+
+<span class="hljs-comment">// disable global proxy server</span>
+AnyProxy.utils.systemProxyMgr.disableGlobalProxy();</code></pre></li>
+<li><p>AnyProxy.utils.certMgr</p>
+<ul class="list">
+<li>Manage certificates of AnyProxy</li>
+<li><code>AnyProxy.utils.certMgr.ifRootCAFileExists()</code><ul class="list">
+<li>detect if AnyProx rootCA exists</li>
+</ul>
+</li>
+<li><code>AnyProxy.utils.certMgr.generateRootCA(callback)</code><ul class="list">
+<li>generate a rootCA</li>
+</ul>
+</li>
+<li>Sample</li>
+</ul>
+<pre class="hljs"><code>  <span class="hljs-keyword">const</span> AnyProxy = <span class="hljs-built_in">require</span>(<span class="hljs-string">'AnyProxy'</span>);
+  <span class="hljs-keyword">const</span> exec = <span class="hljs-built_in">require</span>(<span class="hljs-string">'child_process'</span>).exec;
+
+  <span class="hljs-keyword">if</span> (!AnyProxy.utils.certMgr.ifRootCAFileExists()) {
+    AnyProxy.utils.certMgr.generateRootCA(<span class="hljs-function">(<span class="hljs-params">error, keyPath</span>) =&gt;</span> {
+      <span class="hljs-comment">// let users to trust this CA before using proxy</span>
+      <span class="hljs-keyword">if</span> (!error) {
+        <span class="hljs-keyword">const</span> certDir = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>).dirname(keyPath);
+        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'The cert is generated at'</span>, certDir);
+        <span class="hljs-keyword">const</span> isWin = <span class="hljs-regexp">/^win/</span>.test(process.platform);
+        <span class="hljs-keyword">if</span> (isWin) {
+          exec(<span class="hljs-string">'start .'</span>, { <span class="hljs-attr">cwd</span>: certDir });
+        } <span class="hljs-keyword">else</span> {
+          exec(<span class="hljs-string">'open .'</span>, { <span class="hljs-attr">cwd</span>: certDir });
+        }
+      } <span class="hljs-keyword">else</span> {
+        <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'error when generating rootCA'</span>, error);
+      }
+    });
+  }</code></pre></li>
+</ul>
+<h2 id="about-anyproxy"><a class="header-link" href="#about-anyproxy"></a>About AnyProxy</h2>
+<ul class="list">
+<li>Change Log: <a href="https://github.com/alibaba/anyproxy/blob/master/CHANGELOG">https://github.com/alibaba/anyproxy/blob/master/CHANGELOG</a></li>
+<li>Github:<a href="https://github.com/alibaba/anyproxy">https://github.com/alibaba/anyproxy</a></li>
+<li>issue:<a href="https://github.com/alibaba/anyproxy/issues">https://github.com/alibaba/anyproxy/issues</a></li>
+</ul>
+<h2 id="appendix"><a class="header-link" href="#appendix"></a>Appendix</h2>
+<h3 id="config-root-ca-in-osx"><a class="header-link" href="#config-root-ca-in-osx"></a>Config root CA in OSX</h3>
+<ul class="list">
+<li>this kind of errors is usually caused by untrusted root CA</li>
+</ul>
+<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/CBkLGYgvoHAYwNVAYkpk.png" width="450" /></p>
+<blockquote>
+<p>Warning: please keep your root CA safe since it may influence your system security.</p>
+</blockquote>
+<p>install :</p>
+<ul class="list">
+<li><p>double click <em>rootCA.crt</em></p>
+</li>
+<li><p>add cert into login or system</p>
+</li>
+</ul>
+<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/bCwNUFFpvsmVuljQKrIk.png" width="350" /></p>
+<ul class="list">
+<li>find the newly imported AnyProxy certificates, configured as <strong>Always Trust</strong></li>
+</ul>
+<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/HOmEElNGdoZEWFMLsTNT.png" width="700" /></p>
+<h3 id="trust-root-ca-in-windows"><a class="header-link" href="#trust-root-ca-in-windows"></a>trust root CA in windows</h3>
+<p class="img-container"><img src="https://t.alipayobjects.com/tfscom/T1D3hfXeFtXXXXXXXX.jpg" width="700" /></p>
+<h3 id="config-osx-system-proxy"><a class="header-link" href="#config-osx-system-proxy"></a>config OSX system proxy</h3>
+<ul class="list">
+<li>the config is in wifi - advanced</li>
+</ul>
+<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/vduwhobSTypTfgniBvoa.png" width="500" /></p>
+<h3 id="config-http-proxy-server"><a class="header-link" href="#config-http-proxy-server"></a>config http proxy server</h3>
+<ul class="list">
+<li>take Chrome extent [SwitchyOmega] as an example(<a href="https://chrome.google.com/webstore/detail/padekgcemlokbadohgkifijomclgjgif)为例">https://chrome.google.com/webstore/detail/padekgcemlokbadohgkifijomclgjgif)为例</a></li>
+</ul>
+<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/jIPZrKmqXRaSledQeJUJ.png" width="500" /></p>
+<h3 id="trust-root-ca-in-ios"><a class="header-link" href="#trust-root-ca-in-ios"></a>trust root CA in iOS</h3>
+<ul class="list">
+<li>Click <em>Root CA</em> in web ui, and follow the instruction to install</li>
+</ul>
+<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/BrugmMelGVysLDOIBblj.png" width="260" /></p>
+<h3 id="trust-root-ca-in-ios->=-10.3"><a class="header-link" href="#trust-root-ca-in-ios->=-10.3"></a>trust root CA in iOS &gt;= 10.3</h3>
+<ul class="list">
+<li>Besides installing root CA, you have to &quot;turn on&quot; the certificate for web manually in <em>settings - general - about - Certificate Trust Settings</em>. Otherwire, safari will not trust the root CA generated by AnyProxy.</li>
+</ul>
+<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/hVWkXHrzHmOKOtCKGUWx.png" width="500" /></p>
+<h3 id="config-ios/android-proxy-server"><a class="header-link" href="#config-ios/android-proxy-server"></a>config iOS/Android proxy server</h3>
+<ul class="list">
+<li><p>proxy settings are placed in wifi setting</p>
+</li>
+<li><p>iOS</p>
+</li>
+</ul>
+<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/tLGqIozhffTccUgPakuw.png" width="260" /></p>
+<ul class="list">
+<li>Android</li>
+</ul>
+<p class="img-container"><img src="https://zos.alipayobjects.com/rmsportal/YQtbQYVNuOszZGdAOauU.png" width="260" /></p>
+    </div>
+  </article>
+
+  <script src="//cdn.bootcss.com/zepto/1.2.0/zepto.min.js"></script>
+  <script>
+  window.onload = function(){
+    var itemList = [];
+    var targetMap = {};
+    $("[id]", ".main-content").map(function (index, heading) {
+      targetMap[heading.getAttribute('id')] = heading;
+    });
+
+    $("#j_toc li").map(function (index, item) {
+      if (item.className.indexOf('sidebar-header-2') >= 0 || item.className.indexOf('sidebar-header-3') >= 0) {
+        var targetName = item.firstChild.getAttribute('href').replace('#', '');
+        var targetItem = targetMap[targetName];
+        itemList.push({ target: targetItem, tocItem: item, top: $(targetItem).position().top });
+      }
+    });
+
+    var updateTocActive = function (e) {
+      var windowHeight = window.innerHeight;
+      //find the first item to match
+      var scrollYThres = window.scrollY + 200;
+      var target;
+      if (scrollYThres < 100) {
+        target = itemList[0].tocItem;
+      } else {
+        itemList.forEach(function (item, index) {
+          if (target) return;
+          if (index > 0) {
+            if (item.top >= scrollYThres) {
+              target = itemList[index - 1].tocItem;
+            }
+          }
         });
-    </script>
+      }
+
+      $('.toc-active').removeClass('toc-active');
+      $(target).addClass('toc-active');
+    };
+
+    window.onscroll = updateTocActive;
+    updateTocActive();
+  }
+  </script>
 </body>
+
 </html>
\ No newline at end of file
diff --git a/package.json b/package.json
index 815511a..5c5a6a0 100644
--- a/package.json
+++ b/package.json
@@ -30,7 +30,6 @@
   "scripts": {
     "test": "exit 0"
   },
-  "pre-commit": "test",
   "repository": {
     "type": "git",
     "url": "https://github.com/alibaba/anyproxy.git"
diff --git a/sampleA.png b/sampleA.png
deleted file mode 100644
index 0c4c379..0000000
Binary files a/sampleA.png and /dev/null differ
diff --git a/sampleB.png b/sampleB.png
deleted file mode 100644
index 10e9f67..0000000
Binary files a/sampleB.png and /dev/null differ
diff --git a/sampleC.png b/sampleC.png
deleted file mode 100644
index 160ce0c..0000000
Binary files a/sampleC.png and /dev/null differ
diff --git a/sampleD.png b/sampleD.png
deleted file mode 100644
index aec4470..0000000
Binary files a/sampleD.png and /dev/null differ
diff --git a/src/i18n.json b/src/i18n.json
deleted file mode 100644
index 56da5d3..0000000
--- a/src/i18n.json
+++ /dev/null
@@ -1,71 +0,0 @@
-{
-	"cn":{
-		"language":"cn",
-		"summary":"AnyProxy 4.x版正在Beta中,欢迎试用 Ref:<a href=\"/4.x/\">AnyProxy 4.x 文档</a>",
-		"featureA":"基于Node.js",
-		"featureADesc":"全程JavaScript,学习无压力",
-		"featureB":"支持Https",
-		"featureBDesc":"明文解析Https请求数据",
-		"featureBHowTo":"如何配置",
-		"featureC":"Web界面",
-		"featureCDesc":"多终端共享,可视化观察每个请求",
-		"featureD":"规则逻辑(Rule)",
-		"featureDDesc":"个性化处理规则,定制专属调试工具",
-		"installationTitle":"安装",
-		"installationStepA":"安装",
-		"installationStepB":"可能需要",
-		"quickStartTitle":"使用",
-		"quickStartStepA":"运行",
-		"quickStartStepB":"把浏览器http代理指向 127.0.0.1:8001",
-		"quickStartStepC":"访问界面:http://127.0.0.1:8002",
-		"quickStartMoreUsage":"更多用法",
-		"sampleRuleTitle":"规则文件(rule)样例",
-		"sampleATitle":"在HTML响应末尾加上\"hello world\"",
-		"sampleBTitle":"去除请求头的if-modified-since字段",
-		"sampleCTitle":"为某个请求指定目标IP地址",
-		"sampleDTitle":"把所有图片响应替换成本地图片",
-		"ruleGuideText":"阅读:规则文件(Rule)API",
-		"ruleGuideLink":"https://github.com/alibaba/anyproxy/wiki/%E4%BB%A3%E7%90%86%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%9A%84%E6%96%B0%E8%BD%AE%E5%AD%90%EF%BC%9Aanyproxy#%E5%BC%80%E6%94%BE%E5%BC%8F%E4%BB%A3%E7%90%86%E6%9C%8D%E5%8A%A1%E5%99%A8%E8%AE%BE%E8%AE%A1",
-		"otherFeaturesTitle":"其他特性",
-		"otherFeatureA":"Map Local,Log Filter等常规功能",
-		"otherFeatureB":"低网速网速模拟",
-		"otherFeatureBDesc":",调试应用在2G/3G下的表现",
-		"otherFeatureC":"把AnyProxy作为npm模块",
-		"otherFeatureCDesc":",基于它做二次开发"
-
-	},
-	"en":{
-		"language":"en",
-		"summary":"AnyProxy is a fully configurable http/https proxy in NodeJS, which offers you the ablity to handle http traffic as you wish.",
-		"featureA":"Based on Node.js",
-		"featureADesc":"It's all javascript and easy to learn.",
-		"featureB":"HTTPS supported",
-		"featureBDesc":"help to decrypted HTTPS data",
-		"featureBHowTo":"How to config",
-		"featureC":"Web UI",
-		"featureCDesc":"Web based interface to view requests",
-		"featureD":"Customed Rule File",
-		"featureDDesc":"Make your own debugging tool by writing rule files",
-		"installationTitle":"Installation",
-		"installationStepA":"install",
-		"installationStepB":"may require",
-		"quickStartTitle":"Quick Start",
-		"quickStartStepA":"run",
-		"quickStartStepB":"set proxy to 127.0.0.1:8001 on your browser or device",
-		"quickStartStepC":"view web interface at http://127.0.0.1:8002",
-		"quickStartMoreUsage":"More Usage",
-		"sampleRuleTitle":"Sample of Rule Files",
-		"sampleATitle":"Append \"hello world\" on HTML response",
-		"sampleBTitle":"remove if-modified-since from http request header",
-		"sampleCTitle":"assign a specified ip address for some requests",
-		"sampleDTitle":"replace all image response by local one",
-		"ruleGuideText":"Ref : Guide of Rule file",
-		"ruleGuideLink":"https://github.com/alibaba/anyproxy/wiki/What-is-rule-file-and-how-to-write-one",
-		"otherFeaturesTitle":"Other Features",
-		"otherFeatureA":"Map file to local , filter your logs",
-		"otherFeatureB":"Simulate a low-speed network",
-		"otherFeatureBDesc":" , help to test the performance of your app on poor network",
-		"otherFeatureC":"Using AnyProxy as an npm module",
-		"otherFeatureCDesc":" , to deploy your own debugging tools"
-	}
-}
\ No newline at end of file
diff --git a/src/index.html b/src/index.html
deleted file mode 100644
index 486a07a..0000000
--- a/src/index.html
+++ /dev/null
@@ -1,250 +0,0 @@
-<html>
-<head>
-    <title>AnyProxy</title>
-    <link rel="stylesheet" type="text/css" href="/dest/index.css">
-    <link rel="shortcut icon" type="image/png" href="/favico.png?t=2" />
-    <meta name="description" content="A fully configurable proxy in NodeJS, which can handle HTTPS requests perfectly.">
-    <meta name="description" content="AnyProxy - 开放式的HTTP/HTTPS代理,你可以灵活控制各种网络数据">
-    <meta name="keywords" content="代理服务器 Proxy HTTP HTTPS">
-    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
-    <script> 
-        //redirect to Chinese version if in China
-        if(new Date().getTimezoneOffset() == "-480" && !(/(cn|en)/i.test(location.href))){
-            location.href = "/cn";
-        }else{
-            var _hmt = _hmt || []; (function() {var hm = document.createElement("script"); hm.src = "//hm.baidu.com/hm.js?4e51565b7d471fd6623c163a8fd79e07"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })();
-        }
-    </script>
-
-</head>
-<body>
-
-    <div class="wrapper">
-        <div class="cornerBtnWrapper">
-            <a href="/cn">中文</a>|
-            <a href="/en">English</a>|
-            <a href="https://github.com/alibaba/anyproxy" target="_blank">View on Github</a>
-        </div>
-
-        <div class="brief">
-            <div class="logo">
-                <img src="http://gtms04.alicdn.com/tps/i4/TB1XfxDHpXXXXXpapXX20ySQVXX-512-512.png" width="250" height="250" alt="anyproxy logo" />
-            </div>
-            <h2 class="slogan">$${summary}</h2>
-            <div class="action">
-                <iframe src="https://ghbtns.com/github-btn.html?user=alibaba&repo=anyproxy&type=star&count=true" frameborder="0" scrolling="0" width="100px" height="20px"></iframe>&nbsp;&nbsp;&nbsp;
-                <iframe src="https://ghbtns.com/github-btn.html?user=alibaba&repo=anyproxy&type=fork&count=true" frameborder="0" scrolling="0" width="100px" height="20px"></iframe>
-            </div>
-        </div>
-
-        <div class="feature">
-            <div class="featureContent">
-                <div class="item">
-                    <span class="iconWrapper">
-                        <i class="iconfont">&#xe602;</i>
-                    </span>
-                    <h4>${featureA}</h4>
-                    <h5>${featureADesc}</h5>
-                </div>
-                <div class="item">
-                    <span class="iconWrapper">
-                        <i class="iconfont">&#xe601;</i>
-                    </span>
-                    <h4>${featureB}</h4>
-                    <h5>${featureBDesc}<a href="https://github.com/alibaba/anyproxy/wiki/HTTPS%E7%9B%B8%E5%85%B3%E6%95%99%E7%A8%8B" target="_blank"><br>${featureBHowTo}&nbsp;&gt;&gt;</a></h5>
-                </div>
-                <div class="item">
-                    <span class="iconWrapper">
-                        <i class="iconfont bigger">&#xe600;</i>
-                    </span>
-                    <h4>${featureC}</h4>
-                    <h5>${featureCDesc}</h5>
-                </div>
-                <div class="item">
-                    <span class="iconWrapper">
-                        <i class="iconfont">&#xe604;</i>
-                    </span>
-                    <h4>${featureD}</h4>
-                    <h5>${featureDDesc}</h5>
-                </div>
-                <div style="clear:both"></div>
-            </div>
-        </div>
-
-        <div class="quickstart listSection">
-            <div class="quickstartContent listContent">
-                <h4 class="subtitle" id="install">${installationTitle}</h4>
-                <ul>
-                    <li>${installationStepA} <a href="http://nodejs.org/" target="_blank">Node.js</a> &gt;= v0.12</li>
-                    <li><code class="simpleBash">npm install -g anyproxy</code>, ${installationStepB}<code class="simpleBash">sudo</code></li>
-                    <li><a href="https://github.com/alibaba/anyproxy#quick-start" target="_blank">More&gt;&gt;</a></li>
-                </ul>
-                <h4 class="subtitle" id="quickstart">${quickStartTitle}</h4>
-                <ul>
-                    <li>${quickStartStepA}&nbsp;&nbsp;<code class="simpleBash">anyproxy</code></li>
-                    <li>${quickStartStepB}</li>
-                    <li>${quickStartStepC}</li>
-                    <li><a href="https://github.com/alibaba/anyproxy#quick-start" target="_blank">${quickStartMoreUsage}&nbsp;&gt;&gt;</a></li>
-                </ul>
-                <a href="https://github.com/alibaba/anyproxy#step-4---launch-web-interface" target="_blank"><img class="screenshot" src="http://gtms01.alicdn.com/tps/i1/TB1IdgqGXXXXXa9apXXLExM2pXX-854-480.gif" width="350"/></a>
-            </div>
-        </div>
-
-        <div class="sample">
-
-            <div class="sampleContent">
-                <h4 class="subtitle" id="sample ">${sampleRuleTitle}</h4>
-
-                <div class="item">
-                    <h5 class="itemTitle">${sampleATitle}</h5>
-                    <pre>
-<code class="javascript">
-//append "hello world" to all web pages
-//file : rule_replace_response_data.js
-//run  : anyproxy --rule rule_replace_response_data.js
-module.exports = {
-    replaceServerResDataAsync: function(req,res,serverRes,cb){
-
-        if(/html/i.test(res.headers['content-type'])){
-            var newDataStr = serverRes.toString();
-            newDataStr += "hello world!";
-            cb(newDataStr);
-        }
-    }
-};
-</code>
-                    </pre>
-                    <span class="figure">
-                        <img src="https://t.alipayobjects.com/images/rmsweb/T1LcphXf0eXXXXXXXX.png" width="350"/>
-                    </span>
-                    <hr />
-                </div>              
-                <div class="item">
-                    <h5 class="itemTitle">${sampleBTitle}</h5>
-                    <pre>
-<code class="javascript">
-//remove cache related header
-//file : rule_remove_cache_header.js
-//run  : anyproxy --rule rule_remove_cache_header.js
-module.exports = {
-    replaceRequestOption : function(req,option){
-        var newOption = option;
-        delete newOption.headers['if-modified-since'];
-
-        return newOption;
-    }
-};
-</code>
-                    </pre>
-                    <span class="figure">
-                        <img src="https://t.alipayobjects.com/images/rmsweb/T1ecFhXjxcXXXXXXXX.png" width="350"/>
-                    </span>
-                    <hr />
-                </div>
-
-                <div class="item">
-                    <h5 class="itemTitle">${sampleCTitle}</h5>
-                    <pre>
-<code class="javascript">
-//assign a specific IP adress for some request
-//file : rule_reverse_proxy.js
-//run  : anyproxy --rule anyproxy --rule rule_reverse_proxy.js
-module.exports = {
-    replaceRequestOption : function(req,option){
-        var newOption = option;
-        if(newOption.headers.host == "www.taobao.com"){
-            newOption.hostname = "192.168.1.3";
-            newOption.port     = "80";
-        }
-
-        return newOption;
-    }
-};
-</code>
-                    </pre>
-                    <span class="figure">
-                        <img src="https://t.alipayobjects.com/images/rmsweb/T1hsxhXeddXXXXXXXX.png" width="350"/>
-                    </span>
-                    <hr />
-                </div>
-
-                <div class="item">
-                    <h5 class="itemTitle">${sampleDTitle}</h5>
-                    <pre>
-<code class="javascript">
-//replace all the images with local one
-//file : rule_use_local_data.js
-//run  : anyproxy --rule anyproxy --rule rule_use_local_data.js
-var fs  = require("fs"),
-    img = fs.readFileSync("sample.jpg");
-
-module.exports = {
-    shouldUseLocalResponse : function(req,reqBody){
-        if(/\.(png|gif|jpg|jpeg)$/.test(req.url)){
-            req.replaceLocalFile = true;
-            return true;
-        }else{
-            return false;
-        }
-    },
-
-    dealLocalResponse : function(req,reqBody,callback){
-        if(req.replaceLocalFile){
-            callback(200, {"content-type":"image/png"},img );
-        }
-    }
-};
-</code>
-                    </pre>
-                    <span class="figure">
-                        <img src="https://t.alipayobjects.com/images/rmsweb/T1Zr4hXeXhXXXXXXXX.png" width="350"/>
-                    </span>
-                </div>
-
-                <div class="readmoreBtn">
-                    <a href="${ruleGuideLink}" target="_blank">&gt;&gt;&nbsp;${ruleGuideText}</a>
-                </div>
-
-            </div>
-        </div>
-
-        <div class="readMore listSection">
-            <div class="listContent">
-                <h4 class="subtitle" id="otherfeature">${otherFeaturesTitle}</h4>
-                <ul>
-                    <li>${otherFeatureA}</li>
-                    <li><a href="https://github.com/alibaba/anyproxy#throttling">${otherFeatureB}</a>${otherFeatureBDesc}</li>
-                    <li><a href="https://github.com/alibaba/anyproxy#work-as-a-module-for-nodejs" target="_blank">${otherFeatureC}</a>${otherFeatureCDesc}</li>
-                </ul>
-                {@if language == "cn"}
-                <h4 class="subtitle" id="ref">相关阅读</h4>
-                <ul>
-                    <li><a href="https://github.com/alibaba/anyproxy/wiki/%E4%BB%A3%E7%90%86%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%9A%84%E6%96%B0%E8%BD%AE%E5%AD%90%EF%BC%9Aanyproxy" target="_blank">代理服务器的新轮子</a>,介绍AnyProxy的设计初衷,以及它的开放式设计可以解决什么问题。</li>
-                    <li><a href="http://www.infoq.com/cn/presentations/alipay-hybrid-application-quality-assurance-practice" target="_blank">QCon - 《支付宝hybrid应用质量保证实践》</a>,涉及到AnyProxy在测试工程中的应用(By 陈晔)</li>
-                </ul>
-                {@/if}
-            </div>
-        </div>
-
-        <div class="learnMore listSection">
-            <div class="btnWrapper">
-                <h4 class="subtitle white" id="readmore">Read More</h4>
-                <a class="actionBtn actionBtnWhite" href="https://github.com/alibaba/anyproxy" target="_blank">https://github.com/alibaba/anyproxy</a>
-            </div>
-        </div>
-
-        <div class="footer"></div>
-
-    </div>
-
-    <link rel="stylesheet" type="text/css" href="/dest/github.css" />
-    <script src="/dest/lib.js"></script>
-    <script type="text/javascript">
-        Zepto(document).ready(function() {
-            Zepto('.sample code').each(function(i, block) {
-                hljs.highlightBlock(block);
-            });
-        });
-    </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/src/index.js b/src/index.js
deleted file mode 100644
index e69de29..0000000
diff --git a/src/index.less b/src/index.less
deleted file mode 100644
index ca46ea2..0000000
--- a/src/index.less
+++ /dev/null
@@ -1,407 +0,0 @@
-@main : #00AAEE;
-@dark : #326EEB;
-@gray : #F9F9F9;
-@darkGray : #DEDEDE;
-@textDark : #5A5A5A;
-@textLight: #777;
-
-@wideContent : 1200px;
-@normalContent : 890px;
-
-@wideContentMobile : 100%;
-@normalContentMobile : 100%;
-
-@font-face {
-	font-family: 'iconfont';
-	src: url('//at.alicdn.com/t/font_1440130445_6601267.eot'); /* IE9*/
-	src: url('//at.alicdn.com/t/font_1440130445_6601267.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
-	url('//at.alicdn.com/t/font_1440130445_6601267.woff') format('woff'), /* chrome、firefox */
-	url('//at.alicdn.com/t/font_1440130445_6601267.ttf') format('truetype'), /* chrome、firefox、opera、Safari, Android, iOS 4.2+*/
-	url('//at.alicdn.com/t/font_1440130445_6601267.svg#iconfont') format('svg'); /* iOS 4.1- */
-}
-
-i.iconfont{
-	font-family: "iconfont";
-	font-style: normal;
-}
-
-body{
-	margin: 0;
-	padding: 0;
-	font-family: 'Source Sans Pro', 'Helvetica Neue', Arial, sans-serif;
-	-webkit-font-smoothing: antialiased;
-	-moz-osx-font-smoothing: grayscale;
-}
-
-.wrapper{
-	.cornerBtnWrapper{
-		position : absolute;
-		right    : 10px;
-		top      : 10px;
-		z-index  : 1;
-		width: 100%;
-		text-align: right;
-		color: @textDark; 
-	}
-
-	.cornerBtnWrapper a{
-		display: inline-block;
-		margin-right: 10px;
-		margin-left : 10px;
-	}
-
-	a,
-	a:hover{
-		text-decoration: none;
-	}	
-
-	a{
-		font-size: 16px;
-		color: @main;
-	}
-
-	h4.subTitle{
-		font-size: 30px;
-		margin: 0;
-		padding: 50px 0 10px 0;
-		width: 100%;
-		text-align: center;
-		color: @textDark;
-	}
-
-	h4.subTitle.white{
-		color: #FFF;
-	}
-
-	code{
-		display: inline-block;
-	}
-
-	.actionBtn.actionBtnWhite{
-		color: #FFF;
-		border: 1px solid #FFF;
-
-	}
-
-	.actionBtn.actionBtnWhite:hover{
-		background: @gray;
-		color: @dark;
-	}
-
-	.actionBtn{
-		color: @dark;
-		border: 1px solid @dark;
-		line-height: 30px;
-		font-size: 30px;
-		padding: 20px 45px;
-		border-radius: 30px;
-		display: inline-block;
-		transition:0.3s;
-
-		@media only screen 
-		and (min-device-width: 320px) 
-		and (max-device-width: 600px)
-		and (-webkit-min-device-pixel-ratio: 2){
-			font-size:16px;
-			padding: 10px 20px;
-		}
-	}
-
-	.actionBtn:hover{
-		background: @dark;
-		color: @gray;
-	}
-}
-
-.wrapper>div{
-	width: 100%;
-	min-width: @normalContent;
-
-	@media only screen 
-	and (min-device-width: 320px) 
-	and (max-device-width: 600px)
-	and (-webkit-min-device-pixel-ratio: 2){
-		min-width: @normalContentMobile;
-	}
-}
-
-
-
-.brief{
-	height: 300px;
-	text-align: center;
-	padding: 100px 0;
-	position: relative;
-	margin-top: 20px;
-
-
-	@media only screen 
-	and (min-device-width: 320px) 
-	and (max-device-width: 600px)
-	and (-webkit-min-device-pixel-ratio: 2){
-		padding: 60px 0 90px;
-	}
-
-	.slogan{
-		font-size: 16px;
-		color: @textDark;
-		padding: 0 20px;
-	}
-}
-
-.feature{
-	background: @darkGray; 
-
-	.featureContent{
-		@media only screen 
-		and (min-device-width: 320px) 
-		and (max-device-width: 600px)
-		and (-webkit-min-device-pixel-ratio: 2){
-			width: @wideContentMobile;
-		}
-
-		width: @wideContent;
-		margin: 0 auto;
-
-		.item{
-			padding: 30px 0 20px;
-			width: 280px;
-			/*border: 1px solid #AAA;*/
-			margin: 0 10px;
-			float: left;
-			box-sizing:border-box;
-			-webkit-box-sizing:border-box;
-			font-size: 30px;
-			text-align: center;
-		}
-
-		.iconWrapper{
-			display: inline-block;
-			line-height: 40px;
-			width: 70px;
-			text-align: center;
-			font-size: 40px;
-			color: @textDark;
-		}
-		.iconWrapper .bigger{
-			font-size: 44px;
-		}
-
-		h4{
-			color: @textDark;
-			margin: 12px auto 2px;
-			font-size: 20px;
-		}
-
-		h5{
-			color: @textLight;
-			margin: 0;
-		}
-
-		h5,
-		a{
-			font-size: 14px;
-			line-height: 20px;
-		}
-
-
-		@media only screen 
-		and (min-device-width: 320px) 
-		and (max-device-width: 600px)
-		and (-webkit-min-device-pixel-ratio: 2){
-			.item{
-				padding: 20px 0;
-				float     :none;
-				margin    : 0 auto;
-				font-size : 24px;
-			}
-
-			.iconWrapper{
-				font-size: 25px;
-				line-height: 25px;
-			}	
-
-			.iconWrapper .bigger{
-				font-size: 30px;
-			}
-
-			h4{
-				font-size: 16px;
-				margin: 4px;
-			}
-
-		}
-	}
-}
-
-.quickstart{
-	background: @gray;
-
-	.quickstartContent{
-		position: relative;
-	}
-
-	.screenshot{
-		position: absolute;
-		right: 0;
-		bottom: 0;
-
-		@media only screen 
-		and (min-device-width: 320px) 
-		and (max-device-width: 600px)
-		and (-webkit-min-device-pixel-ratio: 2){
-			display : none;
-		}
-	}
-
-	code.simpleBash{
-	    font-family: monospace;
-	    font-weight: bold;
-	    color: #333;
-	    padding: 0;
-	}
-}
-
-.listSection{
-	.listContent{
-
-		@media only screen 
-		and (min-device-width: 320px) 
-		and (max-device-width: 600px)
-		and (-webkit-min-device-pixel-ratio: 2){
-			width: @normalContentMobile;
-		}
-
-		width: @normalContent;
-		margin: 0 auto;
-	}
-
-	ul{
-		margin: 0 auto;
-
-		@media only screen 
-		and (min-device-width: 320px) 
-		and (max-device-width: 600px)
-		and (-webkit-min-device-pixel-ratio: 2){
-			padding: 0 20px 0 30px;
-		}
-	}
-
-	li{
-		color: @textDark;
-		font-size: 16px;
-		line-height: 40px;
-	}
-}
-
-.sample{
-	background: @gray;
-	.sampleContent{
-
-		@media only screen 
-		and (min-device-width: 320px) 
-		and (max-device-width: 600px)
-		and (-webkit-min-device-pixel-ratio: 2){
-			width: @normalContentMobile;
-		}
-
-		width: @normalContent;
-		margin: 0 auto;
-	}
-
-
-	.item{
-		margin: 10px;
-	}
-
-	.itemTitle{
-		font-size: 16px;
-		margin: 0px 10px;
-		color: @textDark;
-
-		@media only screen 
-		and (min-device-width: 320px) 
-		and (max-device-width: 600px)
-		and (-webkit-min-device-pixel-ratio: 2){
-			margin :0;
-		}
-	}
-
-	.figure{
-		vertical-align: top;
-		@media only screen 
-		and (min-device-width: 320px) 
-		and (max-device-width: 600px)
-		and (-webkit-min-device-pixel-ratio: 2){
-			display: block;
-		    margin: 0 auto;
-		    text-align: center;
-		}
-	}
-
-	pre{
-		margin: 0;
-		display: inline-block;
-		vertical-align: top;
-		@media only screen 
-		and (min-device-width: 320px) 
-		and (max-device-width: 600px)
-		and (-webkit-min-device-pixel-ratio: 2){
-			width: 100%;
-		}
-	}
-
-	code{
-		width: 495px;
-		@media only screen 
-		and (min-device-width: 320px) 
-		and (max-device-width: 600px)
-		and (-webkit-min-device-pixel-ratio: 2){
-			width:100%;
-			margin: 0 auto;
-		    word-wrap: break-word;
-		    padding: 0;
-		}
-	}
-
-	hr{
-		border: none;
-		border-top: 1px solid @textLight;
-		width: 80%;
-		margin: 0 auto;
-		padding: 15px 0;
-	}
-
-	.readmoreBtn{
-		margin-left: 10px;
-		padding-bottom: 20px;
-	}
-}
-
-.readMore{
-	background: @gray;
-	padding-bottom: 50px;
-}
-
-.learnMore{
-	background: @dark;
-	text-align: center;
-	position: relative;
-	padding: 120px 0;
-	@media only screen 
-	and (min-device-width: 320px) 
-	and (max-device-width: 600px)
-	and (-webkit-min-device-pixel-ratio: 2){
-		padding: 70px 0;
-	}
-
-	h4.subtitle{
-		padding: 0;
-		margin-bottom: 30px;
-	}
-
-	.btnWrapper{
-		text-align: center;
-	}
-}
-