Skip to content

Commit

Permalink
README.md udpates
Browse files Browse the repository at this point in the history
  • Loading branch information
netptop committed Feb 15, 2020
1 parent d19b4b9 commit edeaa90
Show file tree
Hide file tree
Showing 10 changed files with 602 additions and 0 deletions.
8 changes: 8 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
indent_style: 'space',
indent_size: 2,
charset: 'utf-8',
trim_trailing_whitespace: true,
insert_final_newline: true,
tab_width: 2
}
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
node_modules
dist
src/renderer/pages/.umi
src/renderer/pages/.umi-production
release
yarn-error.log
yarn.lock
.history
.vscode
.umirc.local.js
.now
234 changes: 234 additions & 0 deletions Proxy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
var express = require('express');
var proxy = require('http-proxy-middleware');
const https = require('https')
const zlib = require("zlib")
const cookiejar = require('cookiejar')
const iconv = require('iconv-lite')
const {CookieAccessInfo, CookieJar, Cookie} = cookiejar

function countUtf8Bytes(s) {
var b = 0, i = 0, c
for(;c=s.charCodeAt(i++);b+=c>>11?3:c>>7?2:1);
return b
}

var enableCors = function(req, res) {
if (req.headers['access-control-request-method']) {
res.setHeader('access-control-allow-methods', req.headers['access-control-request-method']);
}

if (req.headers['access-control-request-headers']) {
res.setHeader('access-control-allow-headers', req.headers['access-control-request-headers']);
}

if (req.headers.origin) {
res.setHeader('access-control-allow-origin', req.headers.origin);
res.setHeader('access-control-allow-credentials', 'true');
}
};

// only support https for now.
let router = (req) => { //return target
let {host, httpType} = getHostFromReq(req)
let target = `${httpType}://${host}`
console.log(`router, target:${target}, req.url:${req.url}`)
return target
}

let getHostFromReq = (req) => { //return target
// url: http://127.0.0.1:8011/https/www.youtube.com/xxx/xxx/...
let https_prefix = '/https/'
let http_prefix = '/http/'
let host = ''
let httpType = 'https'
if (req.url.startsWith(https_prefix)) {
host = req.url.slice(https_prefix.length, req.url.length)
if (host.indexOf('/') !== -1) {
host = host.slice(0, host.indexOf('/'))
}
} else if (req.url.startsWith(http_prefix)) {
host = req.url.slice(http_prefix.length, req.url.length)
if (host.indexOf('/') !== -1) {
host = host.slice(0, host.indexOf('/'))
}
httpType = 'http'
} else if (req.headers['referer'] && req.headers['referer'].indexOf('https/') !== -1) {
let start = req.headers['referer'].indexOf('https/') + 6
host = req.headers['referer'].slice(start, req.headers['referer'].length)
let end = host.indexOf('/')
if (end === -1) {
end = host.length
}
host = host.slice(0, end)
console.log(`============= host:${host}, req referer:${req.headers['referer']}`)
} else if (req.headers['referer'] && req.headers['referer'].indexOf('http/') !== -1) {
let start = req.headers['referer'].indexOf('http/') + 5
host = req.headers['referer'].slice(start, req.headers['referer'].length)
let end = host.indexOf('/')
if (end === -1) {
end = host.length
}
host = host.slice(0, end)
httpType = 'http'
console.log(`============= host:${host}, req referer:${req.headers['referer']}`)
}
console.log(`getHostFromReq, req.url:${req.url}, referer:${req.headers['referer']}`)
return {host, httpType}
}


