2017-02-28 18:06:43 +08:00
<!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" / >
2017-04-05 16:18:09 +08:00
< 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";
} 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 >
2017-02-28 18:06:43 +08:00
< / head >
< body >
< a href = "https://github.com/alibaba/anyproxy/tree/4.x" target = "_blank" >
2017-04-05 16:18:09 +08:00
< img style = "position: fixed; top: 0; right: 0; border: 0;z-index: 1;" src = "https://camo.githubusercontent.com/a6677b08c955af8400f44c6298f40e7d19cc5b2d/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f677261795f3664366436642e706e67"
2017-02-28 18:06:43 +08:00
alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_gray_6d6d6d.png">
< / a >
< article class = "markdown-body" >
2017-04-05 16:18:09 +08:00
< div class = "toc-container" id = "j_toc" >
< div class = "toc-content" > < ul class = "nav nav-list" >
2017-02-28 18:06:43 +08:00
< li class = "sidebar-header-1" > < a href = "#anyproxy" > AnyProxy< / a > < / li >
2017-04-05 16:18:09 +08:00
< 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 >
2017-03-03 13:53:37 +08:00
< li class = "sidebar-header-3" > < a href = "#summary" > summary< / a > < / li >
2017-04-05 16:18:09 +08:00
< li class = "sidebar-header-4" > < a href = "#summary-1" > summary< / a > < / li >
2017-03-03 13:53:37 +08:00
< li class = "sidebar-header-3" > < a href = "#beforesendrequest" > beforeSendRequest< / a > < / li >
2017-02-28 18:06:43 +08:00
< li class = "sidebar-header-4" > < a href = "#beforesendrequest(requestdetail)" > beforeSendRequest(requestDetail)< / a > < / li >
2017-03-03 13:53:37 +08:00
< li class = "sidebar-header-3" > < a href = "#beforesendresponse" > beforeSendResponse< / a > < / li >
2017-02-28 18:06:43 +08:00
< li class = "sidebar-header-4" > < a href = "#beforesendresponse(requestdetail,-responsedetail)" > beforeSendResponse(requestDetail, responseDetail)< / a > < / li >
2017-03-03 13:53:37 +08:00
< li class = "sidebar-header-3" > < a href = "#beforedealhttpsrequest" > beforeDealHttpsRequest< / a > < / li >
2017-02-28 18:06:43 +08:00
< li class = "sidebar-header-4" > < a href = "#beforedealhttpsrequest(requestdetail)" > beforeDealHttpsRequest(requestDetail)< / a > < / li >
2017-03-03 13:53:37 +08:00
< 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 >
2017-02-28 18:06:43 +08:00
< li class = "sidebar-header-3" > < a href = "#faq" > FAQ< / a > < / li >
2017-04-05 16:18:09 +08:00
< 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 = "#config-ios/android-proxy-server" > config iOS/Android proxy server< / a > < / li >
< / ul >
< / div >
2017-02-28 18:06:43 +08:00
< / div >
< div class = "main-content" > < h1 id = "anyproxy" > < a class = "header-link" href = "#anyproxy" > < / a > AnyProxy< / h1 >
2017-04-05 16:18:09 +08:00
< 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 >
2017-02-28 18:06:43 +08:00
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< li > Offer you the ablity to handle http traffic by invoking a js module< / li >
< li > Intercept https< / li >
< li > GUI webinterface< / li >
2017-02-28 18:06:43 +08:00
< / ul >
2017-04-05 16:18:09 +08:00
< p > Change Logs since 3.x:< / p >
2017-02-28 18:06:43 +08:00
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< li > Support Promise and Generator in rule module< / li >
< li > Simplified interface in rule module< / li >
< li > A newly designed web interface< / li >
2017-02-28 18:06:43 +08:00
< / ul >
< p class = "img-container" > < img src = "https://zos.alipayobjects.com/rmsportal/SqVntpzmscXPbSzfcGcr.png" width = "500" / > < / p >
2017-04-05 16:18:09 +08:00
< 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 >
2017-02-28 18:06:43 +08:00
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< li > start AnyProxy in command line, with default port 8001< / li >
2017-02-28 18:06:43 +08:00
< / ul >
< pre class = "hljs" > < code > anyproxy< / code > < / pre > < ul class = "list" >
2017-04-05 16:18:09 +08:00
< 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 >
2017-02-28 18:06:43 +08:00
< / ul >
2017-04-05 16:18:09 +08:00
< h3 id = "other-commands" > < a class = "header-link" href = "#other-commands" > < / a > other commands< / h3 >
2017-02-28 18:06:43 +08:00
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< li > specify the port of http proxy< / li >
2017-02-28 18:06:43 +08:00
< / ul >
2017-04-05 16:18:09 +08:00
< 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 >
2017-02-28 18:06:43 +08:00
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< li > AnyProxy does NOT intercept https requests by default. To view decrypted info, you have to config the CA certificate.< / li >
2017-02-28 18:06:43 +08:00
< / ul >
< blockquote >
2017-04-05 16:18:09 +08:00
< 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 >
2017-02-28 18:06:43 +08:00
< / blockquote >
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< li > generate certifycates and intercept< / li >
2017-02-28 18:06:43 +08:00
< / ul >
2017-04-05 16:18:09 +08:00
< 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 >
2017-02-28 18:06:43 +08:00
< / ul >
2017-04-05 16:18:09 +08:00
< 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 >
2017-02-28 18:06:43 +08:00
< blockquote >
2017-04-05 16:18:09 +08:00
< p > Make sure your rule file is got from a trusted source. Otherwise, you may face some unknown security risk.< / p >
2017-02-28 18:06:43 +08:00
< / blockquote >
2017-04-05 16:18:09 +08:00
< p > Rule module could do the following stuff:< / p >
2017-02-28 18:06:43 +08:00
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< li > intercept and modify the request which is being sent< ul class = "list" >
< li > editable fields include request header, body, target address< / li >
2017-02-28 18:06:43 +08:00
< / ul >
< / li >
2017-04-05 16:18:09 +08:00
< li > intercept and modify the response from server< ul class = "list" >
< li > editable fields include response status code, header, body< / li >
2017-02-28 18:06:43 +08:00
< / ul >
< / li >
2017-04-05 16:18:09 +08:00
< li > intercept https requests, modify request and response< / li >
2017-02-28 18:06:43 +08:00
< / ul >
2017-04-05 16:18:09 +08:00
< h3 id = "sample" > < a class = "header-link" href = "#sample" > < / a > sample< / h3 >
2017-02-28 18:06:43 +08:00
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< li > < p > Target< / p >
2017-02-28 18:06:43 +08:00
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< 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 >
2017-02-28 18:06:43 +08:00
< / ul >
< / li >
2017-04-05 16:18:09 +08:00
< li > < p > Step 1, Write the rule file, save as sample.js< / p >
2017-02-28 18:06:43 +08:00
< pre class = "hljs" > < code > < span class = "hljs-comment" > // file: sample.js< / span >
< span class = "hljs-built_in" > module< / span > .exports = {
2017-04-05 16:18:09 +08:00
< span class = "hljs-attr" > summary< / span > : < span class = "hljs-string" > 'a rule to modify response'< / span > ,
2017-02-28 18:06:43 +08:00
*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 > ) => < / span > {
setTimeout(< span class = "hljs-function" > < span class = "hljs-params" > ()< / span > => < / span > { < span class = "hljs-comment" > // delay< / span >
resolve({ < span class = "hljs-attr" > response< / span > : newResponse });
}, < span class = "hljs-number" > 5000< / span > );
});
}
},
};< / code > < / pre > < / li >
2017-04-05 16:18:09 +08:00
< li > < p > Step 2, start AnyProxy and load the rule file< / p >
2017-02-28 18:06:43 +08:00
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< li > run < code > anyproxy --rule sample.js< / code > < / li >
2017-02-28 18:06:43 +08:00
< / ul >
< / li >
2017-04-05 16:18:09 +08:00
< li > < p > Step 3, test< / p >
2017-02-28 18:06:43 +08:00
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< li > < p > use curl < / p >
2017-02-28 18:06:43 +08:00
< pre class = "hljs" > < code > curl http://httpbin.org/user-agent --proxy http://127.0.0.1:8001< / code > < / pre > < / li >
2017-04-05 16:18:09 +08:00
< 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 >
2017-02-28 18:06:43 +08:00
< / li >
2017-04-05 16:18:09 +08:00
< li > < p > the expected response from proxy is < / p >
2017-02-28 18:06:43 +08:00
< / 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 >
2017-04-05 16:18:09 +08:00
< li > < p > Step 4, view the request log< / p >
2017-02-28 18:06:43 +08:00
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< 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 >
2017-02-28 18:06:43 +08:00
< / ul >
< / li >
< / ul >
2017-04-05 16:18:09 +08:00
< h3 id = "the-entire-process" > < a class = "header-link" href = "#the-entire-process" > < / a > the entire process< / h3 >
2017-02-28 18:06:43 +08:00
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< li > The flow chart is as follows< / li >
2017-03-03 13:53:37 +08:00
< / ul >
< p class = "img-container" > < img src = "https://zos.alipayobjects.com/rmsportal/TWyNuSJtEZBdrdcOMRjE.png" width = "550" / > < / p >
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< li > < p > When got an http request, the entire process of proxy server is< / p >
2017-02-28 18:06:43 +08:00
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< 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 >
2017-02-28 18:06:43 +08:00
< / ul >
< / li >
2017-04-05 16:18:09 +08:00
< li > < p > When AnyProxy get https request, it could replace the certificate and decrypt the request data< / p >
2017-02-28 18:06:43 +08:00
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< 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 >
2017-02-28 18:06:43 +08:00
< / ul >
< / li >
< / ul >
2017-04-05 16:18:09 +08:00
< h3 id = "how-to-load-rule-module" > < a class = "header-link" href = "#how-to-load-rule-module" > < / a > how to load rule module< / h3 >
2017-02-28 18:06:43 +08:00
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< 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 >
2017-02-28 18:06:43 +08:00
< pre class = "hljs" > < code > anyproxy --rule https://sample.com/rule.js< / code > < / pre > < / li >
2017-04-05 16:18:09 +08:00
< li > < p > use an npm module< / p >
2017-02-28 18:06:43 +08:00
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< li > AnyProxy uses < code > require()< / code > to load rule module. You could either load a local npm module or a global-installed one.< / li >
2017-02-28 18:06:43 +08:00
< / ul >
2017-04-05 16:18:09 +08:00
< pre class = "hljs" > < code > anyproxy --rule ./myRulePkg/ < span class = "hljs-comment" > #local module< / span >
npm i -g myRulePkg & & anyproxy --rule myRulePkg < span class = "hljs-comment" > #global-installed module< / span > < / code > < / pre > < / li >
2017-02-28 18:06:43 +08:00
< / ul >
2017-04-05 16:18:09 +08:00
< 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 >
2017-02-28 18:06:43 +08:00
< pre class = "hljs" > < code > < span class = "hljs-built_in" > module< / span > .exports = {
2017-04-05 16:18:09 +08:00
< 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 >
2017-03-03 13:53:37 +08:00
*beforeSendRequest(requestDetail) { < span class = "hljs-comment" > /* ... */< / span > },
2017-04-05 16:18:09 +08:00
< span class = "hljs-comment" > // deal response before send to client < / span >
2017-03-03 13:53:37 +08:00
*beforeSendResponse(requestDetail, responseDetail) { < span class = "hljs-comment" > /* ... */< / span > },
2017-04-05 16:18:09 +08:00
< span class = "hljs-comment" > // if deal https request< / span >
2017-03-03 13:53:37 +08:00
*beforeDealHttpsRequest(requestDetail) { < span class = "hljs-comment" > /* ... */< / span > },
2017-04-05 16:18:09 +08:00
< span class = "hljs-comment" > // error happened when dealing requests< / span >
2017-03-03 13:53:37 +08:00
*onError(requestDetail, error) { < span class = "hljs-comment" > /* ... */< / span > },
2017-04-05 16:18:09 +08:00
< span class = "hljs-comment" > // error happened when connect to https server< / span >
2017-03-03 13:53:37 +08:00
*onConnectError(requestDetail, error) { < span class = "hljs-comment" > /* ... */< / span > }
2017-04-05 16:18:09 +08:00
};< / 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 >
2017-02-28 18:06:43 +08:00
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< li > Introduction of this rule file. AnyProxy will read this field and give some tip to user.< / li >
2017-02-28 18:06:43 +08:00
< / ul >
2017-03-03 13:53:37 +08:00
< h3 id = "beforesendrequest" > < a class = "header-link" href = "#beforesendrequest" > < / a > beforeSendRequest< / h3 >
2017-02-28 18:06:43 +08:00
< h4 id = "beforesendrequest(requestdetail)" > < a class = "header-link" href = "#beforesendrequest(requestdetail)" > < / a > beforeSendRequest(requestDetail)< / h4 >
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< li > Before sending request to server, AnyProxy will call < code > beforeSendRequest< / code > with param < code > requestDetail< / code > < / li >
2017-02-28 18:06:43 +08:00
< li > < code > requestDetail< / code > < ul class = "list" >
2017-04-05 16:18:09 +08:00
< 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(' http' ).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 >
2017-02-28 18:06:43 +08:00
< / ul >
< / li >
2017-04-05 16:18:09 +08:00
< li > < p > e.g. When requesting < em > anyproxy.io< / em > , < code > requestDetail< / code > is something like the following< / p >
2017-02-28 18:06:43 +08:00
< 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 >
2017-04-05 16:18:09 +08:00
< li > < p > Any of these return values are valid< / p >
2017-02-28 18:06:43 +08:00
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< li > do nothing, and return null< / li >
2017-02-28 18:06:43 +08:00
< / ul >
< pre class = "hljs" > < code > < span class = "hljs-keyword" > return< / span > < span class = "hljs-literal" > null< / span > ;< / code > < / pre > < ul class = "list" >
2017-04-05 16:18:09 +08:00
< li > modify the request protocol, i.e. force use https< / li >
2017-02-28 18:06:43 +08:00
< / 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" >
2017-04-05 16:18:09 +08:00
< li > modify request param< / li >
2017-02-28 18:06:43 +08:00
< / 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" >
2017-04-05 16:18:09 +08:00
< li > modify request body< / li >
2017-02-28 18:06:43 +08:00
< / 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 >
2017-04-05 16:18:09 +08:00
< span class = "hljs-comment" > // requestOptions can also be used here< / span >
2017-02-28 18:06:43 +08:00
};< / code > < / pre > < ul class = "list" >
2017-04-05 16:18:09 +08:00
< li > give response to the client, not sending request any longer. < code > statusCode< / code > < code > headers< / code > are required is this situation.< / li >
2017-02-28 18:06:43 +08:00
< / ul >
< pre class = "hljs" > < code > < span class = "hljs-keyword" > return< / span > {
2017-03-03 13:53:37 +08:00
< 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 < string> or < buffer> '< / span >
}
2017-02-28 18:06:43 +08:00
};< / code > < / pre > < / li >
< / ul >
2017-03-03 13:53:37 +08:00
< h3 id = "beforesendresponse" > < a class = "header-link" href = "#beforesendresponse" > < / a > beforeSendResponse< / h3 >
2017-02-28 18:06:43 +08:00
< h4 id = "beforesendresponse(requestdetail,-responsedetail)" > < a class = "header-link" href = "#beforesendresponse(requestdetail,-responsedetail)" > < / a > beforeSendResponse(requestDetail, responseDetail)< / h4 >
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< 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 >
2017-02-28 18:06:43 +08:00
< li > < code > responseDetail< / code > < ul class = "list" >
2017-04-05 16:18:09 +08:00
< 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 >
2017-02-28 18:06:43 +08:00
< / ul >
< / li >
2017-04-05 16:18:09 +08:00
< li > < p > e.g. When requesting < em > anyproxy.io< / em > , < code > responseDetail< / code > is something like the following< / p >
2017-03-03 13:53:37 +08:00
< 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 >
2017-04-05 16:18:09 +08:00
< li > < p > Any of these return values are valid< / p >
2017-02-28 18:06:43 +08:00
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< li > do nothing, and return null< / li >
2017-02-28 18:06:43 +08:00
< / ul >
< pre class = "hljs" > < code > < span class = "hljs-keyword" > return< / span > < span class = "hljs-literal" > null< / span > ;< / code > < / pre > < ul class = "list" >
2017-04-05 16:18:09 +08:00
< li > modify the response status code< / li >
2017-02-28 18:06:43 +08:00
< / 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" >
2017-04-05 16:18:09 +08:00
< li > modify the response content< / li >
2017-02-28 18:06:43 +08:00
< / 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 >
2017-03-03 13:53:37 +08:00
< h3 id = "beforedealhttpsrequest" > < a class = "header-link" href = "#beforedealhttpsrequest" > < / a > beforeDealHttpsRequest< / h3 >
2017-02-28 18:06:43 +08:00
< h4 id = "beforedealhttpsrequest(requestdetail)" > < a class = "header-link" href = "#beforedealhttpsrequest(requestdetail)" > < / a > beforeDealHttpsRequest(requestDetail)< / h4 >
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< 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 >
2017-02-28 18:06:43 +08:00
< li > < code > requestDetail< / code > < ul class = "list" >
2017-04-05 16:18:09 +08:00
< li > < code > host< / code > {string} the target host to request. Due to the request protocol, full url couldn' 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 >
2017-02-28 18:06:43 +08:00
< / ul >
< / li >
2017-04-05 16:18:09 +08:00
< li > return value< ul class = "list" >
< li > < code > true< / code > or < code > false< / code > , whether AnyProxy should intercept the https request< / li >
2017-02-28 18:06:43 +08:00
< / ul >
< / li >
< / ul >
2017-03-03 13:53:37 +08:00
< 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" >
2017-04-05 16:18:09 +08:00
< 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 >
2017-03-03 13:53:37 +08:00
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< li > do nothing, and AnyProxy will response a default error page< / li >
2017-03-03 13:53:37 +08:00
< / ul >
< pre class = "hljs" > < code > < span class = "hljs-keyword" > return< / span > < span class = "hljs-literal" > null< / span > ;< / code > < / pre > < ul class = "list" >
2017-04-05 16:18:09 +08:00
< li > return a customized error page< / li >
2017-03-03 13:53:37 +08:00
< / 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 < string> or < buffer> '< / 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" >
2017-04-05 16:18:09 +08:00
< 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 >
2017-03-03 13:53:37 +08:00
< / ul >
2017-02-28 18:06:43 +08:00
< h3 id = "faq" > < a class = "header-link" href = "#faq" > < / a > FAQ< / h3 >
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< 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 >
2017-02-28 18:06:43 +08:00
< / ul >
2017-04-05 16:18:09 +08:00
< h2 id = "rule-samples" > < a class = "header-link" href = "#rule-samples" > < / a > Rule Samples< / h2 >
2017-02-28 18:06:43 +08:00
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< 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 >
2017-02-28 18:06:43 +08:00
< / ul >
< / li >
< / ul >
2017-04-05 16:18:09 +08:00
< h3 id = "use-local-response" > < a class = "header-link" href = "#use-local-response" > < / a > use local response< / h3 >
2017-02-28 18:06:43 +08:00
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< li > intercept the request towards < a href = "http://httpbin.org" > http://httpbin.org< / a > , return the local-defined response< / li >
2017-02-28 18:06:43 +08:00
< / 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
};
}
},
2017-04-05 16:18:09 +08:00
};< / code > < / pre > < h3 id = "modify-request-header" > < a class = "header-link" href = "#modify-request-header" > < / a > modify request header< / h3 >
2017-02-28 18:06:43 +08:00
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< li > modify the user-agent sent to httpbin.org< / li >
2017-02-28 18:06:43 +08:00
< / 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
};
}
},
2017-04-05 16:18:09 +08:00
};< / code > < / pre > < h3 id = "modify-request-body" > < a class = "header-link" href = "#modify-request-body" > < / a > modify request body< / h3 >
2017-02-28 18:06:43 +08:00
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< li > modify the post body of < a href = "http://httpbin.org/post" > http://httpbin.org/post< / a > < / li >
2017-02-28 18:06:43 +08:00
< / 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:
2017-02-28 18:15:58 +08:00
curl -H "Content-Type: text/plain" -X POST -d 'original post data' http://httpbin.org/post --proxy http://127.0.0.1:8001
2017-02-28 18:06:43 +08:00
expected response:
{ "data": "i-am-anyproxy-modified-post-data" }
*/< / span >
< span class = "hljs-built_in" > module< / span > .exports = {
*beforeSendRequest(requestDetail) {
2017-02-28 18:15:58 +08:00
< span class = "hljs-keyword" > if< / span > (requestDetail.url.indexOf(< span class = "hljs-string" > 'http://httpbin.org/post'< / span > ) === < span class = "hljs-number" > 0< / span > ) {
2017-02-28 18:06:43 +08:00
< span class = "hljs-keyword" > return< / span > {
2017-02-28 18:15:58 +08:00
< span class = "hljs-attr" > requestData< / span > : < span class = "hljs-string" > 'i-am-anyproxy-modified-post-data'< / span >
2017-02-28 18:06:43 +08:00
};
}
},
2017-04-05 16:18:09 +08:00
};< / code > < / pre > < h3 id = "modify-the-request-target" > < a class = "header-link" href = "#modify-the-request-target" > < / a > modify the request target< / h3 >
2017-02-28 18:06:43 +08:00
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< 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 >
2017-02-28 18:06:43 +08:00
< / 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
};
}
},
2017-04-05 16:18:09 +08:00
};< / code > < / pre > < h3 id = "modify-request-protocol" > < a class = "header-link" href = "#modify-request-protocol" > < / a > modify request protocol< / h3 >
2017-02-28 18:06:43 +08:00
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< li > modify the http request towards < a href = "http://httpbin.org" > http://httpbin.org< / a > to https< / li >
2017-02-28 18:06:43 +08:00
< / 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
};
}
}
2017-04-05 16:18:09 +08:00
};< / code > < / pre > < h3 id = "modify-response-status-code" > < a class = "header-link" href = "#modify-response-status-code" > < / a > modify response status code< / h3 >
2017-02-28 18:06:43 +08:00
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< li > modify all status code from < a href = "http://httpbin.org" > http://httpbin.org< / a > to 404< / li >
2017-02-28 18:06:43 +08:00
< / 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
};
}
}
2017-04-05 16:18:09 +08:00
};< / code > < / pre > < h3 id = "modify-the-response-header" > < a class = "header-link" href = "#modify-the-response-header" > < / a > modify the response header< / h3 >
2017-02-28 18:06:43 +08:00
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< 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 >
2017-02-28 18:06:43 +08:00
< / 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
};
}
}
2017-04-05 16:18:09 +08:00
};< / 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 >
2017-02-28 18:06:43 +08:00
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< 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 >
2017-02-28 18:06:43 +08:00
< / 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 > ) => < / span > {
setTimeout(< span class = "hljs-function" > < span class = "hljs-params" > ()< / span > => < / 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 > );
});
}
},
2017-04-05 16:18:09 +08:00
};< / 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 >
2017-02-28 18:06:43 +08:00
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< li > install< / li >
2017-02-28 18:06:43 +08:00
< / ul >
2017-04-05 16:18:09 +08:00
< 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 >
2017-02-28 18:06:43 +08:00
< / 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 > , () => { < span class = "hljs-comment" > /* */< / span > });
proxyServer.on(< span class = "hljs-string" > 'error'< / span > , (e) => { < 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" >
2017-04-05 16:18:09 +08:00
< li > < p > create a proxy server< / p >
2017-02-28 18:06:43 +08:00
< 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" >
2017-04-05 16:18:09 +08:00
< 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 >
2017-02-28 18:06:43 +08:00
< / ul >
< / li >
< / ul >
< / li >
< li > < p > Event: < code > ready< / code > < / p >
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< li > emit when proxy server is ready< / li >
< li > sample< / li >
2017-02-28 18:06:43 +08:00
< / 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" >
2017-04-05 16:18:09 +08:00
< li > emit when error happened inside proxy server< / li >
< li > sample< / li >
2017-02-28 18:06:43 +08:00
< / 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" >
2017-04-05 16:18:09 +08:00
< li > start proxy server< / li >
< li > sample< / li >
2017-02-28 18:06:43 +08:00
< / ul >
< pre class = "hljs" > < code > proxy.start();< / code > < / pre > < / li >
< li > < p > Method: < code > close< / code > < / p >
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< li > close proxy server< / li >
< li > sample< / li >
2017-02-28 18:06:43 +08:00
< / ul >
< pre class = "hljs" > < code > proxy.close();< / code > < / pre > < / li >
< / ul >
< / li >
< li > < p > AnyProxy.utils.systemProxyMgr< / p >
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< li > manage the system proxy config. sudo password may be required< / li >
< li > sample< / li >
2017-02-28 18:06:43 +08:00
< / ul >
2017-04-05 16:18:09 +08:00
< pre class = "hljs" > < code > < span class = "hljs-comment" > // set 127.0.0.1:8001 as system http server< / span >
2017-02-28 18:06:43 +08:00
AnyProxy.utils.systemProxyMgr.enableGlobalProxy(< span class = "hljs-string" > '127.0.0.1'< / span > , < span class = "hljs-string" > '8001'< / span > );
2017-04-05 16:18:09 +08:00
< span class = "hljs-comment" > // disable global proxy server< / span >
2017-02-28 18:06:43 +08:00
AnyProxy.utils.systemProxyMgr.disableGlobalProxy();< / code > < / pre > < / li >
< li > < p > AnyProxy.utils.certMgr< / p >
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< li > Manage certificates of AnyProxy< / li >
2017-02-28 18:06:43 +08:00
< li > < code > AnyProxy.utils.certMgr.ifRootCAFileExists()< / code > < ul class = "list" >
2017-04-05 16:18:09 +08:00
< li > detect if AnyProx rootCA exists< / li >
2017-02-28 18:06:43 +08:00
< / ul >
< / li >
< li > < code > AnyProxy.utils.certMgr.generateRootCA(callback)< / code > < ul class = "list" >
2017-04-05 16:18:09 +08:00
< li > generate a rootCA< / li >
2017-02-28 18:06:43 +08:00
< / ul >
< / li >
2017-04-05 16:18:09 +08:00
< li > Sample< / li >
2017-02-28 18:06:43 +08:00
< / 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 > ) => < / 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 >
2017-04-05 16:18:09 +08:00
< h2 id = "about-anyproxy" > < a class = "header-link" href = "#about-anyproxy" > < / a > About AnyProxy< / h2 >
2017-02-28 18:06:43 +08:00
< 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 >
2017-04-05 16:18:09 +08:00
< 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 >
2017-02-28 18:06:43 +08:00
< / ul >
2017-04-05 16:18:09 +08:00
< 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 >
2017-02-28 18:06:43 +08:00
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< li > this kind of errors is usually caused by untrusted root CA< / li >
2017-02-28 18:06:43 +08:00
< / ul >
< p class = "img-container" > < img src = "https://zos.alipayobjects.com/rmsportal/CBkLGYgvoHAYwNVAYkpk.png" width = "450" / > < / p >
< blockquote >
2017-04-05 16:18:09 +08:00
< p > Warning: please keep your root CA safe since it may influence your system security.< / p >
2017-02-28 18:06:43 +08:00
< / blockquote >
2017-04-05 16:18:09 +08:00
< p > install : < / p >
2017-02-28 18:06:43 +08:00
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< li > < p > double click < em > rootCA.crt< / em > < / p >
2017-02-28 18:06:43 +08:00
< / li >
2017-04-05 16:18:09 +08:00
< li > < p > add cert into login or system< / p >
2017-02-28 18:06:43 +08:00
< / li >
< / ul >
< p class = "img-container" > < img src = "https://zos.alipayobjects.com/rmsportal/bCwNUFFpvsmVuljQKrIk.png" width = "350" / > < / p >
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< li > find the newly imported AnyProxy certificates, configured as < strong > Always Trust< / strong > < / li >
2017-02-28 18:06:43 +08:00
< / ul >
< p class = "img-container" > < img src = "https://zos.alipayobjects.com/rmsportal/HOmEElNGdoZEWFMLsTNT.png" width = "700" / > < / p >
2017-04-05 16:18:09 +08:00
< h3 id = "trust-root-ca-in-windows" > < a class = "header-link" href = "#trust-root-ca-in-windows" > < / a > trust root CA in windows< / h3 >
2017-02-28 18:06:43 +08:00
< p class = "img-container" > < img src = "https://t.alipayobjects.com/tfscom/T1D3hfXeFtXXXXXXXX.jpg" width = "700" / > < / p >
2017-04-05 16:18:09 +08:00
< h3 id = "config-osx-system-proxy" > < a class = "header-link" href = "#config-osx-system-proxy" > < / a > config OSX system proxy< / h3 >
2017-02-28 18:06:43 +08:00
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< li > the config is in wifi - advanced< / li >
2017-02-28 18:06:43 +08:00
< / ul >
< p class = "img-container" > < img src = "https://zos.alipayobjects.com/rmsportal/vduwhobSTypTfgniBvoa.png" width = "500" / > < / p >
2017-04-05 16:18:09 +08:00
< h3 id = "config-http-proxy-server" > < a class = "header-link" href = "#config-http-proxy-server" > < / a > config http proxy server< / h3 >
2017-02-28 18:06:43 +08:00
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< 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 >
2017-02-28 18:06:43 +08:00
< / ul >
< p class = "img-container" > < img src = "https://zos.alipayobjects.com/rmsportal/jIPZrKmqXRaSledQeJUJ.png" width = "500" / > < / p >
2017-04-05 16:18:09 +08:00
< h3 id = "config-ios/android-proxy-server" > < a class = "header-link" href = "#config-ios/android-proxy-server" > < / a > config iOS/Android proxy server< / h3 >
2017-02-28 18:06:43 +08:00
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< li > < p > proxy settings are placed in wifi setting< / p >
2017-02-28 18:06:43 +08:00
< / li >
2017-04-05 16:18:09 +08:00
< li > < p > iOS< / p >
2017-02-28 18:06:43 +08:00
< / li >
< / ul >
< p class = "img-container" > < img src = "https://zos.alipayobjects.com/rmsportal/tLGqIozhffTccUgPakuw.png" width = "260" / > < / p >
< ul class = "list" >
2017-04-05 16:18:09 +08:00
< li > Android< / li >
2017-02-28 18:06:43 +08:00
< / 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 >
2017-03-01 10:14:06 +08:00
window.onload = function(){
2017-02-28 18:06:43 +08:00
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
2017-03-01 10:14:06 +08:00
var scrollYThres = window.scrollY + 200;
2017-02-28 18:06:43 +08:00
var target;
2017-03-01 10:14:06 +08:00
if (scrollYThres < 100 ) {
2017-02-28 18:06:43 +08:00
target = itemList[0].tocItem;
} else {
itemList.forEach(function (item, index) {
if (target) return;
2017-03-01 10:14:06 +08:00
if (index > 0) {
if (item.top >= scrollYThres) {
target = itemList[index - 1].tocItem;
2017-02-28 18:06:43 +08:00
}
}
});
}
$('.toc-active').removeClass('toc-active');
$(target).addClass('toc-active');
};
window.onscroll = updateTocActive;
updateTocActive();
2017-03-01 10:14:06 +08:00
}
2017-02-28 18:06:43 +08:00
< / script >
< / body >
< / html >