Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to set proxy by request hostname with http-proxy-middleware and express?

I want to configure proxy with http-proxy-middleware and express . The rule is a mapping of hostname, exmaple:

http://123.com   >>  http://localhost:3000/123
http://456.com   >>  http://localhost:3000/abc

I have tried like this:

import express from 'express';
import http from 'http';
import proxy from 'http-proxy-middleware';

const app = express();

app.use( async function (req, res) {  
  let direction = 'http://localhost:3000';
  console.log('hostname: ', req.hostname);
  console.log('originalUrl: ', req.originalUrl);
  if (req.hostname == '123.com') {
    direction = `http://localhost:3000/123${req.originalUrl}`;
  }
  if (req.hostname == '456.com') {
    direction = `http://localhost:3000/abc${req.originalUrl}`;
  }

  return await proxy({ target: direction, changeOrigin: false })
});

const server = http.createServer(app);
app.set('port', '127.0.0.1');
server.listen(9999, '0.0.0.0');

but it doesn't work.

like image 596
Rife Avatar asked Mar 26 '19 11:03

Rife


People also ask

How do I use HTTP-proxy-middleware in node JS?

Create and configure a proxy middleware with: createProxyMiddleware(config) . const { createProxyMiddleware } = require('http-proxy-middleware'); const apiProxy = createProxyMiddleware({ target: 'http://www.example.org', changeOrigin: true, }); // 'apiProxy' is now ready to be used as middleware in a server.

What is the use of HTTP-proxy-middleware?

The http-proxy-middleware module does not return a promise, instead it returns an express middleware. You can use a custom filter to decide whether or not to proxy the request. You need to add the pathRewrite options in order to rewrite the url according to the current hostname.

What is Express HTTP proxy?

Express middleware to proxy request to another host and pass response back to original caller.


1 Answers

There's a couple of things you need to consider:

  • The http-proxy-middleware module does not return a promise, instead it returns an express middleware.
  • You can use a custom filter to decide whether or not to proxy the request.
  • You need to add the pathRewrite options in order to rewrite the url according to the current hostname.
  • Another option would be to use the router option. See the relevant documentation.

I wrote a quick express app to test this (note that i overwrote my hosts file with localwebapp and localwebapp2 pointing to 127.0.0.1) and it seems to work fine:

const express = require('express')
const proxy = require('http-proxy-middleware')

const app = express();
const filter = (pathname, req) => {
    if (req.hostname == 'localwebapp' || req.hostname == 'localwebapp2') {
        return true;
    }
    return false;
};

app.get('/123*', (req, res) => {
    res.send(`matched 123* route: ${req.path}`);
})

app.get('/abc*', (req, res) => {
    res.send(`matched abc* route: ${req.path}`);
})

app.get('/test', (req, res) => {
    res.send("matched non proxied route '/test'");
})

const apiProxy = proxy(filter, {
    target: 'http://localhost:3000',
    logLevel: 'debug',
    changeOrigin: true,
    pathRewrite: function (path, req) {
        if (req.hostname == 'localwebapp') {
            return `/123${req.originalUrl}`;
        }
        if (req.hostname == 'localwebapp2') {
            return `/abc${req.originalUrl}`;
        }
        return path;
    }
})
app.use(apiProxy)
app.listen(3000);
like image 119
eol Avatar answered Oct 11 '22 06:10

eol