用CloudFlare加速Github下载

最近在拉取Github项目源码的时候经常出现404,自己在网上研究了一下,发现有个项目可以用CloudFlare的代理流量来下载Github的项目源码
我们今天用的项目是gh-proxy
首先我们注册个CloudFlare账号点我转跳CF
注册应该都会吧,没有人不会注册吧
接着我们点开菜单的Workers

选择免费的那个接着创建一个服务,服务名称就是以后访问的方式,不过没用,因为CF的域名被污染了,所以自己要准备一个域名并添加到CloudFlera里面
我们选择HTTP处理程序
创建好了后我们点快速编辑,删除全部代码把下面的代码填进去

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
'use strict'

/**
* static files (404.html, sw.js, conf.js)
*/
const ASSET_URL = 'https://hunshcn.github.io/gh-proxy/'
// 前缀,如果自定义路由为example.com/gh/*,将PREFIX改为 '/gh/',注意,少一个杠都会错!
const PREFIX = '/'
// 分支文件使用jsDelivr镜像的开关,0为关闭,默认关闭
const Config = {
jsdelivr: 0
}

const whiteList = [] // 白名单,路径里面有包含字符的才会通过,e.g. ['/username/']

/** @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',
}),
}


const exp1 = /^(?:https?:\/\/)?github\.com\/.+?\/.+?\/(?:releases|archive)\/.*$/i
const exp2 = /^(?:https?:\/\/)?github\.com\/.+?\/.+?\/(?:blob|raw)\/.*$/i
const exp3 = /^(?:https?:\/\/)?github\.com\/.+?\/.+?\/(?:info|git-).*$/i
const exp4 = /^(?:https?:\/\/)?raw\.(?:githubusercontent|github)\.com\/.+?\/.+?\/.+?\/.+$/i
const exp5 = /^(?:https?:\/\/)?gist\.(?:githubusercontent|github)\.com\/.+?\/.+?\/.+$/i
const exp6 = /^(?:https?:\/\/)?github\.com\/.+?\/.+?\/tags.*$/i

/**
* @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)
})


function checkUrl(u) {
for (let i of [exp1, exp2, exp3, exp4, exp5, exp6]) {
if (u.search(i) === 0) {
return true
}
}
return false
}

/**
* @param {FetchEvent} e
*/
async function fetchHandler(e) {
const req = e.request
const urlStr = req.url
const urlObj = new URL(urlStr)
let path = urlObj.searchParams.get('q')
if (path) {
return Response.redirect('https://' + urlObj.host + PREFIX + path, 301)
}
// cfworker 会把路径中的 `//` 合并成 `/`
path = urlObj.href.substr(urlObj.origin.length + PREFIX.length).replace(/^https?:\/+/, 'https://')
if (path.search(exp1) === 0 || path.search(exp5) === 0 || path.search(exp6) === 0 || path.search(exp3) === 0 || path.search(exp4) === 0) {
return httpHandler(req, path)
} else if (path.search(exp2) === 0) {
if (Config.jsdelivr) {
const newUrl = path.replace('/blob/', '@').replace(/^(?:https?:\/\/)?github\.com/, 'https://cdn.jsdelivr.net/gh')
return Response.redirect(newUrl, 302)
} else {
path = path.replace('/blob/', '/raw/')
return httpHandler(req, path)
}
} else if (path.search(exp4) === 0) {
const newUrl = path.replace(/(?<=com\/.+?\/.+?)\/(.+?\/)/, '@$1').replace(/^(?:https?:\/\/)?raw\.(?:githubusercontent|github)\.com/, 'https://cdn.jsdelivr.net/gh')
return Response.redirect(newUrl, 302)
} else {
return fetch(ASSET_URL + path)
}
}


/**
* @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)
}

const reqHdrNew = new Headers(reqHdrRaw)

let urlStr = pathname
let flag = false
for (let i of whiteList) {
if (urlStr.includes(i)) {
flag = true
break
}
}
if (!flag) {
return new Response("blocked", {status: 403})
}
if (urlStr.startsWith('github')) {
urlStr = 'https://' + urlStr
}
const urlObj = newUrl(urlStr)

/** @type {RequestInit} */
const reqInit = {
method: req.method,
headers: reqHdrNew,
redirect: 'manual',
body: req.body
}
return proxy(urlObj, reqInit)
}


/**
*
* @param {URL} urlObj
* @param {RequestInit} reqInit
*/
async function proxy(urlObj, reqInit) {
const res = await fetch(urlObj.href, reqInit)
const resHdrOld = res.headers
const resHdrNew = new Headers(resHdrOld)

const status = res.status

if (resHdrNew.has('location')) {
let _location = resHdrNew.get('location')
if (checkUrl(_location))
resHdrNew.set('location', PREFIX + _location)
else {
reqInit.redirect = 'follow'
return proxy(newUrl(_location), reqInit)
}
}
resHdrNew.set('access-control-expose-headers', '*')
resHdrNew.set('access-control-allow-origin', '*')

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,
})
}

填完后点击保存并部署
然后点击旁边的发送按钮,如果显示200K就是正常的了,不是的话就看看你的代码会不会输错

因为CF域名被DNS污染的关系,我们需要使用自己的域名,我们再次点开Workers选择刚才创建的服务,点击触发器
找到触发器选择添加自定义域,把你想要的自定义域名填进去

然后访问你的域名就可以使用了


用CloudFlare加速Github下载
https://bricawa.com/posts/32336/
作者
BricRoot
发布于
2022年7月20日
更新于
2023年12月15日
许可协议