65 lines
1.8 KiB
TypeScript
65 lines
1.8 KiB
TypeScript
type HostSource = string | null | undefined;
|
|
|
|
type CanvasHostUrlParams = {
|
|
canvasPort?: number;
|
|
hostOverride?: HostSource;
|
|
requestHost?: HostSource;
|
|
forwardedProto?: HostSource | HostSource[];
|
|
localAddress?: HostSource;
|
|
scheme?: "http" | "https";
|
|
};
|
|
|
|
const isLoopbackHost = (value: string) => {
|
|
const normalized = value.trim().toLowerCase();
|
|
if (!normalized) return false;
|
|
if (normalized === "localhost") return true;
|
|
if (normalized === "::1") return true;
|
|
if (normalized === "0.0.0.0" || normalized === "::") return true;
|
|
return normalized.startsWith("127.");
|
|
};
|
|
|
|
const normalizeHost = (value: HostSource, rejectLoopback: boolean) => {
|
|
if (!value) return "";
|
|
const trimmed = value.trim();
|
|
if (!trimmed) return "";
|
|
if (rejectLoopback && isLoopbackHost(trimmed)) return "";
|
|
return trimmed;
|
|
};
|
|
|
|
const parseHostHeader = (value: HostSource) => {
|
|
if (!value) return "";
|
|
try {
|
|
return new URL(`http://${String(value).trim()}`).hostname;
|
|
} catch {
|
|
return "";
|
|
}
|
|
};
|
|
|
|
const parseForwardedProto = (value: HostSource | HostSource[]) => {
|
|
if (Array.isArray(value)) return value[0];
|
|
return value;
|
|
};
|
|
|
|
export function resolveCanvasHostUrl(params: CanvasHostUrlParams) {
|
|
const port = params.canvasPort;
|
|
if (!port) return undefined;
|
|
|
|
const scheme =
|
|
params.scheme ??
|
|
(parseForwardedProto(params.forwardedProto)?.trim() === "https"
|
|
? "https"
|
|
: "http");
|
|
|
|
const override = normalizeHost(params.hostOverride, true);
|
|
const requestHost = normalizeHost(parseHostHeader(params.requestHost), !!override);
|
|
const localAddress = normalizeHost(
|
|
params.localAddress,
|
|
Boolean(override || requestHost),
|
|
);
|
|
|
|
const host = override || requestHost || localAddress;
|
|
if (!host) return undefined;
|
|
const formatted = host.includes(":") ? `[${host}]` : host;
|
|
return `${scheme}://${formatted}:${port}`;
|
|
}
|