Giter Site home page Giter Site logo

next-http-proxy-middleware's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

next-http-proxy-middleware's Issues

How to pass self response data with selfHandleResponse in NextJS

I want to handle the self response data (I want to do something like set a some data to cookie, etc...) in Next.js API Routes, but if I set it to true, none of the webOutgoing passes are called, that resulted in my request never being responded. What should I do?

    const handleProxyInit = (proxy) => {
        proxy.on('proxyRes', (proxyRes, req, res) => {
            let body = [];

            proxyRes.on('data', function (chunk) {
                body.push(chunk);
            });
            proxyRes.on('end', function () {
                body = Buffer.concat(body).toString('utf8');
                // do something here
            });
        });
    };

    httpProxyMiddleware(req, res, {
        ...,
        selfHandleResponse: true,
        changeOrigin: true,
        onProxyInit: handleProxyInit,
    });

Dependabot Security warning for this package.

Dependabot is triggering a warning because of this package. Please update Dependencies.

(You can activate Dependabot in the Github settings for free for your repo)

Thanks

Dependabot cannot update node-notifier to a non-vulnerable version
The latest possible version that can be installed is 6.0.0 because of the following conflicting dependency:

[email protected] requires node-notifier@^6.0.0 via a transitive dependency on @jest/[email protected]
The earliest fixed version is 8.0.1.

Target chaining

Hello,
what should one do in order to rewrite paths for different targets?

Proxy websockets

I'm trying to use this library to proxy websockets. I've tried several approaches but so far none of them are working.

import { NextApiRequest, NextApiResponse } from "next";
import httpProxyMiddleware from "next-http-proxy-middleware";

export const config = {
  api: {
    bodyParser: false,
    externalResolver: true,
  },
};

export default async (req: NextApiRequest, res: NextApiResponse) => {
  return httpProxyMiddleware(req, res, {
    target: "ws://localhost:3001/graphql",
    ws: true,
  });
};

Is it possible to do it with this library?

Can this be used in production?

Can this be used in production? We have an next.js app and a nestjs server. We have cookies running to and from both of them so different domains are a problem. This seems to fix this issue. Is this stable enough to be used in production?

Unable to use path rewrite to external endpoint.

Unable to use path rewrite to external endpoint.
using vanila http-proxy-middleware it is possible using router
https://github.com/chimurai/http-proxy-middleware/blob/c935888ea7135365bea3c4c81e4ffe48f359a670/examples/response-interceptor/index.js#L39

Pseudo code

// src/pages/api/demo.ts
export default (req: NextApiRequest, res: NextApiResponse) =>
    httpProxyMiddleware(req, res, {
        timeout: 3000,
        target: 'http://localhost:8080',
        router: {
            '/api/demo': 'https://google.com',
        },
        pathRewrite: {
            '/api/demo': '',
        },
    }).catch(async (error) => {
        res.end(error.message);
        console.log(error);
    });

As a workaround i create multiple files with different target option

memory leak?

I was using this module like so:

import httpProxyMiddleware from 'next-http-proxy-middleware';
import { NextApiRequest, NextApiResponse } from 'next';
import { getSession } from '@auth0/nextjs-auth0';
import * as Sentry from '@sentry/node';

import { initSentry } from 'src/utils/sentry';

export default async (req: NextApiRequest, res: NextApiResponse) => {
    const session = getSession(req, res);

    return new Promise((resolve) =>
        httpProxyMiddleware(req, res, {
            target: process.env.NEXT_PUBLIC_API_BASE_URL,
            headers: { Authorization: `Bearer ${session?.idToken}`, 'Content-Type': 'application/json-patch+json' },
        }).catch(async (error) => {
            initSentry();
            Sentry.captureException(error);
            await Sentry.flush(2000);

            return resolve(error);
        })
    );
};

And as you can see in memory usage graph it is spikes and some server restarts.
But when I switched to middleware like so

import { NextApiRequest, NextApiResponse } from 'next';
import { getSession } from '@auth0/nextjs-auth0';
import { createProxyMiddleware } from 'http-proxy-middleware';
import * as Sentry from '@sentry/node';

import { initSentry } from 'src/utils/sentry';

export const config = {
    api: {
        bodyParser: false,
        externalResolver: true,
    },
};

export default createProxyMiddleware({
    target: process.env.NEXT_PUBLIC_API_BASE_URL,
    headers: {
        'Content-Type': 'application/json-patch+json',
    },
    selfHandleResponse: false,
    changeOrigin: true,
    xfwd: true,
    secure: true,
    proxyTimeout: 3000,
    ws: true,
    onProxyReq: (proxyReq, req: Request & NextApiRequest, res: Response & NextApiResponse) => {
        proxyReq.setHeader('Authorization', `Bearer ${getSession(req, res)?.idToken}`);
    },
    onError: (err, req: Request & NextApiRequest, res: Response & NextApiResponse) => {
        initSentry();
        Sentry.captureException(err);
        Sentry.flush(2000);

        res.end('Something went wrong.');
    },
});

