Spaces:
Paused
Paused
Update index.ts
Browse files
index.ts
CHANGED
|
@@ -1,77 +1,239 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
-
var WPAD_URL = "X_WPAD_URL";
|
| 4 |
-
var CLI_URL = "X_CLI_URL"
|
| 5 |
|
| 6 |
-
|
| 7 |
-
|
| 8 |
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
async fetch(request, env){
|
| 23 |
-
if (Object.keys(tokenmap).length == 0){
|
| 24 |
-
await syncTokens();
|
| 25 |
-
} else if(new Date().getTime() - 10*1000 > tokenSyncTime) {
|
| 26 |
-
syncTokens();
|
| 27 |
-
}
|
| 28 |
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
return await fetch(WPAD_URL, {})
|
| 40 |
-
} else if(url.length > 7 && url.substring(url.length-7) === "/cli.js") {
|
| 41 |
-
return await fetch(CLI_URL, {})
|
| 42 |
-
}
|
| 43 |
-
} catch(e) {
|
| 44 |
-
return new Response("Server error", {status: 500});
|
| 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 |
}
|
|
|
|
| 1 |
+
addEventListener('fetch', event => {
|
| 2 |
+
event.passThroughOnException()
|
|
|
|
|
|
|
| 3 |
|
| 4 |
+
event.respondWith(handleRequest(event))
|
| 5 |
+
})
|
| 6 |
|
| 7 |
+
/**
|
| 8 |
+
* Respond to the request
|
| 9 |
+
*/
|
| 10 |
+
async function handleRequest(event) {
|
| 11 |
+
const { request } = event;
|
| 12 |
+
//请求头部、返回对象
|
| 13 |
+
let reqHeaders = new Headers(request.headers),
|
| 14 |
+
outBody, outStatus = 200, outStatusText = 'OK', outCt = null, outHeaders = new Headers({
|
| 15 |
+
"x-url": request.url,
|
| 16 |
+
"Access-Control-Allow-Origin": reqHeaders.get('Origin'),
|
| 17 |
+
"Access-Control-Allow-Methods": "GET, POST, PUT, PATCH, DELETE, OPTIONS",
|
| 18 |
+
"Access-Control-Allow-Headers": reqHeaders.get('Access-Control-Allow-Headers') || "Accept, Authorization, Cache-Control, Content-Type, DNT, If-Modified-Since, Keep-Alive, Origin, User-Agent, X-Requested-With, Token, x-access-token, Notion-Version"
|
| 19 |
+
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 20 |
|
| 21 |
+
//取域名第一个斜杠后的所有信息为代理链接
|
| 22 |
+
let url = request.url.substr(8);
|
| 23 |
+
url = decodeURIComponent(url.substr(url.indexOf('/') + 1));
|
| 24 |
+
let refer = reqHeaders.get("Referer")
|
| 25 |
+
let cookie = reqHeaders.get("Cookie")
|
| 26 |
+
try {
|
| 27 |
+
//需要忽略的代理
|
| 28 |
+
if (request.method == "OPTIONS" && reqHeaders.has('access-control-request-headers')) {
|
| 29 |
+
//输出提示
|
| 30 |
+
return new Response(null, PREFLIGHT_INIT)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 31 |
}
|
| 32 |
+
//阻断
|
| 33 |
+
/*else if (blocker.check(url)) {
|
| 34 |
+
return Response.redirect('https://baidu.com/block'+url, 301)
|
| 35 |
+
} else if(url && !(url.includes("https:")||url.includes("http:"))){
|
| 36 |
+
url = "https://github.com/"+url
|
| 37 |
+
} else if(url=="/"){
|
| 38 |
+
url = "https://github.com/"
|
| 39 |
+
} else {*/
|
| 40 |
+
//补上前缀 http://
|
| 41 |
+
url = url.replace(/https:(\/)*/,'https://').replace(/http:(\/)*/, 'http://')
|
| 42 |
+
if (url.indexOf("://") == -1) {
|
| 43 |
+
if(refer){
|
| 44 |
+
refer = refer.replace("https://x-undefined-2-socks-server.hf.space/", "")
|
| 45 |
+
let xref = refer.substr(0, refer.indexOf('/', 10)+1)
|
| 46 |
+
url = xref + url;
|
| 47 |
+
}
|
| 48 |
+
}
|
| 49 |
+
let domain = url.substr(0, url.indexOf('/', 10)+1);
|
| 50 |
+
if(refer){
|
| 51 |
+
refer = refer.replace("https://x-undefined-2-socks-server.hf.space/", "")
|
| 52 |
+
domain = refer.substr(0, refer.indexOf('/', 10)+1)
|
| 53 |
+
// url = domain + url
|
| 54 |
+
}
|
| 55 |
+
outHeaders.set("xxx_url", url)
|
| 56 |
+
outHeaders.set("xxx_domain", domain)
|
| 57 |
+
//}
|
| 58 |
+
//构建 fetch 参数
|
| 59 |
+
let fp = {
|
| 60 |
+
method: request.method,
|
| 61 |
+
headers: {}
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
//保留头部其它信息
|
| 65 |
+
let he = reqHeaders.entries();
|
| 66 |
+
for (let h of he) {
|
| 67 |
+
if (!['content-length'].includes(h[0])) {
|
| 68 |
+
fp.headers[h[0]] = h[1];
|
| 69 |
+
}
|
| 70 |
}
|
| 71 |
+
// 是否带 body
|
| 72 |
+
if (["POST", "PUT", "PATCH", "DELETE"].indexOf(request.method) >= 0) {
|
| 73 |
+
const ct = (reqHeaders.get('content-type') || "").toLowerCase();
|
| 74 |
+
if (ct.includes('application/json')) {
|
| 75 |
+
let requestJSON = await request.json()
|
| 76 |
+
console.log(typeof requestJSON)
|
| 77 |
+
fp.body = JSON.stringify(requestJSON);
|
| 78 |
+
} else if (ct.includes('application/text') || ct.includes('text/html')) {
|
| 79 |
+
fp.body = await request.text();
|
| 80 |
+
} else if (ct.includes('form')) {
|
| 81 |
+
fp.body = await request.formData();
|
| 82 |
+
} else {
|
| 83 |
+
fp.body = await request.blob();
|
| 84 |
+
}
|
| 85 |
+
}
|
| 86 |
+
// 发起 fetch
|
| 87 |
+
let fr = (await fetch(new URL(url), fp));
|
| 88 |
+
outCt = fr.headers.get('content-type');
|
| 89 |
+
if(outCt && (outCt.includes('application/text') || outCt.includes('text/html'))) {
|
| 90 |
+
try {
|
| 91 |
+
// 添加base
|
| 92 |
+
let newFr = new HTMLRewriter()
|
| 93 |
+
.on("head", {
|
| 94 |
+
element(element) {
|
| 95 |
+
element.prepend(`<base href="https://x-undefined-2-socks-server.hf.space/${url}" />`, {
|
| 96 |
+
html: true
|
| 97 |
+
})
|
| 98 |
+
},
|
| 99 |
+
})
|
| 100 |
+
.on("link", {
|
| 101 |
+
element(element) {
|
| 102 |
+
let href = element.getAttribute("href")
|
| 103 |
+
if(href){
|
| 104 |
+
if(href.indexOf("https://") == 0){
|
| 105 |
+
element.setAttribute("href", "https://x-undefined-2-socks-server.hf.space/"+href);
|
| 106 |
+
} else if(href[0] == '/') {
|
| 107 |
+
element.setAttribute("href", "https://x-undefined-2-socks-server.hf.space/"+domain.substr(0, domain.lastIndexOf('/'))+href);
|
| 108 |
+
} else {
|
| 109 |
+
element.setAttribute("href", request.url+href);
|
| 110 |
+
}
|
| 111 |
+
}
|
| 112 |
+
},
|
| 113 |
+
})
|
| 114 |
+
.on("script", {
|
| 115 |
+
element(element) {
|
| 116 |
+
let href = element.getAttribute("src")
|
| 117 |
+
if(href){
|
| 118 |
+
if(href.indexOf("https://") == 0){
|
| 119 |
+
element.setAttribute("src", "https://x-undefined-2-socks-server.hf.space/"+href);
|
| 120 |
+
} else if(href[0] == '/') {
|
| 121 |
+
element.setAttribute("src", "https://x-undefined-2-socks-server.hf.space/"+domain.substr(0, domain.lastIndexOf('/'))+href);
|
| 122 |
+
} else {
|
| 123 |
+
element.setAttribute("src", request.url+href);
|
| 124 |
+
}
|
| 125 |
+
}
|
| 126 |
+
},
|
| 127 |
+
})
|
| 128 |
+
.on("img", {
|
| 129 |
+
element(element) {
|
| 130 |
+
let href = element.getAttribute("src")
|
| 131 |
+
if(href){
|
| 132 |
+
if(href.indexOf("https://") == 0){
|
| 133 |
+
element.setAttribute("src", "https://x-undefined-2-socks-server.hf.space/"+href);
|
| 134 |
+
} else if(href[0] == '/') {
|
| 135 |
+
element.setAttribute("src", "https://x-undefined-2-socks-server.hf.space/"+domain.substr(0, domain.lastIndexOf('/'))+href);
|
| 136 |
+
} else if(href.indexOf("data:image") == 0){
|
| 137 |
+
} else {
|
| 138 |
+
element.setAttribute("src", request.url+href);
|
| 139 |
+
}
|
| 140 |
+
}
|
| 141 |
+
},
|
| 142 |
+
})
|
| 143 |
+
.on("form", {
|
| 144 |
+
element(element) {
|
| 145 |
+
let href = element.getAttribute("action")
|
| 146 |
+
if(href){
|
| 147 |
+
if(href.indexOf("https://") == 0){
|
| 148 |
+
element.setAttribute("action", "https://x-undefined-2-socks-server.hf.space/"+href);
|
| 149 |
+
} else if(href[0] == '/') {
|
| 150 |
+
element.setAttribute("action", "https://x-undefined-2-socks-server.hf.space/"+domain.substr(0, domain.lastIndexOf('/'))+href);
|
| 151 |
+
} else {
|
| 152 |
+
element.setAttribute("action", request.url+href);
|
| 153 |
+
}
|
| 154 |
+
}
|
| 155 |
+
},
|
| 156 |
+
})
|
| 157 |
+
.on("a", {
|
| 158 |
+
element(element) {
|
| 159 |
+
let href = element.getAttribute("href")
|
| 160 |
+
if(href){
|
| 161 |
+
if(href.indexOf("https://") == 0){
|
| 162 |
+
element.setAttribute("href", "https://x-undefined-2-socks-server.hf.space/"+href);
|
| 163 |
+
} else if(href[0] == '/') {
|
| 164 |
+
element.setAttribute("href", "https://x-undefined-2-socks-server.hf.space/"+domain.substr(0, domain.lastIndexOf('/'))+href);
|
| 165 |
+
} else {
|
| 166 |
+
element.setAttribute("href", request.url+href);
|
| 167 |
+
}
|
| 168 |
+
}
|
| 169 |
+
},
|
| 170 |
+
})
|
| 171 |
+
.transform(fr)
|
| 172 |
+
outHeaders.set("error", "noerror");
|
| 173 |
+
fr = newFr
|
| 174 |
+
} catch(e) {
|
| 175 |
+
outHeaders.set("error", e);
|
| 176 |
+
}
|
| 177 |
+
}
|
| 178 |
+
|
| 179 |
+
for (const [key, value] of fr.headers.entries()) {
|
| 180 |
+
if(key =="Content-Security-Policy" || key =="content-security-policy"){
|
| 181 |
+
outHeaders.set(key, value.replaceAll("github.githubassets.com", "x-undefined-2-socks-server.hf.space github.githubassets.com").replaceAll("script-src .*?;", "script-src 'self' 'unsafe-inline';"));
|
| 182 |
+
}
|
| 183 |
+
}
|
| 184 |
+
outHeaders.set("Access-Control-Allow-Origin", "x-undefined-2-socks-server.hf.space")
|
| 185 |
+
outHeaders.set("Access-Control-Allow-Methods", "*")
|
| 186 |
+
outHeaders.set("Access-Control-Allow-Credentials", "true")
|
| 187 |
+
|
| 188 |
+
outStatus = fr.status;
|
| 189 |
+
outStatusText = fr.statusText;
|
| 190 |
+
outBody = fr.body;
|
| 191 |
+
outBody = injectOutBody(url, outBody)
|
| 192 |
+
} catch (err) {
|
| 193 |
+
outHeaders.set("hasError", err);
|
| 194 |
+
outCt = "application/json";
|
| 195 |
+
outBody = JSON.stringify({
|
| 196 |
+
code: -1,
|
| 197 |
+
msg: JSON.stringify(err.stack) || err
|
| 198 |
+
});
|
| 199 |
+
} finally {
|
| 200 |
+
outHeaders.set("x_Url_ext", request.url)
|
| 201 |
+
outHeaders.set("x_Refer", refer)
|
| 202 |
}
|
| 203 |
+
|
| 204 |
+
//设置类型
|
| 205 |
+
if (outCt && outCt != "") {
|
| 206 |
+
outHeaders.set("content-type", outCt);
|
| 207 |
+
}
|
| 208 |
+
|
| 209 |
+
let response = new Response(outBody, {
|
| 210 |
+
status: outStatus,
|
| 211 |
+
statusText: outStatusText,
|
| 212 |
+
headers: outHeaders
|
| 213 |
+
})
|
| 214 |
+
|
| 215 |
+
return response;
|
| 216 |
+
|
| 217 |
+
// return new Response('OK', { status: 200 })
|
| 218 |
+
}
|
| 219 |
+
|
| 220 |
+
/**
|
| 221 |
+
* 阻断器
|
| 222 |
+
*/
|
| 223 |
+
const blocker = {
|
| 224 |
+
keys: [".m3u8", ".ts", ".acc", ".m4s", "photocall.tv", "googlevideo.com"],
|
| 225 |
+
check: function (url) {
|
| 226 |
+
url = url.toLowerCase();
|
| 227 |
+
let len = blocker.keys.filter(x => url.includes(x)).length;
|
| 228 |
+
return len != 0;
|
| 229 |
+
}
|
| 230 |
+
}
|
| 231 |
+
|
| 232 |
+
const injectOutBody = (url, body)=>{
|
| 233 |
+
// if(url.includes("huggingface.co") && url.endsWith("index.js")) {
|
| 234 |
+
// let domain = url.substr(0, url.indexOf("/", 9))
|
| 235 |
+
// console.log(body)
|
| 236 |
+
// return body.text();//.replace(/href: \"(.*?)\"/ig, "href:\"https://x-undefined-2-socks-server.hf.space/"+domain+"$1\"")
|
| 237 |
+
// }
|
| 238 |
+
return body;
|
| 239 |
}
|