Search code examples
node.jsproxynext.jsmultipartform-data

Proxy pass multipart in NextJS(also NodeJS)


My task was to proxy pass multipart/form-data through NextJS api routes, but the built-in bodyParser was breaking incoming muptipart data. Any others plugins for NodeJS not allowing me to proxy pass clear bytes of multipart data and making others objects which is not form-data.

So how to proxy pass multipart/form-data in NextJS API-routes without plugins?


Solution

  • Next code is the solution to success proxy pass multipart/form-data without plugins for NextJS:

    // /pages/api/miltipart.ts
    
    // helpers to generate cookies
    import { setCookies } from '@utils/api';
    import type { NextApiRequest, NextApiResponse } from 'next';
    
    // turn off default parser for current route
    export const config = {
      api: {
        bodyParser: false,
      },
    };
    
    const handler = async (req: NextApiRequest, res: NextApiResponse): Promise<void> => {
      // create container for all buffers of multipart/form-data
      const buffers: any[] = [];
      // first of all listen 'readable' event to catch all incoming request data
      req
        .on('readable', () => {
          // read every incoming chunk. Every chunk is 64Kb data of Buffer
          const chunk = req.read();
          if (chunk !== null) {
            buffers.push(chunk);
          }
        })
        // listen on end event of request to send our data
        .on('end', async () => {
            try {
              const result = await fetch('https://google.com/api/upload', {
                method: 'POST',
                credentials: 'include',
                mode: 'cors',
                headers: {
                  'Content-Type': req.headers['content-type'] ?? 'multipart/form-data',
                  'User-Agent': req.headers['user-agent'] ?? '',
                  Authorization: 'Bearer Token',
                },
                // concatination of array of Buffers and store it to body
                body: Buffer.concat(buffers),
              });
              const body = await result.json();
              setCookies(res, result.headers);
              res.status(result.status).json(body);
              return;
            } catch (error) {
              res.status(500).json(error);
            }
    
          res.status(405);
          res.send('Method Not Allowed');
        });
    };
    export default handler;