let Proxy = ({cookieDomainRewrite, locationReplaceMap302, regReplaceMap, siteSpecificReplace, pathReplace}) => {
let handleRespond = ({req, res, body, gbFlag}) => {
// console.log("res from proxied server:", body);
/*
var myRe = new RegExp(`https://`, 'g') // support maximum 300 characters for web site name, like: www.google.com
body = body.replace(myRe, `http://127.0.0.1:${port}/https/`)
myRe = new RegExp(`https%3A%2F%2F`, 'g')
body = body.replace(myRe, `https%3A%2F%2Fproxy.goincop1.workers.dev%3A443%2Fhttps%2F127.0.0.1%3A${port}%2F`)
*/
let myRe
let {host, httpType} = getHostFromReq(req)
let location = res.getHeaders()['location']
if (res.statusCode == '302' || res.statusCode == '301') {
for(key in locationReplaceMap302) {
myRe = new RegExp(key, 'g') // match group
location = location.replace(myRe, locationReplaceMap302[key])
}
res.setHeader('location', location)
}
// console.log(`HandleRespond(), req.url:${req.url}, req.headers:${JSON.stringify(req.headers)}`)
for(key in regReplaceMap) {
myRe = new RegExp(key, 'g') // match group
body = body.replace(myRe, regReplaceMap[key])
}
Object.keys(siteSpecificReplace).forEach( (site) => {
if (req.url.indexOf(site) !== -1 || req.headers['referer'].indexOf(site) !== -1) {
keys = Object.keys(siteSpecificReplace[site])
keys.forEach( key => {
myRe = new RegExp(key, 'g') // match group
body = body.replace(myRe, siteSpecificReplace[site][key])
})
}
})
if (host) {
body = pathReplace({host, httpType, body})
}

if (gbFlag) {
body = iconv.encode(body, 'gbk')
}
body = zlib.gzipSync(body)
res.setHeader('content-encoding', 'gzip');
console.log(`handleRespond: res.headers:${JSON.stringify(res.getHeaders())}`)
res.end(body);
}
let p = proxy({
target: `https://www.google.com`,
router,
/*
pathRewrite: (path, req) => {
let {host, httpType} = getHostFromReq(req)
let newpath = path.replace(`/https/${host}`, '') || '/'
console.log(`newpath:${newpath}`)
return newpath
},
*/
hostRewrite: true,
// autoRewrite: true,
protocolRewrite: true,
// followRedirects: true,
cookieDomainRewrite,
secure: false,
changeOrigin: true,
debug:true,
onError: (err, req, res) => {
console.log(`onerror: ${err}`)
},
selfHandleResponse: true, // so that the onProxyRes takes care of sending the response
onProxyRes: (proxyRes, req, res) => {
let {host, httpType} = getHostFromReq(req)
console.log(`proxyRes.status:${proxyRes.statusCode} proxyRes.headers:${JSON.stringify(proxyRes.headers)}`)
var body = Buffer.from('');
proxyRes.on('data', function(data) {
body = Buffer.concat([body, data]);
})
proxyRes.on('end', function() {
let gbFlag = false
if (proxyRes.headers["content-encoding"] === 'gzip') {
zlib.gunzip(body,function(er,gunzipped){
console.log(`zlib.gunzip...`)
if (proxyRes.headers["content-type"].indexOf('text/') !== -1) {
if (!gunzipped) {
res.status(404).send()
return
}
console.log(`utf-8 text...`)
body = gunzipped.toString('utf-8');
if (body.indexOf('content="text/html; charset=gb2312') !== -1) {
body = iconv.decode(gunzipped, 'gbk')
gbFlag = true
}
handleRespond({req, res, body, gbFlag})
} else {
res.end(body)
}
});
} else if (proxyRes.headers["content-type"] && proxyRes.headers["content-type"].indexOf('text/') !== -1) {
console.log(`utf-8 text...`)
body = body.toString('utf-8');
handleRespond({req, res, body, gbFlag})
} else {
res.end(body)
}
})
const setCookieHeaders = proxyRes.headers['set-cookie'] || []
const modifiedSetCookieHeaders = setCookieHeaders
.map(str => new cookiejar.Cookie(str))
.map(cookie => {
console.log(`cookie:${JSON.stringify(cookie)}`)
if (cookie.path && cookie.path[0] === '/') {
cookie.domain = `127.0.0.1`
cookie.path = `${req.url}`
}
cookie.secure = false
return cookie
})
.map(cookie => cookie.toString())
proxyRes.headers['set-cookie'] = modifiedSetCookieHeaders
Object.keys(proxyRes.headers).forEach(function (key) {
if (key === 'content-encoding' ||
(key === 'content-length' && proxyRes.headers["content-type"] && proxyRes.headers["content-type"].indexOf('text/') !== -1)) {
console.log(`skip header:${key}`)
return
}
// res.append(key, proxyRes.headers[key]);
res.setHeader(key, proxyRes.headers[key]);
});
res.statusCode = proxyRes.statusCode
console.log(`res.status:${res.statusCode} res.url:${res.url}, res.headers:${JSON.stringify(res.getHeaders())}`)
},
onProxyReq: (proxyReq, req, res) => {
let {host, httpType} = getHostFromReq(req)
req.headers['host'] = host
req.headers['referer'] = host
let newpath = req.url.replace(`/${httpType}/${host}`, '') || '/'
console.log(`httpType:${httpType}, host:${host}, req.url:${req.url}, req.headers:${JSON.stringify(req.headers)}`)
Object.keys(req.headers).forEach(function (key) {
proxyReq.setHeader(key, req.headers[key]);
});
proxyReq.setHeader('Accept-Encoding', 'gzip')
proxyReq.setHeader('referer', host)
proxyReq.path = newpath
console.log(`req host:${host}, req.url:${req.url}, proxyReq.path:${proxyReq.path}, proxyReq.url:${proxyReq.url} proxyReq headers:${JSON.stringify(proxyReq.getHeaders())}`)
if(host === '' || !host) {
console.log(`------------------ sending status 404`)
res.status(404).send()
res.end()
}

},
})
return p
}

