mirror of
https://github.com/alibaba/anyproxy.git
synced 2025-06-05 16:58:22 +00:00
add support for CROS
This commit is contained in:
parent
f0832f37dc
commit
3a4955e92c
54
README.md
54
README.md
@ -1,7 +1,18 @@
|
||||
anyproxy
|
||||
==========
|
||||
|
||||
## Intro
|
||||
Feature
|
||||
------------
|
||||
* work as http or https proxy
|
||||
* generate and intercept https requests for any domain without complaint by browser (after you trust its root CA)
|
||||
* support CROS-related http header, you could use make cross-domain requests via this proxy
|
||||
* can be used globally or as a nodejs module
|
||||
|
||||
|
||||
Why we write another proxy
|
||||
------------
|
||||
|
||||
### To perfectly support https proxy
|
||||
While there are lots of proxy written by nodejs in github, most of them can not handle users' HTTPS requests perfectly. A typical problem is that the browser will throw warning like INVALID_CERTIFICATE when they want to intercept some https requests.
|
||||
|
||||
A simple and fast solution is to short the traffic between the user and the target server. That is to say, what the proxy do is to forward all the traffic of both sides, without intercepting or looking inside.
|
||||
@ -13,40 +24,41 @@ In order to have a browser-trusted certificate, we would sign certificates dynam
|
||||
|
||||
What this proxy do is to generate and replace a temporary cert for any domain if neccessary. Using it, we can intercept any requests for debug. BTW, this is also what the charlse/fiddler do when you check the enable_ssl_proxy in preference.
|
||||
|
||||
## Feature
|
||||
* work as http or https proxy
|
||||
* generate and intercept https requests for any domain without complaint by browser (after you trust its root CA)
|
||||
* can be used globally or as a nodejs module
|
||||
### To support cross-domain requests
|
||||
By properly responding HTTP OPTIONS request and Access-Control-Allow-* headers on server side, we can perform cross-domain requests in modern browsers. Anyproxy will automatically handle these things for you, no matter the remote server supports or not. This can be extremely useful for those who often debug webpages embedded in a special browser.
|
||||
|
||||
## Usage
|
||||
Usage
|
||||
--------------
|
||||
### step 0 - setup env
|
||||
|
||||
* install NodeJS
|
||||
* install [openssl](http://wiki.openssl.org/index.php/Compilation_and_Installation) , i.e. the command ``openssl`` should be exposed to your shell
|
||||
* install [NodeJS](http://nodejs.org/)
|
||||
* install [openssl](http://wiki.openssl.org/index.php/Compilation_and_Installation) ,if you want to use HTTPS-related features. After that, the command ``openssl`` should be exposed to your shell
|
||||
|
||||
### step 1 - install
|
||||
|
||||
* ``npm install -g anyproxy`` , may need ``sudo``
|
||||
* ``npm install -g anyproxy`` , may require ``sudo``
|
||||
|
||||
### step 2 - start server
|
||||
|
||||
* start with default settings : ``anyproxy``
|
||||
* start with a specific port: ``anyproxy --port 8001``
|
||||
|
||||
|
||||
### step 2 - generate a rootCA and trust it
|
||||
|
||||
Using https features
|
||||
----------------
|
||||
### generate a rootCA and trust it
|
||||
* you should do this when it is the first time to start anyproxy
|
||||
* execute ``anyproxy --root`` ,follow the instructions on screen
|
||||
* you will see some tip like *rootCA generated at : /usr/lib...* , just cd to that position, add the rootCA.crt file to your system keychain and trust. In OSX, you may do that by open the *crt file directly
|
||||
* you will see some tip like *rootCA generated at : /usr/lib...* . ``cd`` 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
|
||||
|
||||
### step 3 - start server
|
||||
|
||||
#### start with default settings
|
||||
* ``anyproxy``
|
||||
|
||||
#### start with a specific port
|
||||
* ``anyproxy --port 8001``
|
||||
|
||||
#### start a https proxy
|
||||
### start a https proxy
|
||||
* ``anyproxy --type https --host my.domain.com``
|
||||
* the param ``host`` 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.
|
||||
|
||||
### others
|
||||
|
||||
others
|
||||
-----------------
|
||||
#### work as a module
|
||||
```
|
||||
npm install anyproxy
|
||||
|
@ -27,7 +27,8 @@ var handleRule = {
|
||||
|
||||
function userRequestHandler(req,userRes){
|
||||
var host = req.headers.host,
|
||||
path = url.parse(req.url).pathname,
|
||||
urlPattern = url.parse(req.url),
|
||||
path = urlPattern.path,
|
||||
ifLocalruleMatched = false;
|
||||
|
||||
console.log(color.green("\nreceived request to : " + host + path));
|
||||
@ -37,6 +38,13 @@ function userRequestHandler(req,userRes){
|
||||
in https server : /work/alibaba
|
||||
*/
|
||||
|
||||
if(req.method == "OPTIONS"){
|
||||
console.log("==>OPTIONS req for CROS, will allow all");
|
||||
userRes.writeHead(200,mergeCROSHeader(req.headers)); //remove any cache related header, add crossdomain headers
|
||||
userRes.end();
|
||||
return;
|
||||
}
|
||||
|
||||
for(var index in handleRule.map){
|
||||
var rule = handleRule.map[index];
|
||||
|
||||
@ -58,7 +66,6 @@ function userRequestHandler(req,userRes){
|
||||
if(fs.existsSync(targetLocalfile)){
|
||||
try{
|
||||
var fsStream = fs.createReadStream(targetLocalfile);
|
||||
userRes.writeHead(200,{"cache-control":"max-age=0"}); //remove any cache related header
|
||||
fsStream.pipe(userRes);
|
||||
ifLocalruleMatched = true;
|
||||
break;
|
||||
@ -79,24 +86,24 @@ function userRequestHandler(req,userRes){
|
||||
var ifHttps = !!req.connection.encrypted && !/http:/.test(req.url);
|
||||
|
||||
var options = {
|
||||
hostname : req.headers.host,
|
||||
port : req.port || (ifHttps ? 443 : 80),
|
||||
hostname : urlPattern.hostname || req.headers.host,
|
||||
port : urlPattern.port || req.port || (ifHttps ? 443 : 80),
|
||||
path : path,
|
||||
method : req.method,
|
||||
headers : req.headers
|
||||
};
|
||||
|
||||
var proxyReq = (ifHttps ? https : http).request(options, function(res) {
|
||||
userRes.writeHead(res.statusCode,res.headers);
|
||||
userRes.writeHead(res.statusCode,mergeCROSHeader(req.headers,res.headers));
|
||||
res.pipe(userRes);
|
||||
});
|
||||
|
||||
proxyReq.on("error",function(e){
|
||||
console.log("err with request :" + req.url);
|
||||
console.log("err with request :" + e.code + " " + req.url);
|
||||
userRes.end();
|
||||
});
|
||||
proxyReq.end();
|
||||
|
||||
|
||||
req.pipe(proxyReq);
|
||||
}
|
||||
}
|
||||
|
||||
@ -147,7 +154,6 @@ function connectReqHandler(req, socket, head){
|
||||
socket.write('HTTP/' + req.httpVersion + ' 200 OK\r\n\r\n', 'UTF-8', function() {
|
||||
conn.pipe(socket);
|
||||
socket.pipe(conn);
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
@ -177,6 +183,18 @@ function setRules(newRule){
|
||||
}
|
||||
}
|
||||
|
||||
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
|
||||
function mergeCROSHeader(reqHeader,originHeader){
|
||||
var targetObj = originHeader || {};
|
||||
|
||||
targetObj["Access-Control-Allow-Credentials"] = "true";
|
||||
targetObj["Access-Control-Allow-Origin"] = reqHeader['origin'] || "-___-||";
|
||||
targetObj["Access-Control-Allow-Methods"] = "GET, POST, PUT";
|
||||
targetObj["Access-Control-Allow-Headers"] = reqHeader['access-control-request-headers'] || "-___-||";
|
||||
|
||||
return targetObj;
|
||||
}
|
||||
|
||||
module.exports.userRequestHandler = userRequestHandler;
|
||||
module.exports.connectReqHandler = connectReqHandler;
|
||||
module.exports.setRules = setRules;
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "anyproxy",
|
||||
"version": "1.1.2",
|
||||
"description": "a charles/fiddle like web proxy for developers which can intercept https requests without browser warning",
|
||||
"version": "1.2.0",
|
||||
"description": "another proxy written in NODEJS, which can handle HTTPS requests and CROS perfectly",
|
||||
"main": "proxy.js",
|
||||
"bin": {
|
||||
"anyproxy": "bin.js"
|
||||
|
18
postReceiver.js
Normal file
18
postReceiver.js
Normal file
@ -0,0 +1,18 @@
|
||||
var http= require("http");
|
||||
|
||||
var s = http.createServer(function(req,res) {
|
||||
var total = "";
|
||||
req.on("data",function(chunk){
|
||||
total += chunk;
|
||||
});
|
||||
|
||||
req.on("end",function(){
|
||||
console.log(total);
|
||||
});
|
||||
|
||||
console.log(req);
|
||||
// body...
|
||||
});
|
||||
|
||||
s.listen(80);
|
||||
|
28
testPost.js
Normal file
28
testPost.js
Normal file
@ -0,0 +1,28 @@
|
||||
// We need this to build our post string
|
||||
var http = require('http');
|
||||
var fs = require('fs');
|
||||
|
||||
|
||||
|
||||
// An object of options to indicate where to post to
|
||||
var post_options = {
|
||||
host: 'localhost',
|
||||
port: '8004',
|
||||
path: '/',
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Host: "127.0.0.1"
|
||||
}
|
||||
};
|
||||
|
||||
// Set up the request
|
||||
var post_req = http.request(post_options, function(res) {
|
||||
res.setEncoding('utf8');
|
||||
res.on('data', function (chunk) {
|
||||
console.log('Response: ' + chunk);
|
||||
});
|
||||
});
|
||||
|
||||
// post the data
|
||||
post_req.write("hello world hello world hello world hello world hello world ");
|
||||
post_req.end();
|
Loading…
x
Reference in New Issue
Block a user