cfworker自建dockerhub镜像加速服务

隔壁已经有cfworker自建dockerhub镜像加速服务了
代码我贴这里,帮我顶上去。
用法:
原镜像

docker pull whyour/qinglong:latest

加速镜像

docker pull 你的域名/whyour/qinglong:latest

我的加速域名为:do.nark.eu.org

'use strict'

const hub_host = 'registry-1.docker.io'

const auth_url = 'https://auth.docker.io'

const workers_url = 'https://你的域名'

/**

 * static files (404.html, sw.js, conf.js)

 */

/** @type {RequestInit} */

const PREFLIGHT_INIT = {

    status: 204,

    headers: new Headers({

        'access-control-allow-origin': '*',

        'access-control-allow-methods': 'GET,POST,PUT,PATCH,TRACE,DELETE,HEAD,OPTIONS',

        'access-control-max-age': '1728000',

    }),

}

/**

 * @param {any} body

 * @param {number} status

 * @param {Object<string, string>} headers

 */

function makeRes(body, status = 200, headers = {}) {

    headers['access-control-allow-origin'] = '*'

    return new Response(body, {status, headers})

}

/**

 * @param {string} urlStr

 */

function newUrl(urlStr) {

    try {

        return new URL(urlStr)

    } catch (err) {

        return null

    }

}

addEventListener('fetch', e => {

    const ret = fetchHandler(e)

        .catch(err => makeRes('cfworker error:\n' + err.stack, 502))

    e.respondWith(ret)

})

/**

 * @param {FetchEvent} e

 */

async function fetchHandler(e) {

  const getReqHeader = (key) => e.request.headers.get(key);

  let url = new URL(e.request.url);

  if (url.pathname === '/token') {

      let token_parameter = {

        headers: {

        'Host': 'auth.docker.io',

        'User-Agent': getReqHeader("User-Agent"),

        'Accept': getReqHeader("Accept"),

        'Accept-Language': getReqHeader("Accept-Language"),

        'Accept-Encoding': getReqHeader("Accept-Encoding"),

        'Connection': 'keep-alive',

        'Cache-Control': 'max-age=0'

        }

      };

      let token_url = auth_url + url.pathname + url.search

      return fetch(new Request(token_url, e.request), token_parameter)

  }

  url.hostname = hub_host;

  

  let parameter = {

    headers: {

      'Host': hub_host,

      'User-Agent': getReqHeader("User-Agent"),

      'Accept': getReqHeader("Accept"),

      'Accept-Language': getReqHeader("Accept-Language"),

      'Accept-Encoding': getReqHeader("Accept-Encoding"),

      'Connection': 'keep-alive',

      'Cache-Control': 'max-age=0'

    },

    cacheTtl: 3600

  };

  if (e.request.headers.has("Authorization")) {

    parameter.headers.Authorization = getReqHeader("Authorization");

  }

  let original_response = await fetch(new Request(url, e.request), parameter)

  let original_response_clone = original_response.clone();

  let original_text = original_response_clone.body;

  let response_headers = original_response.headers;

  let new_response_headers = new Headers(response_headers);

  let status = original_response.status;

  if (new_response_headers.get("Www-Authenticate")) {

    let auth = new_response_headers.get("Www-Authenticate");

    let re = new RegExp(auth_url, 'g');

    new_response_headers.set("Www-Authenticate", response_headers.get("Www-Authenticate").replace(re, workers_url));

  }

  if (new_response_headers.get("Location")) {

    return httpHandler(e.request, new_response_headers.get("Location"))

  }

  let response = new Response(original_text, {

            status,

            headers: new_response_headers

        })

  return response;

  

}

/**

 * @param {Request} req

 * @param {string} pathname

 */

function httpHandler(req, pathname) {

    const reqHdrRaw = req.headers

    // preflight

    if (req.method === 'OPTIONS' &&

        reqHdrRaw.has('access-control-request-headers')

    ) {

        return new Response(null, PREFLIGHT_INIT)

    }

    let rawLen = ''

    const reqHdrNew = new Headers(reqHdrRaw)

    const refer = reqHdrNew.get('referer')

    let urlStr = pathname

    

    const urlObj = newUrl(urlStr)

    /** @type {RequestInit} */

    const reqInit = {

        method: req.method,

        headers: reqHdrNew,

        redirect: 'follow',

        body: req.body

    }

    return proxy(urlObj, reqInit, rawLen, 0)

}

/**

 *

 * @param {URL} urlObj

 * @param {RequestInit} reqInit

 */

async function proxy(urlObj, reqInit, rawLen) {

    const res = await fetch(urlObj.href, reqInit)

    const resHdrOld = res.headers

    const resHdrNew = new Headers(resHdrOld)

    // verify

    if (rawLen) {

        const newLen = resHdrOld.get('content-length') || ''

        const badLen = (rawLen !== newLen)

        if (badLen) {

            return makeRes(res.body, 400, {

                '--error': `bad len: ${newLen}, except: ${rawLen}`,

                'access-control-expose-headers': '--error',

            })

        }

    }

    const status = res.status

    resHdrNew.set('access-control-expose-headers', '*')

    resHdrNew.set('access-control-allow-origin', '*')

    resHdrNew.set('Cache-Control', 'max-age=1500')

    

    resHdrNew.delete('content-security-policy')

    resHdrNew.delete('content-security-policy-report-only')

    resHdrNew.delete('clear-site-data')

    return new Response(res.body, {

        status,

        headers: resHdrNew

    })

}

给TA打赏
共{{data.count}}人
人已打赏
网络技巧

【教程】Rime - 安装最强的中文跨平台输入法引擎 没有之一

2024-6-7 11:43:03

网络技巧网络随笔

内网机器简单frp加https证书

2024-6-14 23:49:05

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索