import { RegionModel } from '@db/Region'; import { ServerlistModel } from '@db/Serverlist'; import proxy from 'egg-http-proxy-middleware'; module.exports = () => { return async function (ctx, next) { if(!ctx.app.config.envToHost) { let envToHost = new Map(); let regions = await RegionModel.getAllRegion(); for(let { env, webHost } of regions) { envToHost.set(env, webHost); } ctx.app.config.envToHost = envToHost; } if(!ctx.app.config.sidToHost) { await getNewHost(ctx); } let options = {}; for(let [env, webHost] of ctx.app.config.envToHost) { options[`/web/${env}/`] = { target: webHost, changeOrigin: true, secure: true, pathRewrite: function(path) { console.log('proxy', path, path.replace(`/web/${env}/`, '/web/')) return path.replace(`/web/${env}/`, '/web/') } } } if(ctx.request.header['is-proxy'] != 'true') { let url = getProxyUrl(ctx.request.url); if(url) { let sid = getServerId(url, ctx); if(!ctx.app.config.sidToHost) { await getNewHost(sid); } if(!!ctx.app.config.sidToHost.get(sid)) { options[url] = { target: ctx.app.config.sidToHost.get(sid), changeOrigin: true, secure: true, headers: { "is-proxy": "true" } } } } } return proxy(options)(ctx, next); }; }; async function getNewHost(ctx) { let envToHost = ctx.app.config.envToHost||new Map(); let sidToHost = new Map(); let servers = await ServerlistModel.getAllServerList(); for(let { id, env, isMain } of servers) { let webHost = envToHost.get(env); sidToHost.set(id.toString(), webHost); if(isMain) sidToHost.set('main', webHost); } if(!sidToHost.has('main') && servers.length > 0) sidToHost.set('main', envToHost.get(servers[0].env)); ctx.app.config.sidToHost = sidToHost; } function getProxyUrl(url: string) { const urls = [ '/cb/treatusername', '/cb/treatguildname', '/cb/getguildbyuser', '/cb/refundioscallback', '/cb/sendgiftcode', '/cb/getrolebyserver', '/cb/getserverinfo', '/cb/getrolebyuid', ]; for(let str of urls) { if(url && url.startsWith(str)) { return str; } } } function getServerId(url: string, ctx: any) { switch(url) { case '/cb/treatusername': case '/cb/treatguildname': case '/cb/getguildbyuser': return ctx.query.sid.toString(); case '/cb/refundioscallback': return ctx.request.body.sid.toString(); case '/cb/sendgiftcode': return ctx.request.body.server_id.toString(); case '/cb/getrolebyserver': case '/cb/getserverinfo': return ctx.query.server_id.toString(); case '/cb/getrolebyuid': return 'main'; } }