diff --git a/src/app/api/download-file/route.ts b/src/app/api/download-file/route.ts index bb1fb78..b3fab84 100644 --- a/src/app/api/download-file/route.ts +++ b/src/app/api/download-file/route.ts @@ -1,64 +1,71 @@ -import { NextRequest, NextResponse } from 'next/server' +import { NextRequest, NextResponse } from 'next/server'; export async function GET(request: NextRequest) { try { - const searchParams = request.nextUrl.searchParams - const fileUrl = searchParams.get('url') - const fileName = searchParams.get('filename') + const searchParams = request.nextUrl.searchParams; + const fileUrl = searchParams.get('url'); + const fileName = searchParams.get('filename'); + + console.log('🔽 Проксируем скачивание файла:', fileUrl); if (!fileUrl) { return NextResponse.json( - { error: 'File URL is required' }, + { error: 'URL файла не предоставлен' }, { status: 400 } - ) + ); } - // Проверяем, что URL принадлежит нашему S3 хранилищу - if (!fileUrl.includes('s3.twcstorage.ru/617774af-sfera/')) { + // Проверяем, что URL начинается с нашего доверенного домена + if (!fileUrl.startsWith('https://s3.twcstorage.ru/')) { return NextResponse.json( - { error: 'Invalid file URL' }, + { error: 'Недопустимый URL файла' }, { status: 400 } - ) + ); } - console.log('🔽 Проксируем скачивание файла:', fileUrl) - // Загружаем файл с S3 - const response = await fetch(fileUrl, { - method: 'GET', - headers: { - 'User-Agent': 'Mozilla/5.0 (compatible; SferaApp/1.0)', - } - }) - + const response = await fetch(fileUrl); + if (!response.ok) { - console.error('❌ Ошибка загрузки с S3:', response.status, response.statusText) + console.error('❌ Ошибка загрузки файла с S3:', response.status, response.statusText); return NextResponse.json( - { error: `Failed to fetch file: ${response.status}` }, - { status: response.status } - ) + { error: 'Файл не найден' }, + { status: 404 } + ); } - // Получаем содержимое файла - const buffer = await response.arrayBuffer() + // Получаем буфер файла + const arrayBuffer = await response.arrayBuffer(); + const buffer = new Uint8Array(arrayBuffer); - console.log('✅ Файл успешно загружен с S3, размер:', buffer.byteLength) + console.log('✅ Файл успешно загружен с S3, размер:', buffer.length); + + // Определяем MIME-тип из исходного ответа или устанавливаем по умолчанию + const contentType = response.headers.get('content-type') || 'application/octet-stream'; + + // Правильно кодируем имя файла для поддержки Unicode символов + let contentDisposition = 'attachment'; + if (fileName) { + // Используем RFC 5987 кодирование для поддержки Unicode + const encodedFileName = encodeURIComponent(fileName); + contentDisposition = `attachment; filename*=UTF-8''${encodedFileName}`; + } // Возвращаем файл с правильными заголовками для скачивания return new NextResponse(buffer, { headers: { - 'Content-Type': 'application/octet-stream', // Принудительное скачивание - 'Content-Disposition': `attachment; filename="${fileName || 'file'}"`, - 'Content-Length': buffer.byteLength.toString(), + 'Content-Type': contentType, + 'Content-Disposition': contentDisposition, + 'Content-Length': buffer.length.toString(), 'Cache-Control': 'no-cache', }, - }) + }); } catch (error) { - console.error('❌ Ошибка в download-file API:', error) + console.error('❌ Ошибка в download-file API:', error); return NextResponse.json( - { error: 'Failed to download file' }, + { error: 'Внутренняя ошибка сервера' }, { status: 500 } - ) + ); } } \ No newline at end of file