Spaces:
Running
Running
| /* | |
| * route.ts | |
| * Purpose: Fetches remote images through a same-origin route so export/canvas code can safely reuse them. | |
| * Used by: Image capture/export helpers and any UI path that needs proxied remote images. | |
| * Depends on: Next.js route handlers and remote fetch. | |
| */ | |
| import { NextRequest, NextResponse } from 'next/server'; | |
| export async function GET(request: NextRequest) { | |
| const rawUrl = request.nextUrl.searchParams.get('url'); | |
| if (!rawUrl) { | |
| return NextResponse.json({ error: 'url required' }, { status: 400 }); | |
| } | |
| let target: URL; | |
| try { | |
| target = new URL(rawUrl); | |
| } catch { | |
| return NextResponse.json({ error: 'invalid url' }, { status: 400 }); | |
| } | |
| if (!['http:', 'https:'].includes(target.protocol)) { | |
| return NextResponse.json({ error: 'unsupported protocol' }, { status: 400 }); | |
| } | |
| try { | |
| const response = await fetch(target.toString(), { | |
| headers: { | |
| 'User-Agent': 'powerpoint-image-proxy/1.0', | |
| }, | |
| cache: 'no-store', | |
| }); | |
| if (!response.ok) { | |
| return NextResponse.json({ error: 'failed to fetch asset' }, { status: response.status }); | |
| } | |
| const contentType = response.headers.get('content-type') || 'application/octet-stream'; | |
| const buffer = await response.arrayBuffer(); | |
| return new NextResponse(buffer, { | |
| status: 200, | |
| headers: { | |
| 'Content-Type': contentType, | |
| 'Cache-Control': 'public, max-age=3600', | |
| }, | |
| }); | |
| } catch (error) { | |
| console.error('Image proxy error:', error); | |
| return NextResponse.json({ error: 'failed to proxy asset' }, { status: 502 }); | |
| } | |
| } | |