import { NextRequest } from 'next/server'; import { createLogger } from '@/lib/logger'; import { apiError, apiSuccess } from '@/lib/server/api-response'; import { resolvePDFApiKey, resolvePDFBaseUrl } from '@/lib/server/provider-config'; import { validateUrlForSSRF } from '@/lib/server/ssrf-guard'; const log = createLogger('Verify PDF Provider'); export async function POST(req: NextRequest) { let providerId: string | undefined; try { const body = await req.json(); providerId = body.providerId; const { apiKey, baseUrl } = body; if (!providerId) { return apiError('MISSING_REQUIRED_FIELD', 400, 'Provider ID is required'); } const clientBaseUrl = (baseUrl as string | undefined) || undefined; if (clientBaseUrl && process.env.NODE_ENV === 'production') { const ssrfError = await validateUrlForSSRF(clientBaseUrl); if (ssrfError) { return apiError('INVALID_URL', 403, ssrfError); } } const resolvedBaseUrl = clientBaseUrl ? clientBaseUrl : resolvePDFBaseUrl(providerId, baseUrl); if (!resolvedBaseUrl) { return apiError('MISSING_REQUIRED_FIELD', 400, 'Base URL is required'); } const resolvedApiKey = clientBaseUrl ? (apiKey as string | undefined) || '' : resolvePDFApiKey(providerId, apiKey); const headers: Record = {}; if (resolvedApiKey) { headers['Authorization'] = `Bearer ${resolvedApiKey}`; } const response = await fetch(resolvedBaseUrl, { headers, signal: AbortSignal.timeout(10000), redirect: 'manual', }); if (response.status >= 300 && response.status < 400) { return apiError('REDIRECT_NOT_ALLOWED', 403, 'Redirects are not allowed'); } // MinerU's FastAPI root returns 404 (no root route), but the server is reachable. // Any HTTP response (including 404) means the server is up. return apiSuccess({ message: 'Connection successful', status: response.status, }); } catch (error) { log.error(`PDF provider verification failed [provider=${providerId ?? 'unknown'}]:`, error); let errorMessage = 'Connection failed'; if (error instanceof Error) { if (error.message.includes('ECONNREFUSED')) { errorMessage = 'Cannot connect to server, please check the Base URL'; } else if (error.message.includes('ENOTFOUND')) { errorMessage = 'Server not found, please check the Base URL'; } else if (error.message.includes('timeout') || error.name === 'TimeoutError') { errorMessage = 'Connection timed out'; } else { errorMessage = error.message; } } return apiError('INTERNAL_ERROR', 500, errorMessage); } }