geo-mirror
71 строка · 2.0 Кб
1/**
2* getArchMirror
3* @param {string} country
4* @returns Promise<string>
5*/
6export async function getArchMirror(country) {7const src = await fetch('https://archlinux.org/mirrorlist/?ip_version=4', {8cf: {9cacheTtl: 3600, // 1 hour10cacheEverything: true11}12}).then(r => r.text())13const re = /Server = (https?:\/\/.*)\/\$repo\/os\/\$arch/g14const mirrors = {}15let match16while (match = re.exec(src)) {17const url = new URL(match[1])18const tld = url.hostname.split('.').pop()19mirrors[tld] = url.toString()20}21if (country.toLowerCase() in mirrors) {22return mirrors[country.toLowerCase()]23} else {24return 'https://geo.mirror.pkgbuild.com'25}26}
27
28
29/**
30* getDebianMirror
31* @param {string} country
32* @returns Promise<string>
33*/
34export function getDebianMirror(country) {35return Promise.resolve(`https://ftp.${country.toLowerCase()}.debian.org`)36}
37
38/**
39* getUbuntuMirror
40* @param {string} country
41* @returns Promise<string>
42*/
43export function getUbuntuMirror(country) {44return Promise.resolve(`https://${country.toLowerCase()}.archive.ubuntu.com`)45}
46
47export default {48/**49* fetch
50* @param {Request} request
51* @returns {Promise<Response>}
52*/
53async fetch(request) {54const url = new URL(request.url);55const country = /** @type {string} */ (request.cf.country);56const pathname =url.pathname.split('/').slice(2).join('/')57if (url.pathname.startsWith('/archlinux')) {58const redirect = `${await getArchMirror(country)}/${pathname}`59return Response.redirect(redirect);60}61if (url.pathname.startsWith('/ubuntu')) {62const redirect = `${await getUbuntuMirror(country)}/${pathname}`63return Response.redirect(redirect)64}65if (url.pathname.startsWith('/debian')) {66const redirect = `${await getDebianMirror(country)}/${pathname}`67return Response.redirect(redirect);68}69return Response.redirect('https://github.com/tani/geo-mirror')70}71};72