the memory usage becomes stable. Also got correct response headers from API like 404

image

Additional headers doesn't write to request

I am experiencing problem that I am not able to add any custom headers. I have made a quick look on your code and I don't see any action with headers on proxy request ...

Update documentation for multipart/form-data requests

Thanks for open sourcing this library, saved me quite some time while implementing my API proxy.

While working with multipart/form-data requests i've noticed that the Next.js bodyParser tries to parse the body, causing it to corrupt the binary content of all files in the request. Therefore (in my case) it's desired to disable the bodyParser entirely in the API route (https://nextjs.org/docs/api-routes/api-middlewares#custom-config).

export const config = {
	api: {
		bodyParser: false
	}
};

This library handles all other requests/content-types correctly. Perhaps it would be an idea to document this to safe others some time with similar issues.

httpProxyMiddleware chaining with multipel targets

It would be great to have the possibility to chain proxy middlewares like this:
httpProxyMiddleware(req, res, {
target: process.env.target1,
pathRewrite: [{
patternStr: "^/api", replaceStr: "",
}],
}).than((response)=>httpProxyMiddleware(req, response, {
target: process.env.target2,
pathRewrite: [{
patternStr: "^/s3", replaceStr: "",
}],
}))
What is the proper way of doing this?

Can I transfer cooki through next-http-proxy-middleware ?

I have already installed next-http-proxy-middleware and using it on my nextjs app to connect it to my nodejs express which is on another domain. My express API is using JWT cookie for sign in/sign out . I am trying to transfer it to front-end but no chance . Is this possible ?
This is my current setup :

import { NextApiRequest, NextApiResponse } from "next";
import httpProxyMiddleware from "next-http-proxy-middleware";
export default (req: NextApiRequest, res: NextApiResponse) =>
  httpProxyMiddleware(req, res, {
    target: "http://my-nodejs-api-example.herokuapp.com",  changeOrigin: true,
    pathRewrite: {
      "^/api/": '/api/v1/',
    },
  });

Type error: This expression is not callable.

I am getting error with my page

./pages/api/[...all].ts:13:10
Type error: This expression is not callable.
  Type 'typeof import("/Users/joeyoung/_WORKING/joegyoung/node_modules/next-http-proxy-middleware/src/index")' has no call signatures.

  11 | 		} = req;
  12 | 