module.exports = Proxy
55 changes: 55 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# siteproxy
pure web page proxy, zero configuration from client side. Reverse proxy to all internet. 一键部署,翻墙利器。

```
+----> google
+----------------+ |
| | |
user browser +-------------->+ siteproxy +-------> wikipedia
| | |
+----------------+ |
+----> chinese forums
```

## features
- enter siteproxy's address, and go surf on internet without censorship.
- no proxy setting from client side is needed. zero configuration from client browser.
- easy deployment to now.sh

## Mechanism
```
1. user browser url: https://siteproxy.now.sh/https/www.google.com
2. siteproxy.now.sh received the url and request www.google.com, and get response from www.google.com
3. siteproxy replace all returned strings in javascript/html:
https://www.google.com => https://siteproxy.now.sh/https/www.google.com
url(/https/github.com/xxx) => url(/https/github.com/https/www.google.com/xxx)
https://xxx => https://siteproxy.now.sh/https/xxx
etc.
4. send back the modified html/javascript to user browser.
```

## supported websites
```
1. www.google.com, and search action
2. zh.wikipedia.org, and search action
3. other websites.
```

## installation/deployment
```
1. register one now.sh account from https://zeit.co/home
2. npm install -g now
3. git clone https://github.com/netptop/siteproxy.git
4. cd siteproxy
5. now
6. find your domain name from now cli, then replace serverName in 'index.js', like:
serverName: 'siteproxy.now.sh' ====> 'your-domain-name.now.sh'
7. now --prod
8. done
```

## issues
- 部分网站加载有问题;
- 暂时无法看视频网站;
- twitter访问有问题;
- recaptcha验证码有问题;
Binary file added bg-gr-v.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 34 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<meta charset="utf-8"/>
<link rel="stylesheet" href="/style.css"/>
<header class="header-banner">
<kiv class="container-width">
<div class="logo-container">
<div class="logo">
siteproxy
</div>
</div>
<br />
<div class="lead-title"> 从这里开始,不再被训戒. 建议您从浏览器打开网页,避免被微信窃听!
</div>
<form class="lead-title" action=>
<input class="lead-title" type="button" onclick="window.location.href='/https/www.google.com'" value="Google"/>
<input class="lead-title" type="button" onclick="window.location.href='/https/zh.wikipedia.org'" value="维基百科"/>
<input class="lead-title" type="button" onclick="window.location.href='/https/www.wenxuecity.com'" value="文学城"/>
<input class="lead-title" type="button" onclick="window.location.href='/https/www.bbc.com/zhongwen/simp'" value="BBC新闻"/>
<input class="lead-title" type="button" onclick="window.location.href='/https/cn.nytimes.com'" value="纽约时报"/>
</form>

</kiv>
<div class="container-width">
<div class="logo-container">
</div>
<div class="c9130">
<br/>
<br/>
<div class="clearfix">
</div>
<br/>
<br/>
</div>
</div>
</header>
Loading

0 comments on commit edeaa90

Please sign in to comment.