101 lines
3.3 KiB
TypeScript
101 lines
3.3 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server';
|
|
import { getServerSession } from 'next-auth';
|
|
import { authOptions } from '@/app/api/auth/options';
|
|
import { S3Client, GetObjectCommand } from '@aws-sdk/client-s3';
|
|
import { NoSuchKey } from '@aws-sdk/client-s3';
|
|
|
|
// Initialize S3 client
|
|
const s3Client = new S3Client({
|
|
region: 'us-east-1',
|
|
endpoint: 'https://dome-api.slm-lab.net',
|
|
credentials: {
|
|
accessKeyId: '4aBT4CMb7JIMMyUtp4Pl',
|
|
secretAccessKey: 'HGn39XhCIlqOjmDVzRK9MED2Fci2rYvDDgbLFElg'
|
|
},
|
|
forcePathStyle: true // Required for MinIO
|
|
});
|
|
|
|
// This endpoint serves mission images from Minio using the server's credentials
|
|
export async function GET(
|
|
request: NextRequest,
|
|
{ params }: { params: Promise<{ path: string[] }> }
|
|
) {
|
|
try {
|
|
const { path: pathSegments } = await params;
|
|
if (!pathSegments || pathSegments.length === 0) {
|
|
console.error('No path segments provided');
|
|
return new NextResponse('Path is required', { status: 400 });
|
|
}
|
|
|
|
// Reconstruct the full path from path segments
|
|
const filePath = pathSegments.join('/');
|
|
console.log('Fetching mission image:', {
|
|
originalPath: filePath,
|
|
segments: pathSegments
|
|
});
|
|
|
|
// Remove the missions/ prefix from the URL path since the file is already in the missions bucket
|
|
const minioPath = filePath.replace(/^missions\//, '');
|
|
console.log('Full Minio path:', {
|
|
minioPath,
|
|
bucket: 'missions',
|
|
endpoint: 'https://dome-api.slm-lab.net'
|
|
});
|
|
|
|
const command = new GetObjectCommand({
|
|
Bucket: 'missions',
|
|
Key: minioPath,
|
|
});
|
|
|
|
try {
|
|
const response = await s3Client.send(command);
|
|
if (!response.Body) {
|
|
console.error('File not found in Minio:', {
|
|
path: filePath,
|
|
minioPath,
|
|
bucket: 'missions',
|
|
contentType: response.ContentType
|
|
});
|
|
return new NextResponse('File not found', { status: 404 });
|
|
}
|
|
|
|
// Set appropriate content type and cache control
|
|
const contentType = response.ContentType || 'image/png'; // Default to image/png if not specified
|
|
const headers = new Headers();
|
|
headers.set('Content-Type', contentType);
|
|
headers.set('Cache-Control', 'public, max-age=31536000');
|
|
|
|
// Log the response details
|
|
console.log('Serving image:', {
|
|
path: filePath,
|
|
minioPath,
|
|
contentType,
|
|
contentLength: response.ContentLength,
|
|
lastModified: response.LastModified,
|
|
etag: response.ETag
|
|
});
|
|
|
|
return new NextResponse(response.Body as any, { headers });
|
|
} catch (error) {
|
|
console.error('Error fetching file from Minio:', {
|
|
error,
|
|
path: filePath,
|
|
minioPath,
|
|
bucket: 'missions',
|
|
endpoint: 'https://dome-api.slm-lab.net',
|
|
errorType: error instanceof NoSuchKey ? 'NoSuchKey' : 'Unknown'
|
|
});
|
|
if (error instanceof NoSuchKey) {
|
|
return new NextResponse('File not found', { status: 404 });
|
|
}
|
|
return new NextResponse('Internal Server Error', { status: 500 });
|
|
}
|
|
} catch (error) {
|
|
console.error('Error in image serving:', {
|
|
error,
|
|
errorType: error instanceof Error ? error.constructor.name : typeof error,
|
|
message: error instanceof Error ? error.message : String(error)
|
|
});
|
|
return new NextResponse('Internal Server Error', { status: 500 });
|
|
}
|
|
}
|