File size: 3,739 Bytes
978aec7 b3f1ddf 978aec7 b3f1ddf 978aec7 901bdbc 978aec7 b3f1ddf 978aec7 b3f1ddf 978aec7 901bdbc 978aec7 901bdbc 978aec7 901bdbc 978aec7 b3f1ddf 978aec7 b3f1ddf 978aec7 901bdbc 978aec7 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | import { NextRequest, NextResponse } from 'next/server';
const BACKEND_URL = process.env.BACKEND_URL || 'http://localhost:8000';
// Increase timeout to 5 minutes for long-running operations
export const maxDuration = 300;
export async function GET(
request: NextRequest,
context: { params: Promise<{ path: string[] }> }
) {
const { path } = await context.params;
const pathString = path.join('/');
const url = `${BACKEND_URL}/api/${pathString}${request.nextUrl.search}`;
try {
const response = await fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
// No timeout - let it run
});
// Try to parse as JSON, fall back to text if it fails
let data;
try {
data = await response.json();
} catch {
const text = await response.text();
data = { detail: text || 'Unknown error' };
}
return NextResponse.json(data, { status: response.status });
} catch (error: any) {
console.error('API proxy error:', error);
return NextResponse.json(
{ detail: error.message || 'Internal server error' },
{ status: 500 }
);
}
}
export async function POST(
request: NextRequest,
context: { params: Promise<{ path: string[] }> }
) {
const { path } = await context.params;
const pathString = path.join('/');
const url = `${BACKEND_URL}/api/${pathString}`;
try {
const contentType = request.headers.get('content-type') || '';
let body: any;
let headers: HeadersInit = {
'Cookie': request.headers.get('cookie') || '',
};
// Handle FormData (file uploads)
if (contentType.includes('multipart/form-data')) {
body = await request.formData();
// Don't set Content-Type - let fetch set it with boundary
} else {
// Handle JSON
body = JSON.stringify(await request.json());
headers['Content-Type'] = 'application/json';
}
const response = await fetch(url, {
method: 'POST',
headers,
body,
// No timeout - let it run as long as needed
});
// Try to parse as JSON, fall back to text if it fails
let data;
try {
data = await response.json();
} catch {
const text = await response.text();
data = { detail: text || 'Unknown error' };
}
// Forward cookies from backend to frontend
const setCookieHeader = response.headers.get('set-cookie');
const responseHeaders: HeadersInit = {};
if (setCookieHeader) {
responseHeaders['set-cookie'] = setCookieHeader;
}
return NextResponse.json(data, {
status: response.status,
headers: responseHeaders
});
} catch (error: any) {
console.error('API proxy error:', error);
return NextResponse.json(
{ detail: error.message || 'Internal server error' },
{ status: 500 }
);
}
}
export async function DELETE(
_request: NextRequest,
context: { params: Promise<{ path: string[] }> }
) {
const { path } = await context.params;
const pathString = path.join('/');
const url = `${BACKEND_URL}/api/${pathString}`;
try {
const response = await fetch(url, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
},
});
// Try to parse as JSON, fall back to text if it fails
let data;
try {
data = await response.json();
} catch {
const text = await response.text();
data = { detail: text || 'Unknown error' };
}
return NextResponse.json(data, { status: response.status });
} catch (error: any) {
console.error('API proxy error:', error);
return NextResponse.json(
{ detail: error.message || 'Internal server error' },
{ status: 500 }
);
}
}
|