Sfoglia il codice sorgente

增加 cfworker 无服务器版

zjcqoo 6 anni fa
parent
commit
c39c3498b1
3 ha cambiato i file con 110 aggiunte e 23 eliminazioni
  1. 2 0
      README.md
  2. 59 1
      cf-worker/README.md
  3. 49 22
      cf-worker/index.js

+ 2 - 0
README.md

@@ -1,6 +1,8 @@
 
 # 更新
 
+* 2019-06-22 [cfworker 无服务器版](cf-worker)发布,长期使用演示服务的请使用该版本。
+
 * 2019-06-11 前端脚本调整,首页可离线访问(如果长时间加载中,尝试多刷新几次或者隐身模式访问)
 
 * 2019-05-30 更新 cfworker,对 ytb 视频进行了优化(推荐选 1080p+,不会增加服务器压力)

+ 59 - 1
cf-worker/README.md

@@ -1 +1,59 @@
-https://cloudflareworkers.com/
+使用 CloudFlare Worker 免费部署
+
+
+# 简介
+
+`CloudFlare Worker` 是 CloudFlare 的边缘计算服务。开发者可通过 JavaScript 对 CDN 进行编程,从而能灵活处理 HTTP 请求。这使得很多任务可在 CDN 上完成,无需自己的服务器参与。
+
+
+# 部署
+
+首页:https://workers.cloudflare.com
+
+注册,登陆,`Start building`,取一个子域名,`Create a Worker`。
+
+复制 [index.js](index.js) 到左侧代码框,`Save and deploy`。如果正常,右侧应显示首页。
+
+线路切换到 `当前站点` 即可使用。(选择演示服务的节点会报错,因为该域名不在我的外链白名单里)
+
+收藏地址框中的 `https://xxxx.子域名.workers.dev`,以后可直接访问。
+
+
+# 计费
+
+后退到 `overview` 页面可参看使用情况。免费版每天有 10 万次免费请求,对于个人通常足够。
+
+如果不够用,可注册多个 Worker,在 `conf.js` 中配置多线路负载均衡。或者升级到 $5 的高级版本,每月可用 1000 万次请求(超出部分 $0.5/百万次请求)。
+
+如果远不够用,建议和服务器组合使用。因为 cfworker 是按请求次数计费的,所以小文件更适合通过服务器代理,大文件走 cfworker 才合算。可参考下面的 `加速功能`。
+
+
+# 修改配置
+
+默认情况下,静态资源从 `https://zjcqoo.github.io` 反向代理,可通过代码中 `ASSET_URL` 配置。
+
+推荐将 `conf.js` 文件的 `node_default` 改为 `mysite`,这样能自动选择 `当前站点` 这个节点,不用每次手动选节点。
+
+
+# 加速功能
+
+如果你已有服务器,也可通过 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 代理尚未实现
+
+* 外链限制尚未实现
+
+* 未充分测试,以后再完善

+ 49 - 22
cf-worker/index.js

@@ -1,10 +1,13 @@
+'use strict'
+
 /**
- * jsproxy cfworker api
- * https://github.com/EtherDream/jsproxy/
+ * static files (404.html, sw.js, conf.js)
  */
-'use strict'
+const ASSET_URL = 'https://zjcqoo.github.io'
+
+const JS_VER = 5
+const MAX_RETRY = 1
 
-const JS_VER = 4
 
 const PREFLIGHT_INIT = {
   status: 204,
@@ -16,9 +19,30 @@ const PREFLIGHT_INIT = {
   }),
 }
 
+/**
+ * @param {string} message
+ */
+function makeErrRes(message) {
+  return new Response(message, {
+    status: 400,
+    headers: {
+      'cache-control': 'no-cache'
+    }
+  })
+}
+
 
 addEventListener('fetch', e => {
-  const ret = handler(e.request)
+  const req = e.request
+  const urlStr = req.url
+  const urlObj = new URL(urlStr)
+  let ret
+  if (urlObj.pathname !== '/http') {
+    // static files
+    ret = fetch(ASSET_URL + urlObj.pathname)
+  } else {
+    ret = handler(req)
+  }
   e.respondWith(ret)
 })
 
@@ -87,6 +111,9 @@ async function handler(req) {
       reqHdrNew.set(k, v)
     }
   }
+  if (!urlObj) {
+    return makeErrRes('missing url param')
+  }
   const reqInit = {
     method: req.method,
     headers: reqHdrNew,
@@ -148,29 +175,29 @@ async function proxy(urlObj, reqInit, acehOld, rawLen, retryTimes) {
   resHdrNew.set('--s', res.status)
 
   // verify
-  const newLen = resHdrOld.get('content-length') || ''
-  const badLen = (rawLen !== newLen)
-
-  let status = 200
-  let body = res.body
-
-  if (badLen) {
-    if (retryTimes < 1) {
-      urlObj = await parseYtVideoRedir(urlObj, newLen, res)
-      if (urlObj) {
-        return proxy(urlObj, reqInit, acehOld, rawLen, retryTimes + 1)
+  if (rawLen) {
+    const newLen = resHdrOld.get('content-length') || ''
+    const badLen = (rawLen !== newLen)
+
+    if (badLen) {
+      if (retryTimes < MAX_RETRY) {
+        urlObj = await parseYtVideoRedir(urlObj, newLen, res)
+        if (urlObj) {
+          return proxy(urlObj, reqInit, acehOld, rawLen, retryTimes + 1)
+        }
       }
+      return makeErrRes(`bad len (old: ${rawLen} new: ${newLen})`)
+    }
+
+    if (retryTimes > 1) {
+      resHdrNew.set('--retry', retryTimes)
     }
-    status = 400
-    body = `bad len (old: ${rawLen} new: ${newLen})`
-    resHdrNew.set('cache-control', 'no-cache')
   }
 
-  resHdrNew.set('--retry', retryTimes)
   resHdrNew.set('--ver', JS_VER)
 
-  return new Response(body, {
-    status,
+  return new Response(res.body, {
+    status: 200,
     headers: resHdrNew,
   })
 }