2014-11-26 22:31:01 +08:00
<!DOCTYPE html>
2014-09-03 16:17:58 +08:00
< html >
2014-11-26 22:31:01 +08:00
2014-09-03 16:17:58 +08:00
< head >
2014-11-26 22:31:01 +08:00
< meta charset = 'utf-8' >
2014-09-03 16:17:58 +08:00
< meta http-equiv = "X-UA-Compatible" content = "chrome=1" >
2014-11-26 22:31:01 +08:00
< meta name = "description" content = "Anyproxy : A fully configurable proxy in NodeJS, which can handle HTTPS requests perfectly." >
2014-11-26 11:57:05 +08:00
2014-11-26 22:31:01 +08:00
< link rel = "stylesheet" type = "text/css" media = "screen" href = "stylesheets/stylesheet.css" >
2014-11-26 11:57:05 +08:00
2014-11-26 22:31:01 +08:00
< title > Anyproxy< / title >
2014-09-03 16:17:58 +08:00
< / head >
2014-11-26 22:31:01 +08:00
2014-09-03 16:17:58 +08:00
< body >
2014-11-26 22:31:01 +08:00
<!-- HEADER -->
< div id = "header_wrap" class = "outer" >
< header class = "inner" >
< a id = "forkme_banner" href = "https://github.com/alibaba/anyproxy" > View on GitHub< / a >
< h1 id = "project_title" > Anyproxy< / h1 >
< h2 id = "project_tagline" > A fully configurable proxy in NodeJS, which can handle HTTPS requests perfectly.< / h2 >
< section id = "downloads" >
< a class = "zip_download_link" href = "https://github.com/alibaba/anyproxy/zipball/master" > Download this project as a .zip file< / a >
< a class = "tar_download_link" href = "https://github.com/alibaba/anyproxy/tarball/master" > Download this project as a tar.gz file< / a >
< / section >
< / header >
< / div >
<!-- MAIN CONTENT -->
< div id = "main_content_wrap" class = "outer" >
< section id = "main_content" class = "inner" >
2014-09-03 19:41:27 +08:00
< h1 >
2014-11-26 11:57:05 +08:00
< a id = "anyproxy" class = "anchor" href = "#anyproxy" aria-hidden = "true" > < span class = "octicon octicon-link" > < / span > < / a > anyproxy< / h1 >
2014-09-03 16:17:58 +08:00
2014-09-03 19:41:27 +08:00
< p > A fully configurable proxy in NodeJS, which can handle HTTPS requests perfectly.< / p >
2014-09-03 16:17:58 +08:00
2014-09-03 19:41:27 +08:00
< h2 >
2014-11-26 11:57:05 +08:00
< a id = "feature" class = "anchor" href = "#feature" aria-hidden = "true" > < span class = "octicon octicon-link" > < / span > < / a > Feature< / h2 >
2014-09-03 19:41:27 +08:00
< ul >
< li > work as http or https proxy< / li >
< li > fully configurable, you can modify a request at any stage by your own javascript code< / li >
< li > when working as https proxy, it can generate and intercept https requests for any domain without complaint by browser (after you trust its root CA)< / li >
< li > provide a web interface< / li >
2014-11-26 11:57:05 +08:00
< / ul >
< p > < img src = "http://gtms03.alicdn.com/tps/i3/TB1ddyqGXXXXXbXXpXXihxC1pXX-1000-549.jpg_640x640q90.jpg" alt = "screenshot" > < / p >
2014-09-03 16:17:58 +08:00
2014-09-03 19:41:27 +08:00
< h2 >
2014-11-26 11:57:05 +08:00
< a id = "usage" class = "anchor" href = "#usage" aria-hidden = "true" > < span class = "octicon octicon-link" > < / span > < / a > Usage< / h2 >
2014-09-03 16:17:58 +08:00
< h3 >
2014-11-26 11:57:05 +08:00
< a id = "step-1---install" class = "anchor" href = "#step-1---install" aria-hidden = "true" > < span class = "octicon octicon-link" > < / span > < / a > step 1 - install< / h3 >
2014-09-03 16:17:58 +08:00
2014-09-03 19:41:27 +08:00
< ul >
< li > install < a href = "http://nodejs.org/" > NodeJS< / a >
< / li >
< li >
< code > npm install -g anyproxy< / code > , may require < code > sudo< / code >
< / li >
2014-11-26 11:57:05 +08:00
< / ul >
< h3 >
< a id = "step-2---start-server" class = "anchor" href = "#step-2---start-server" aria-hidden = "true" > < span class = "octicon octicon-link" > < / span > < / a > step 2 - start server< / h3 >
2014-09-03 16:17:58 +08:00
2014-09-03 19:41:27 +08:00
< ul >
< li > start with default settings : < code > anyproxy< / code >
< / li >
< li > start with a specific port: < code > anyproxy --port 8001< / code >
< / li >
2014-11-26 11:57:05 +08:00
< / ul >
< h3 >
< a id = "step-3---launch-web-interface" class = "anchor" href = "#step-3---launch-web-interface" aria-hidden = "true" > < span class = "octicon octicon-link" > < / span > < / a > step 3 - launch web interface< / h3 >
2014-09-03 16:17:58 +08:00
2014-09-03 19:41:27 +08:00
< ul >
< li > visit < a href = "http://127.0.0.1:8002" > http://127.0.0.1:8002< / a > with modern browsers< / li >
2014-11-26 11:57:05 +08:00
< / ul >
< h2 >
< a id = "how-to-write-your-own-rule-file" class = "anchor" href = "#how-to-write-your-own-rule-file" aria-hidden = "true" > < span class = "octicon octicon-link" > < / span > < / a > How to write your own rule file< / h2 >
2014-09-03 16:17:58 +08:00
2014-09-03 19:41:27 +08:00
< ul >
< li > with rule file, you can modify a request at any stage, no matter it's just before sending or after servers' responding.< / li >
< li > actually ruleFile.js is a module for Nodejs, feel free to invoke your own modules.< / li >
< li > < code > anyproxy --rule /path/to/ruleFile.js< / code > < / li >
< li > you may learn how it works by our samples: < a href = "https://github.com/alipay-ct-wd/anyproxy/tree/master/rule_sample" > https://github.com/alipay-ct-wd/anyproxy/tree/master/rule_sample< / a >
< / li >
< li >
< p > samples in < a href = "https://github.com/alipay-ct-wd/anyproxy/tree/master/rule_sample" > rule_sample< / a > < / p >
2014-09-03 16:17:58 +08:00
2014-09-03 19:41:27 +08:00
< ul >
< li > < p > < strong > rule__blank.js< / strong > , blank rule file with some comments. You may read this before writing your own rule file.< / p > < / li >
< li > < p > < strong > rule_adjust_response_time.js< / strong > , delay all the response for 1500ms< / p > < / li >
< li >
< strong > rule_allow_CORS.js< / strong > , add CORS headers to allow cross-domain ajax request< / li >
< li >
< strong > rule_intercept_some_https_requests.js< / strong > , intercept https requests toward github.com< / li >
< li >
< strong > rule_remove_cache_header.js< / strong > , remove all cache-related headers from server< / li >
< li >
< strong > rule_replace_request_option.js< / strong > , replace request parameters before sending to the server< / li >
< li >
< strong > rule_replace_response_data.js< / strong > , modify response data< / li >
< li >
< strong > rule_replace_response_status_code.js< / strong > , replace server's status code< / li >
< li >
< strong > rule_use_local_data.js< / strong > , map some requests to local file< / li >
< / ul >
< / li >
< li > < p > rule file scheme is as follows, you may also get it from < a href = "https://github.com/alipay-ct-wd/anyproxy/blob/master/rule_sample/rule__blank.js" > rule__blank.js< / a > < / p > < / li >
2014-11-26 11:57:05 +08:00
< / ul >
2014-09-03 19:41:27 +08:00
2014-11-26 11:57:05 +08:00
< div class = "highlight highlight-javascript" > < pre >
2015-04-20 22:35:35 +08:00
< span class = "pl-c1" > module< / span > .exports < span class = "pl-k" > =< / span > {
2014-11-26 11:57:05 +08:00
< span class = "pl-c" > /*< / span >
< span class = "pl-c" > these functions will overwrite the default ones, write your own when necessary.< / span >
< span class = "pl-c" > */< / span >
< span class = "pl-c" > //whether to intercept this request by local logic< / span >
< span class = "pl-c" > //if the return value is true, anyproxy will call dealLocalResponse to get response data and will not send request to remote server anymore< / span >
2015-04-20 22:35:35 +08:00
< span class = "pl-en" > shouldUseLocalResponse< / span > : < span class = "pl-k" > function< / span > (< span class = "pl-smi" > req< / span > ,< span class = "pl-smi" > reqBody< / span > ){
2014-11-26 11:57:05 +08:00
< span class = "pl-k" > return< / span > < span class = "pl-c1" > false< / span > ;
},
< span class = "pl-c" > //you may deal the response locally instead of sending it to server< / span >
< span class = "pl-c" > //this function be called when shouldUseLocalResponse returns true< / span >
< span class = "pl-c" > //callback(statusCode,resHeader,responseData)< / span >
< span class = "pl-c" > //e.g. callback(200,{"content-type":"text/html"},"hello world")< / span >
2015-04-20 22:35:35 +08:00
< span class = "pl-en" > dealLocalResponse< / span > : < span class = "pl-k" > function< / span > (< span class = "pl-smi" > req< / span > ,< span class = "pl-smi" > reqBody< / span > ,< span class = "pl-smi" > callback< / span > ){
2014-11-26 11:57:05 +08:00
callback(statusCode,resHeader,responseData)
},
< span class = "pl-c" > //replace the request protocol when sending to the real server< / span >
< span class = "pl-c" > //protocol : "http" or "https"< / span >
2015-04-20 22:35:35 +08:00
< span class = "pl-en" > replaceRequestProtocol< / span > :< span class = "pl-k" > function< / span > (< span class = "pl-smi" > req< / span > ,< span class = "pl-smi" > protocol< / span > ){
< span class = "pl-k" > var< / span > newProtocol < span class = "pl-k" > =< / span > protocol;
2014-11-26 11:57:05 +08:00
< span class = "pl-k" > return< / span > newProtocol;
},
< span class = "pl-c" > //req is user's request sent to the proxy server< / span >
< span class = "pl-c" > //option is how the proxy server will send request to the real server. i.e. require("http").request(option,function(){...})< / span >
< span class = "pl-c" > //you may return a customized option to replace the original option< / span >
< span class = "pl-c" > //you should not write content-length header in options, since anyproxy will handle it for you< / span >
2015-04-20 22:35:35 +08:00
< span class = "pl-en" > replaceRequestOption< / span > : < span class = "pl-k" > function< / span > (< span class = "pl-smi" > req< / span > ,< span class = "pl-smi" > option< / span > ){
< span class = "pl-k" > var< / span > newOption < span class = "pl-k" > =< / span > option;
2014-11-26 11:57:05 +08:00
< span class = "pl-k" > return< / span > newOption;
},
< span class = "pl-c" > //replace the request body< / span >
2015-04-20 22:35:35 +08:00
< span class = "pl-en" > replaceRequestData< / span > : < span class = "pl-k" > function< / span > (< span class = "pl-smi" > req< / span > ,< span class = "pl-smi" > data< / span > ){
2014-11-26 11:57:05 +08:00
< span class = "pl-k" > return< / span > data;
},
< span class = "pl-c" > //replace the statusCode before it's sent to the user< / span >
2015-04-20 22:35:35 +08:00
< span class = "pl-en" > replaceResponseStatusCode< / span > : < span class = "pl-k" > function< / span > (< span class = "pl-smi" > req< / span > ,< span class = "pl-smi" > res< / span > ,< span class = "pl-smi" > statusCode< / span > ){
< span class = "pl-k" > var< / span > newStatusCode < span class = "pl-k" > =< / span > statusCode;
2014-11-26 11:57:05 +08:00
< span class = "pl-k" > return< / span > newStatusCode;
},
< span class = "pl-c" > //replace the httpHeader before it's sent to the user< / span >
< span class = "pl-c" > //Here header == res.headers< / span >
2015-04-20 22:35:35 +08:00
< span class = "pl-en" > replaceResponseHeader< / span > : < span class = "pl-k" > function< / span > (< span class = "pl-smi" > req< / span > ,< span class = "pl-smi" > res< / span > ,< span class = "pl-smi" > header< / span > ){
< span class = "pl-k" > var< / span > newHeader < span class = "pl-k" > =< / span > header;
2014-11-26 11:57:05 +08:00
< span class = "pl-k" > return< / span > newHeader;
},
< span class = "pl-c" > //replace the response from the server before it's sent to the user< / span >
< span class = "pl-c" > //you may return either a Buffer or a string< / span >
< span class = "pl-c" > //serverResData is a Buffer, you may get its content by calling serverResData.toString()< / span >
2015-04-20 22:35:35 +08:00
< span class = "pl-en" > replaceServerResData< / span > : < span class = "pl-k" > function< / span > (< span class = "pl-smi" > req< / span > ,< span class = "pl-smi" > res< / span > ,< span class = "pl-smi" > serverResData< / span > ){
2014-11-26 11:57:05 +08:00
< span class = "pl-k" > return< / span > serverResData;
},
< span class = "pl-c" > //add a pause before sending response to user< / span >
2015-04-20 22:35:35 +08:00
< span class = "pl-en" > pauseBeforeSendingResponse< / span > : < span class = "pl-k" > function< / span > (< span class = "pl-smi" > req< / span > ,< span class = "pl-smi" > res< / span > ){
< span class = "pl-k" > var< / span > timeInMS < span class = "pl-k" > =< / span > < span class = "pl-c1" > 1< / span > ; < span class = "pl-c" > //delay all requests for 1ms< / span >
2014-11-26 11:57:05 +08:00
< span class = "pl-k" > return< / span > timeInMS;
},
< span class = "pl-c" > //should intercept https request, or it will be forwarded to real server< / span >
2015-04-20 22:35:35 +08:00
< span class = "pl-en" > shouldInterceptHttpsReq< / span > :< span class = "pl-k" > function< / span > (< span class = "pl-smi" > req< / span > ){
2014-11-26 11:57:05 +08:00
< span class = "pl-k" > return< / span > < span class = "pl-c1" > false< / span > ;
}
};
2014-09-03 19:41:27 +08:00
< / pre > < / div >
< h2 >
2014-11-26 11:57:05 +08:00
< a id = "using-https-features" class = "anchor" href = "#using-https-features" aria-hidden = "true" > < span class = "octicon octicon-link" > < / span > < / a > Using https features< / h2 >
2014-09-03 19:41:27 +08:00
< h4 >
2014-11-26 11:57:05 +08:00
< a id = "step-1---install-openssl" class = "anchor" href = "#step-1---install-openssl" aria-hidden = "true" > < span class = "octicon octicon-link" > < / span > < / a > step 1 - install openssl< / h4 >
2014-09-03 19:41:27 +08:00
< ul >
< li > install < a href = "http://wiki.openssl.org/index.php/Compilation_and_Installation" > openssl< / a > ,if you want to use HTTPS-related features. After that, the command < code > openssl< / code > should be exposed to your shell< / li >
2014-11-26 11:57:05 +08:00
< / ul >
< h4 >
< a id = "step-2---generate-a-rootca-and-trust-it" class = "anchor" href = "#step-2---generate-a-rootca-and-trust-it" aria-hidden = "true" > < span class = "octicon octicon-link" > < / span > < / a > step 2 - generate a rootCA and trust it< / h4 >
2014-09-03 19:41:27 +08:00
< ul >
< li > you should do this when it is the first time to start anyproxy< / li >
< li > execute < code > anyproxy --root< / code > ,follow the instructions on screen< / li >
< li > you will see some tip like < em > rootCA generated at : /usr/lib...< / em > . < code > cd< / code > to that directory, add/trust the rootCA.crt file to your system keychain. In OSX, you may do that by open the *crt file directly< / li >
2014-11-26 11:57:05 +08:00
< / ul >
< h4 >
< a id = "step-3---start-a-https-proxy" class = "anchor" href = "#step-3---start-a-https-proxy" aria-hidden = "true" > < span class = "octicon octicon-link" > < / span > < / a > step 3 - start a https proxy< / h4 >
2014-09-03 19:41:27 +08:00
< ul >
< li > < code > anyproxy --type https --host my.domain.com< / code > < / li >
< li > the param < code > host< / code > is required with https proxy and it should be kept exactly what it it when you config your browser. Otherwise, you may get some warning about security.< / li >
2014-11-26 11:57:05 +08:00
< / ul >
< h2 >
< a id = "others" class = "anchor" href = "#others" aria-hidden = "true" > < span class = "octicon octicon-link" > < / span > < / a > Others< / h2 >
2014-09-03 19:41:27 +08:00
< h4 >
2014-11-26 11:57:05 +08:00
< a id = "work-as-a-module" class = "anchor" href = "#work-as-a-module" aria-hidden = "true" > < span class = "octicon octicon-link" > < / span > < / a > work as a module< / h4 >
2014-09-03 19:41:27 +08:00
< pre > < code > npm install anyproxy --save
< / code > < / pre >
2015-04-20 22:35:35 +08:00
< div class = "highlight highlight-javascript" > < pre > < span class = "pl-k" > var< / span > proxy < span class = "pl-k" > =< / span > < span class = "pl-c1" > require< / span > (< span class = "pl-s" > < span class = "pl-pds" > "< / span > anyproxy< span class = "pl-pds" > "< / span > < / span > );
2014-09-03 19:41:27 +08:00
2014-11-26 11:57:05 +08:00
< span class = "pl-k" > !< / span > proxy.isRootCAFileExists() < span class = "pl-k" > & & < / span > proxy.generateRootCA(); < span class = "pl-c" > //please manually trust this rootCA< / span >
2015-04-20 22:35:35 +08:00
< span class = "pl-k" > new< / span > < span class = "pl-en" > proxy.proxyServer< / span > (< span class = "pl-s" > < span class = "pl-pds" > "< / span > http< span class = "pl-pds" > "< / span > < / span > ,< span class = "pl-s" > < span class = "pl-pds" > "< / span > 8001< span class = "pl-pds" > "< / span > < / span > , < span class = "pl-s" > < span class = "pl-pds" > "< / span > localhost< span class = "pl-pds" > "< / span > < / span > ,< span class = "pl-s" > < span class = "pl-pds" > "< / span > path/to/rule/file.js< span class = "pl-pds" > "< / span > < / span > );
2014-09-03 19:41:27 +08:00
< / pre > < / div >
< h4 >
2014-11-26 11:57:05 +08:00
< a id = "clear-all-the-temperary-certificates" class = "anchor" href = "#clear-all-the-temperary-certificates" aria-hidden = "true" > < span class = "octicon octicon-link" > < / span > < / a > clear all the temperary certificates< / h4 >
2014-09-03 19:41:27 +08:00
< p > < code > anyproxy --clear< / code > < / p >
< h2 >
2014-11-26 11:57:05 +08:00
< a id = "contact" class = "anchor" href = "#contact" aria-hidden = "true" > < span class = "octicon octicon-link" > < / span > < / a > Contact< / h2 >
2014-09-03 16:17:58 +08:00
2014-09-03 19:41:27 +08:00
< ul >
< li > Please feel free to raise any issue about this project, or give us some advice on this doc. :)< / li >
< / ul >
2014-09-03 16:17:58 +08:00
< / section >
2014-11-26 11:57:05 +08:00
< / div >
2014-11-26 22:31:01 +08:00
<!-- FOOTER -->
< div id = "footer_wrap" class = "outer" >
< footer class = "inner" >
< p class = "copyright" > Anyproxy maintained by < a href = "https://github.com/alibaba" > alibaba< / a > < / p >
2015-04-20 22:35:35 +08:00
< p > Published with < a href = "https://pages.github.com" > GitHub Pages< / a > < / p >
2014-11-26 22:31:01 +08:00
< / footer >
< / div >
2014-11-26 14:09:34 +08:00
< script type = "text/javascript" >
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
< / script >
< script type = "text/javascript" >
try {
var pageTracker = _gat._getTracker("UA-57129650-1");
pageTracker._trackPageview();
} catch(err) {}
< / script >
2014-11-26 22:31:01 +08:00
2014-09-03 16:17:58 +08:00
< / body >
2014-11-26 22:31:01 +08:00
< / html >