> 13 | 		return httpProxyMiddleware(req, res, {
     | 		       ^
  14 | 			// You can use the `http-proxy` option
  15 | 			target: `http://localhost:9000/.netlify/functions/${all}`,
  16 | 			pathRewrite: {
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

This is the source

import { NextApiRequest, NextApiResponse } from "next";
import httpProxyMiddleware from "next-http-proxy-middleware";

const isDevelopment = process.env.NODE_ENV === "development";
const isProduction = process.env.NODE_ENV === "production";

export default (req: NextApiRequest, res: NextApiResponse) => {
	if (isDevelopment) {
		const {
			query: { all },
		} = req;

		return httpProxyMiddleware(req, res, {
			// You can use the `http-proxy` option
			target: `http://localhost:9000/.netlify/functions/${all}`,
			pathRewrite: {
				"^/api+": "",
			},
		});
	} else {
		res.status(404).send(null);
	}
};

What am I needing to do?

The README examples should include importing the middleware

The examples for using next-http-proxy-middleware should include importing (or requiring) the module. There is no indication if this is a named or default export, or if the user can use ES modules or commonJS.

Thank you for your time maintaining this project

Multiple rewrites not supported

Hi,

There's an error in the rewritePath method. It already returns after the first replacement and thus never checks other rewrites.

Example:
Wrong: rewritePath('/api/test/xy/', { '/$': '', '^/api/test/': '' }) -> /api/test/xy
Correct: rewritePath('/api/test/xy/', { '/$': '', '^/api/test/': '' }) -> xy

export const rewritePath = (
  url: string,
  pathRewrite: { [key: string]: string }
) => {
  for (let patternStr in pathRewrite) {
    const pattern = RegExp(patternStr);
    const path = pathRewrite[patternStr];
    if (pattern.test(url as string)) {
      return url.replace(pattern, path); <--- returns to early
    }
  }
  return url;
};

possible fix:

export const rewritePath = (url: string, pathRewrite: { [key: string]: string }): string => {
  let rewrittenUrl = url;
  for (let patternStr in pathRewrite) {
    const pattern = new RegExp(patternStr);
    const path = pathRewrite[patternStr];
    if (pattern.test(url as string)) {
      rewrittenUrl = rewrittenUrl.replace(pattern, path);
    }
  }
  return rewrittenUrl;
};

Eliminate slash at the end of the path

Hello,

I need help and it is that when requesting an endpoint that ends in slash (backend in Django Rest Framework) the proxy removes the slash when I put it in the fetch url.

A solution would be to remove the slash in django rest framework and set APPEND_SLASH = False but I lose the redirection when the request is made with the slash.

RuntimeError: You called this URL via POST, but the URL doesn't end in a slash and you have APPEND_SLASH set. Django can't redirect to the slash URL while maintaining POST data. Change your form to point to localhost:8000/api/auth/jwt/create/ (note the trailing slash), or set APPEND_SLASH=False in your Django settings.

Add support for custom `onProxyReq` and `onProxyRes`

I think it would be useful to add onProxyReq and onProxyRes options in the constructor function:

httpProxyMiddleware(req, res, {
      // You can use the `http-proxy` option
      target: 'https://www.example.com',
      // In addition, you can use the `pathRewrite` option provided by `next-http-proxy-middleware`
      pathRewrite: [{
        patternStr: '^/api/new',
        replaceStr: '/v2'
      }, {
        patternStr: '^/api',
        replaceStr: ''
      }],
+     onProxyReq: (proxyReq, req, res) => {...},
+     onProxyRes: (proxyRes, req, res) => {...},
    })

This will allow more fine-grained request and response rewriting.

1.1.* introduces a bug in pathRewrite option

Hi,

I was using the old signature for pathRewrite of a plan object, with the key as the test pattern & the value being the replacement string.

This was working great with v1.0.* of the library, but it seems like the new v1.1.* introduce change broke this compatiblity.

httpProxyMiddleware(req, res, {
    target: `https://${shop.name}/admin/api/2021-10/graphql.json`,
    headers: {
      "Content-Type": "application/json",
      "X-Shopify-Access-Token": shop.accessToken,
    },
    changeOrigin: true,
    ws: true,
    pathRewrite: {
      "^/api/graphql": "",
    },
  });

I attempted to use the new Array based syntax:

    pathRewrite: [{
      patternStr: "^/api/graphql",
      replaceStr: ""
    }],
  });

But the without being able to visualize the request, I'm not sure why that request is being rejected by the host.

I just know that downgrading and keeping the old signature works for my case.

Leaving this for documentation purposes, maybe I'll get around to adding a debugging mode or something to view the request's parameters easier.

ERR_STREAM_WRITE_AFTER_END

First of all: nice lib. AFAICT it's the only clean middleware out there that allows to update the request's headers with NextJS without errors.

I do encounter issues with your middleware though.

I have a fairly simple proxy setup for an API with a dynamic route (using SWR on the client side):

import type { NextApiRequest, NextApiResponse } from 'next'
import jwt from 'next-auth/jwt'
import httpProxyMiddleware from 'next-http-proxy-middleware';

export default async (req: NextApiRequest, res: NextApiResponse) => {
  const { accessToken } = await jwt.getToken({ req: req, secret: "CHANGE_ME" })
  return httpProxyMiddleware(req, res, {
    target: 'https://whatever.com',
    pathRewrite: { "^/before": '/after' },
    headers: { Authorization: `Bearer ${accessToken}` },
  })
}

When sending requests via to the proxy for with the same path, it works nicely. When requests with different paths go through the middleware, I see the following error (not right away, after a couple of minutes):

Error [ERR_STREAM_WRITE_AFTER_END]: write after end
    at new NodeError (node:internal/errors:278:15)
    at write_ (node:_http_outgoing:718:11)
    at ClientRequest.write (node:_http_outgoing:677:15)
    at ProxyServer.<anonymous> (.../next-http-proxy-middleware/build/index.js:1:2419)
    at ProxyServer.emit (.../eventemitter3/index.js:210:27)
    at ClientRequest.<anonymous> (.../http-proxy/lib/http-proxy/passes/web-incoming.js:133:16)
    at ClientRequest.emit (node:events:388:22)
    at tickOnSocket (node:_http_client:781:7)
    at onSocketNT (node:_http_client:820:5)
    at processTicksAndRejections (node:internal/process/task_queues:81:21) {
  code: 'ERR_STREAM_WRITE_AFTER_END'
}

And prior to that, NextJS's server shows this kind of warning:

[...]
API resolved without sending a response for some/target/url, this may result in stalled requests
[...]

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.