handler: Refactor

This commit is contained in:
LittleChest 2026-06-14 12:41:20 +08:00
parent 1b6191580d
commit 0d95560738
5 changed files with 87 additions and 76 deletions

View File

@ -1,4 +1,4 @@
import handler from "./common"; import handler from "./handler/dns";
export default { export default {
fetch: async (request, env) => fetch: async (request, env) =>

View File

@ -45,85 +45,78 @@ export default async function handler(
} }
const { method, headers, url } = request; const { method, headers, url } = request;
const { search, searchParams, pathname } = new URL(url); const { search, searchParams } = new URL(url);
const ip = const ip =
rawIP || rawIP ||
headers.get("x-forwarded-for").split(",")[0].trim() || headers.get("x-forwarded-for").split(",")[0].trim() ||
headers.get("x-real-ip"); headers.get("x-real-ip");
let res = new Response(null, { status: 404 }); let res = new Response(null, { status: 400 });
// JSON API // JSON API
if (pathname === "/resolve") { if (method === "GET" && searchParams.has("name")) {
res = new Response(null, { status: 400 }); if (concurrent) {
res = await Promise.any(
if (method === "GET" && searchParams.has("name")) { api.map((server) =>
if (concurrent) { fetch(server + search, {
res = await Promise.any( method: "GET",
api.map((server) => headers: {
fetch(server + search, { "User-Agent":
method: "GET", "Dohna-NS (https://github.com/LittleChest/Dohna-NS)",
headers: { },
"User-Agent": }).then((res) => {
"Dohna-NS (https://github.com/LittleChest/Dohna-NS)", if (res.status !== 200) {
}, throw new Error(
}).then((res) => { `Failed to connect to ${server}: ${res.status} ${res.statusText}`,
if (res.status !== 200) { );
throw new Error( }
`Failed to connect to ${server}: ${res.status} ${res.statusText}`, return res;
); }),
} ),
return res; );
}), } else {
), const servers = [...api];
); while (servers.length > 0) {
} else { const index = Math.floor(Math.random() * servers.length);
const servers = [...api]; const server = servers.splice(index, 1)[0];
while (servers.length > 0) { try {
const index = Math.floor(Math.random() * servers.length); res = await fetch(server + search, {
const server = servers.splice(index, 1)[0]; method: "GET",
try { headers: {
res = await fetch(server + search, { "User-Agent":
method: "GET", "Dohna-NS (https://github.com/LittleChest/Dohna-NS)",
headers: { },
"User-Agent": });
"Dohna-NS (https://github.com/LittleChest/Dohna-NS)", if (res.status === 200) break;
}, } catch (e) {
}); console.warn(`Failed to connect to ${server}: ${e.message}`);
if (res.status === 200) break; continue;
} catch (e) {
console.warn(`Failed to connect to ${server}: ${e.message}`);
continue;
}
} }
console.error("All upstream JSON API servers failed.");
res = new Response(null, { status: 500 });
} }
console.error("All upstream JSON API servers failed.");
res = new Response(null, { status: 500 });
} }
} }
// DNS Query // DNS Query
if (pathname === "/dns-query") { let queryData;
res = new Response(null, { status: 400 });
let queryData; // GET
if (method === "GET" && searchParams.has("dns")) {
// Decode the base64-encoded DNS query
try {
const decodedQuery = atob(searchParams.get("dns"));
queryData = new Uint8Array(decodedQuery.length);
for (let i = 0; i < decodedQuery.length; i++) {
queryData[i] = decodedQuery.charCodeAt(i);
}
} catch {}
}
// GET // POST
if (method === "GET" && searchParams.has("dns")) { if (method === "POST") {
// Decode the base64-encoded DNS query const requestBody = await request.arrayBuffer();
try {
const decodedQuery = atob(searchParams.get("dns"));
queryData = new Uint8Array(decodedQuery.length);
for (let i = 0; i < decodedQuery.length; i++) {
queryData[i] = decodedQuery.charCodeAt(i);
}
} catch {}
}
// POST
if (method === "POST") {
const requestBody = await request.arrayBuffer();
// Anti-GFW // Anti-GFW
if ( if (
@ -148,16 +141,15 @@ export default async function handler(
queryData = new Uint8Array(requestBody); queryData = new Uint8Array(requestBody);
} }
if (queryData) { if (queryData) {
res = await queryDns( res = await queryDns(
queryData, queryData,
ip, ip,
dns, dns,
ipv4Prefix, ipv4Prefix,
ipv6Prefix, ipv6Prefix,
concurrent, concurrent,
); );
}
} }
return res; return res;

19
handler/entrypoint.js Normal file
View File

@ -0,0 +1,19 @@
import dnsHandler from "./dns";
export default async function handler(
request,
dns,
api,
ipv4Prefix = 32,
ipv6Prefix = 128,
concurrent = false,
rawIP,
) {
const { pathname } = new URL(request.url);
let res = new Response(null, { status: 404 });
// DNS over HTTPS & JSON API
if (pathname === "/dns-query" || pathname === "/resolve") {
res = dnsHandler(request, dns, api, ipv4Prefix, ipv6Prefix, concurrent, rawIP);
}
}

View File

@ -1,4 +1,4 @@
import handler from "./common"; import handler from "./handler/dns";
export default middleware = async (request) => { export default middleware = async (request) => {
return handler( return handler(

View File

@ -1,4 +1,4 @@
import handler from "../../common.js"; import handler from "../../handler/dns.js";
export default async (request) => export default async (request) =>
handler( handler(
request, request,