import { NextRequest, NextResponse } from "next/server"; import { auth } from "@/app/(auth)/auth"; import { buildAttachmentContentDisposition, fetchCanvasDownloadAsset, sanitizeCanvasDownloadFileName, } from "@/lib/canvas/photoshop-safe-download"; export const runtime = "nodejs"; export const maxDuration = 120; function getRequestOrigin(request: NextRequest): string { const forwardedHost = (request.headers.get("x-forwarded-host") || "").split(",")[0]?.trim(); const forwardedProto = (request.headers.get("x-forwarded-proto") || "").split(",")[0]?.trim(); if (forwardedHost && forwardedProto) { return `${forwardedProto}://${forwardedHost}`; } return new URL(request.url).origin; } function resolveDownloadUrl(rawUrl: unknown, origin: string): string { const value = String(rawUrl || "").trim(); if (!value) return ""; try { const parsed = new URL(value, origin); if (!/^https?:$/i.test(parsed.protocol)) return ""; return parsed.toString(); } catch (_error) { return ""; } } export async function POST(request: NextRequest) { try { const session = await auth(); if (!session?.user?.id) { return NextResponse.json({ success: false, error: "未登录" }, { status: 401 }); } const body = (await request.json().catch(() => ({}))) as Record; const requestOrigin = getRequestOrigin(request); const url = resolveDownloadUrl(body.url, requestOrigin); if (!url) { return NextResponse.json({ success: false, error: "图片地址无效" }, { status: 400 }); } const name = sanitizeCanvasDownloadFileName(String(body.name || ""), "canvas-image"); const result = await fetchCanvasDownloadAsset({ file: { url, name }, index: 0, requestOrigin, cookie: request.headers.get("cookie") || "", includeSequencePrefix: false, }); if (!result.ok) { return NextResponse.json( { success: false, error: result.error || "图片下载失败" }, { status: 502 } ); } return new NextResponse(result.bytes, { status: 200, headers: { "Content-Type": result.contentType, "Content-Length": String(result.bytes.length), "Content-Disposition": buildAttachmentContentDisposition(result.filename), "Cache-Control": "no-store", }, }); } catch (error) { console.error("[CanvasDownloadImage] Failed:", error); return NextResponse.json({ success: false, error: "图片下载失败" }, { status: 500 }); } }