import type { NextRequest } from 'next/server' import { NextResponse } from 'next/server' /// Resend request to backend. /// Body is being sent as stream. export async function redirectRequest( req: NextRequest, proxyUrl: string, backendBaseUrl: string ): Promise { const reqUrl = req.url // full URL e.g. http://localhost:3000/api/proxy?id=123 // Find position of proxyPath in reqUrl const proxyIndex = reqUrl.indexOf(proxyUrl) if (proxyIndex === -1) { return new NextResponse('Invalid proxy path', { status: 400 }) } // Replace '/api/proxy/parserBackend' with backend URL, preserve everything after // e.g. '/api/proxy/extra/path?id=123' -> 'http://backend-server/extra/path?id=123' const backendUrl = backendBaseUrl + reqUrl.substring(proxyIndex + proxyUrl.length) // console.log('redirecting', req.url, 'to', backendUrl) const backendRes = await fetch(backendUrl, { method: req.method, headers: req.headers, body: req.body, // @ts-ignore duplex: 'half', // some property required by nodejs but not defined in @types/node }) return new NextResponse(backendRes.body, { status: backendRes.status, headers: { 'Access-Control-Allow-Origin': '*', 'Content-Type': backendRes.headers.get('content-type') || 'application/octet-stream', }, }) } /// Browsers send OPTIONS request sometimes to check webserver allowed headers and methods. /// My backend doesn't support such requests so use proxy to answer to it that all headers and methods are allowed export async function responseToOPTIONS(req: NextRequest): Promise { // console.log('proxy responding to CORS OPTIONS', req.url) return new NextResponse(null, { status: 200, headers: { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, POST, PUT, PATCH, DELETE, HEAD', 'Access-Control-Allow-Headers': req.headers.get('access-control-request-headers') || 'Content-Type, Authorization', }, }) }