This commit is contained in:
zjcqoo 2019-07-23 20:37:25 +08:00
parent 5ca89b3e7b
commit 3391d1df8b
No known key found for this signature in database
GPG Key ID: 0867DB60BD24788F
6 changed files with 74 additions and 105 deletions

View File

@ -27,15 +27,18 @@ location = /preflight {
more_set_headers
'access-control-allow-origin: *'
'access-control-allow-methods: GET,POST,PUT,PATCH,TRACE,DELETE,HEAD,OPTIONS'
'access-control-allow-headers: --raw-info,--level,--url,--referer,--cookie,--origin,--ext,--aceh,--ver,--type,--mode,accept,accept-charset,accept-encoding,accept-language,accept-datetime,authorization,cache-control,content-length,content-type,date,if-match,if-modified-since,if-none-match,if-range,if-unmodified-since,max-forwards,pragma,range,te,upgrade,upgrade-insecure-requests,x-requested-with,chrome-proxy,purpose'
'access-control-max-age: 1728000'
;
return 204;
}
# 该接口已作废
location = /http {
rewrite ^ /error?msg=API_OBSOLETED;
}
# HTTP(S) Proxy
location = /http {
location /http/ {
# see ./allowed-sites.conf
if ($_origin_id = '') {
rewrite ^ /error?msg=ORIGIN_NOT_ALLOWED;
@ -47,7 +50,7 @@ location = /http {
proxy_set_header Connection $http_connection;
if ($http_access_control_request_headers) {
if ($http_access_control_request_methods) {
rewrite ^ /preflight;
}

View File

@ -0,0 +1,3 @@
listen 8443 ssl http2;
ssl_certificate cert/etherdream.com/ecc.cer;
ssl_certificate_key cert/etherdream.com/ecc.key;

View File

@ -23,29 +23,12 @@
如果不够用,可注册多个 Worker`conf.js` 中配置多线路负载均衡。或者升级到 $5 的高级版本,每月可用 1000 万次请求(超出部分 $0.5/百万次请求)。
如果远不够用,建议和服务器组合使用。因为 cfworker 是按请求次数计费的,所以小文件更适合通过服务器代理,大文件走 cfworker 才合算。可参考下面的 `加速功能`
# 修改配置
默认情况下,静态资源从 `https://zjcqoo.github.io` 反向代理,可通过代码中 `ASSET_URL` 配置,从而可使用自定义的 `conf.js` 配置。
# 加速功能
如果你已有服务器,也可通过 CloudFlare Worker 分担大文件的代理。
前端修改:`conf.js` 的 `cfworker` 节点 `lines` 配置。
后端修改:`lua/http-enc-res-hdr.lua` 的 [114-116 行](https://github.com/EtherDream/jsproxy/blob/master/lua/http-enc-res-hdr.lua#L114-L116) 注释打开,重启服务生效。
可在 [84行](https://github.com/EtherDream/jsproxy/blob/master/lua/http-enc-res-hdr.lua#L84) 处修改大于多少字节的静态资源走加速。
该功能目前还在实验中,有问题或者更好的思路可交流。
(推荐下行流量免费且不限速的服务器,可节省大量费用)
# 存在问题
* WebSocket 代理尚未实现

View File

@ -25,8 +25,6 @@ const PREFLIGHT_INIT = {
* @param {Object<string, string>} headers
*/
function makeRes(body, status = 200, headers = {}) {
headers['cache-control'] = 'no-cache'
headers['vary'] = '--url'
headers['--ver'] = JS_VER
headers['access-control-allow-origin'] = '*'
return new Response(body, {status, headers})
@ -47,6 +45,7 @@ async function fetchHandler(e) {
const req = e.request
const urlStr = req.url
const urlObj = new URL(urlStr)
const {pathname} = urlObj
if (urlObj.protocol === 'http:') {
urlObj.protocol = 'https:'
@ -56,16 +55,18 @@ async function fetchHandler(e) {
})
}
switch (urlObj.pathname) {
case '/http':
if (pathname.startsWith('/http')) {
return httpHandler(req)
}
switch (pathname) {
case '/ws':
return makeRes('not support', 400)
case '/works':
return makeRes('it works')
default:
// static files
return fetch(ASSET_URL + urlObj.pathname)
return fetch(ASSET_URL + pathname)
}
}
@ -86,8 +87,13 @@ function httpHandler(req) {
return new Response(null, PREFLIGHT_INIT)
}
let urlObj = null
let extHdrs = null
const urlStr = req.url.substr(6)
try {
var urlObj = new URL(urlStr)
} catch (err) {
return makeRes('invalid url: ' + urlStr, 403)
}
let acehOld = false
let rawSvr = ''
let rawLen = ''
@ -96,46 +102,34 @@ function httpHandler(req) {
const reqHdrNew = new Headers(reqHdrRaw)
reqHdrNew.set('x-jsproxy', '1')
for (const [k, v] of reqHdrRaw.entries()) {
if (!k.startsWith('--')) {
continue
}
reqHdrNew.delete(k)
// 此处逻辑和 http-dec-req-hdr.lua 大致相同
// https://github.com/EtherDream/jsproxy/blob/master/lua/http-dec-req-hdr.lua
const {sys, ext} = JSON.parse(reqHdrNew.get('accept'))
const k2 = k.substr(2)
switch (k2) {
case 'url':
urlObj = new URL(v)
break
// 系统信息
for (const [k, v] of Object.entries(sys)) {
switch (k) {
case 'aceh':
acehOld = true
break
case 'raw-info':
[rawSvr, rawLen, rawEtag] = v.split('|')
break
case 'level':
case 'mode':
case 'type':
break
case 'ext':
extHdrs = JSON.parse(v)
break
default:
if (v) {
reqHdrNew.set(k2, v)
} else {
reqHdrNew.delete(k2)
}
break
}
}
if (extHdrs) {
for (const [k, v] of Object.entries(extHdrs)) {
reqHdrNew.set(k, v)
// 原始 HTTP 字段
let hasRawAccept = false
for (const [k, v] of Object.entries(ext)) {
if (k === 'accept') {
hasRawAccept = true
}
reqHdrNew.set(k, v)
}
if (!urlObj) {
return makeRes('missing url param', 403)
if (!hasRawAccept) {
reqHdrNew.delete('accept')
}
/** @type {RequestInit} */
@ -163,7 +157,6 @@ async function proxy(urlObj, reqInit, acehOld, rawLen, retryTimes) {
const resHdrNew = new Headers(resHdrOld)
let expose = '*'
let vary = '--url'
for (const [k, v] of resHdrOld.entries()) {
if (k === 'access-control-allow-origin' ||
@ -178,9 +171,6 @@ async function proxy(urlObj, reqInit, acehOld, rawLen, retryTimes) {
}
resHdrNew.delete(k)
}
else if (k === 'vary') {
vary = vary + ',' + v
}
else if (acehOld &&
k !== 'cache-control' &&
k !== 'content-language' &&
@ -225,7 +215,6 @@ async function proxy(urlObj, reqInit, acehOld, rawLen, retryTimes) {
resHdrNew.set('access-control-expose-headers', expose)
resHdrNew.set('access-control-allow-origin', '*')
resHdrNew.set('vary', vary)
resHdrNew.set('--s', status)
resHdrNew.set('--ver', JS_VER)

View File

@ -1,20 +1,18 @@
-- 功能:还原 HTTP 请求头
-- 阶段access_by_lua
-- 还原 HTTP 请求头
-- 前端只保留简单字段(防止出现 preflight
-- 其余字段及系统信息,存储在 Accept 字段里JSON 格式)。
local cjson = require('cjson')
local hdrs, err = ngx.req.get_headers()
local extHdrs
ngx.log(ngx.ALERT, 'accept:' .. hdrs['accept'])
local info = ngx.unescape_uri(hdrs['accept'])
local json = cjson.decode(info)
for k, v in pairs(hdrs) do
if k:sub(1, 2) ~= '--' then
goto continue
end
-- 系统信息
local sys = json['sys']
ngx.req.clear_header(k)
k = k:sub(3)
if k == 'url' then
ngx.var._url = v
elseif k == 'ver' then
for k, v in pairs(sys) do
if k == 'ver' then
ngx.var._ver = v
elseif k == 'type' then
ngx.var._type = v
@ -25,20 +23,25 @@ for k, v in pairs(hdrs) do
elseif k == 'level' then
ngx.var._level = v
ngx.ctx._level = tonumber(v)
elseif k == 'ext' then
extHdrs = require('cjson').decode(v)
else
if k == 'referer' then
ngx.var._ref = v
end
ngx.req.set_header(k, v)
end
::continue::
end
if extHdrs then
for k, v in pairs(extHdrs) do
ngx.req.set_header(k, v)
-- 原始 HTTP 字段
local ext = json['ext']
local hasRawAccept = false
for k, v in pairs(ext) do
if k == 'accept' then
hasRawAccept = true
elseif k == 'referer' then
ngx.var._ref = v
end
end
ngx.req.set_header(k, v)
end
if not hasRawAccept then
ngx.req.clear_header('accept')
end
-- 删除 URL 的 '/http/' 前缀
ngx.var._url = ngx.var.request_uri:sub(7)

View File

@ -9,9 +9,6 @@ local expose = '*'
-- 该值为 true 表示浏览器不支持 aceh: *,需返回详细的头部列表
local detail = ngx.ctx._acehOld
-- 由于接口路径固定,为避免被缓存,以请求头的 --url 值区分缓存
local vary = '--url'
local function addHdr(k, v)
ngx.header[k] = v
@ -32,7 +29,6 @@ local function flushHdr()
ngx.header['access-control-expose-headers'] = expose
ngx.header['access-control-allow-origin'] = '*'
ngx.header['vary'] = vary
local status = ngx.status
@ -57,15 +53,6 @@ local function flushHdr()
end
local function addVary(v)
if type(v) == 'table' then
vary = vary .. ',' .. table.concat(v, ',')
else
vary = vary .. ',' .. v
end
end
local function nodeSwitched()
local status = ngx.status
if status ~= 200 and status ~= 206 then
@ -113,7 +100,6 @@ local function nodeSwitched()
addHdr('--switched', '1')
ngx.header['cache-control'] = 'no-cache'
ngx.header['vary'] = '--url'
ngx.var._switched = resLenStr
ngx.ctx._switched = true
@ -147,9 +133,6 @@ for k, v in pairs(h) do
end
ngx.header[k] = nil
elseif k == 'vary' then
addVary(v)
elseif detail and
-- 非简单头无法被 fetch 读取,需添加到 aceh 列表 --
-- https://developer.mozilla.org/en-US/docs/Glossary/Simple_response_header
@ -164,4 +147,9 @@ for k, v in pairs(h) do
end
end
flushHdr()
-- 不缓存非 GET 请求
if ngx.req.get_method() ~= 'GET' then
ngx.header['cache-control'] = 'no-cache'
end
flushHdr()