35 lines
1.7 KiB
TypeScript
35 lines
1.7 KiB
TypeScript
export const DEFAULT_API_BASE_URL = 'https://webhgcgapi.mfcg.me';
|
|
export const UPSTREAM_HOP_HEADER = 'x-91dj-upstream';
|
|
|
|
export interface ApiRequestContext {
|
|
headers: Pick<Headers, 'get'>;
|
|
url?: string;
|
|
}
|
|
|
|
function configuredApiUrl(): string {
|
|
return (process.env.UPSTREAM_API_URL ?? process.env.API_BASE_URL ?? DEFAULT_API_BASE_URL).trim();
|
|
}
|
|
|
|
export function usesCurrentApiOrigin(): boolean {
|
|
return configuredApiUrl() === 'current';
|
|
}
|
|
|
|
/** Resolve each visitor's origin at request time; never store a request host globally. */
|
|
export function getApiBaseUrl(request?: ApiRequestContext): string {
|
|
const value = configuredApiUrl();
|
|
if (value === 'current') {
|
|
const incoming = request?.url ? new URL(request.url) : undefined;
|
|
const host = (request?.headers.get('host') || request?.headers.get('x-forwarded-host')?.split(',')[0] || incoming?.host || '').trim();
|
|
const protocol = (request?.headers.get('x-forwarded-proto')?.split(',')[0] || incoming?.protocol.replace(':', '') || 'https').trim();
|
|
if (!host || /[\s,/\\?#@]/.test(host) || !['http', 'https'].includes(protocol)) throw new Error('当前域名接口模式缺少有效的请求域名或协议');
|
|
const origin = new URL(protocol + '://' + host);
|
|
if (origin.username || origin.password || origin.pathname !== '/' || origin.search || origin.hash) throw new Error('当前域名接口地址无效');
|
|
return origin.origin;
|
|
}
|
|
try {
|
|
const url = new URL(value);
|
|
if (!['http:', 'https:'].includes(url.protocol) || url.username || url.password || url.search || url.hash) throw new Error('Invalid upstream');
|
|
return url.href.replace(/\/+$/, '');
|
|
} catch { throw new Error('UPSTREAM_API_URL 必须是有效的 HTTP(S) 接口地址'); }
|
|
}
|