import { NextRequest, NextResponse } from "next/server"; import { isAuthenticated } from "@/lib/auth"; export async function GET(req: NextRequest) { const user: any = await isAuthenticated(); if (user instanceof NextResponse || !user) { return NextResponse.json({ message: "Unauthorized" }, { status: 401 }); } const { searchParams } = new URL(req.url); const spaceId = searchParams.get('spaceId'); const commitId = searchParams.get('commitId'); const path = searchParams.get('path') || '/'; if (!spaceId) { return NextResponse.json({ error: "spaceId parameter required" }, { status: 400 }); } try { const spaceDomain = `${spaceId.replace("/", "-")}${commitId !== null? `--rev-${commitId.slice(0, 7)}` : ""}.static.hf.space`; const targetUrl = `https://${spaceDomain}${path}`; console.log("targetUrl", targetUrl); const response = await fetch(targetUrl, { headers: { 'User-Agent': req.headers.get('user-agent') || '', }, }); if (!response.ok) { console.error('Failed to fetch from HF space:', response.status, response.statusText); return NextResponse.json({ error: "Failed to fetch content", details: `${response.status} ${response.statusText}`, targetUrl }, { status: response.status }); } let content = await response.text(); const contentType = response.headers.get('content-type') || 'text/html'; // Rewrite relative URLs to go through the proxy if (contentType.includes('text/html')) { const baseUrl = `https://${spaceDomain}`; // Fix relative URLs in href attributes content = content.replace(/href="([^"]+)"/g, (match, url) => { if (url.startsWith('/') && !url.startsWith('//')) { // Relative URL starting with / return `href="${baseUrl}${url}"`; } else if (!url.includes('://') && !url.startsWith('#') && !url.startsWith('mailto:') && !url.startsWith('tel:')) { // Relative URL not starting with / return `href="${baseUrl}/${url}"`; } return match; }); // Fix relative URLs in src attributes content = content.replace(/src="([^"]+)"/g, (match, url) => { if (url.startsWith('/') && !url.startsWith('//')) { return `src="${baseUrl}${url}"`; } else if (!url.includes('://')) { return `src="${baseUrl}/${url}"`; } return match; }); // Add base tag to ensure relative URLs work correctly const baseTag = ``; if (content.includes('')) { content = content.replace('', `${baseTag}`); } else if (content.includes('')) { content = content.replace('', `${baseTag}`); } else { content = `${baseTag}` + content; } } const injectedScript = ` `; let modifiedContent; if (content.includes('')) { modifiedContent = content.replace( /<\/body>/i, `${injectedScript}` ); } else { modifiedContent = content + injectedScript; } return new NextResponse(modifiedContent, { headers: { 'Content-Type': contentType, 'Cache-Control': 'no-cache, no-store, must-revalidate', }, }); } catch (error) { return NextResponse.json({ error: "Proxy request failed", details: error instanceof Error ? error.message : String(error), spaceId }, { status: 500 }); } }