27 lines
1.7 KiB
TypeScript
27 lines
1.7 KiB
TypeScript
import "server-only";
|
|
import { getDefaultStorageConfig } from "@/lib/db/queries";
|
|
import { findImageArchiveDownloadTask } from "./image-archive-db";
|
|
import { extractImageProxySourceUrl, inferOriginalImageUrl } from "@/lib/image-url";
|
|
|
|
export async function resolveCanvasCdnDownload(urls: string[], filename: string) {
|
|
const sources = Array.from(new Set(urls.flatMap(url => {
|
|
const source = extractImageProxySourceUrl(url) || url;
|
|
return [source, inferOriginalImageUrl(source) || source];
|
|
})));
|
|
const task = await findImageArchiveDownloadTask(sources, true);
|
|
const asset = (task?.metadata as { downloadAsset?: { status?: string; url?: string; contentType?: string; bytes?: number } } | null)?.downloadAsset;
|
|
if (asset?.status !== "ready" || !asset.url || asset.contentType !== "image/png") return { task, direct: null };
|
|
const config = await getDefaultStorageConfig();
|
|
if (config?.type !== "qiniu-kodo" || !config.publicUrl || !config.isEnabled) return { task, direct: null };
|
|
const url = new URL(asset.url);
|
|
const base = new URL(config.publicUrl);
|
|
const origin = process.env.CANVAS_QINIU_ORIGIN_URL;
|
|
if (origin && url.origin === new URL(origin).origin) url.host = base.host;
|
|
if (base.protocol !== "https:" || url.origin !== base.origin
|
|
|| !(url.pathname.startsWith(base.pathname.replace(/\/$/, "") + "/"))) return { task, direct: null };
|
|
// attname is interpreted by Kodo/CDN as Content-Disposition, including Chinese
|
|
// filenames. Keep all processing/auth parameters intact for correct cache keys.
|
|
url.searchParams.set("attname", filename);
|
|
return { task, direct: { delivery: "cdn", downloadUrl: url.toString(), filename, bytes: asset.bytes || 0 } };
|
|
}
|