path based proxy with http-proxy nodejs - node.js

I want a proxy with path based routing.
But my code not working
var httpProxy = require('http-proxy')
var proxy = httpProxy.createProxy();
var options = {
'example.com/app1': 'http://localhost:4444',
'example.com/app2': 'http://localhost:3333'
}
require('http').createServer(function(req, res) {
proxy.web(req, res, {
target: options[req.headers.host]
},function(error) {
});
}).listen(80);
How is the problem?
Thanks for Help

You might want to try express-http-proxy which let you mount the proxy on a express route:
app.use('/app1/', proxy('http://localhost:4444', {
forwardPath: function(req, res){
return url.parse(req.url).path.replace(/\/app1/,'/');
}
})
);
Even though you asked for a node.js solution, I can't really suggest to go with this route (no pun intended).
You're probably better off with something which have been tested more with this specific use case - like nginx:
location /app1/ {
proxy_pass http://localhost:4444;
}

the latest version of http-proxy dropped the proxytable feature. see https://github.com/nodejitsu/node-http-proxy/blob/master/UPGRADING.md
the version 0.8.x can do path based routing. And for current http-proxy, a middleware can do proxytable for it (https://github.com/dominictarr/proxy-by-url)

Related

http-proxy Error: Must provide a proper URL as target

This is my first attempt at http-proxy. I am getting the error:
Error: Must provide a proper URL as target
Code:
httpProxy = require('http-proxy');
httpProxy.createServer(function(req, res) {
proxy.web(req, res, { target: 'http://127.0.0.1:10002' });
}).listen(3001);
I know from curl my website is running on port 10002.
What does a properly URL look like? Or is this error actually mean something completely different? Port 10002 is not accessible outside of the box, I am testing this over the Internet.
You need to create the server with the http module, not http-server.
Replace httpProxy.createServer with require('http').createServer :
const httpProxy = require('http-proxy')
const proxy = httpProxy.createProxyServer({}) // I added this line to make this full snippet working
require('http').createServer(function (req, res) {
proxy.web(req, res, { target: 'http://127.0.0.1:10002' })
}).listen(3001)

Heroku nodejs- redirect HTTP to HTTPS

I am working on Progressive Web App and when testing it with Lighthouse I get:
Does not redirect HTTP traffic to HTTPS
My server is in nodejs and it is on Heroku. I was trying to add this code:
app.get('*',function(req,res,next){
if(req.headers['x-forwarded-proto']!='https'){
res.redirect(`https://${req.header('host')}${req.url}`)
}else{
next()
}
})
But it didn't help. Any ideas how to solve that?
You want to enforce this on the server, and the easiest way to do that is to use the express-sslify module. From the documents:
var express = require('express');
var http = require('http');
var enforce = require('express-sslify');
var app = express();
// Use enforce.HTTPS({ trustProtoHeader: true }) since you're behind Heroku's reverse proxy
app.use(enforce.HTTPS({ trustProtoHeader: true }));
// The rest of your express config.
Note also that you want to employ app.use() as I did, rather than app.get() as you did in order to make sure you're covering all requests to your app, not just GETs.
listen on port 80 and redirect to https
var http = require('http');
var server = http.createServer((req, res) => {
res.writeHead(301,{Location: `https://${req.headers.host}${req.url}`});
res.end();
});
server.listen(80);
Why not check req.protocol?
app.get('*',function(req,res,next){
if(req.protocol !== 'https'){
res.redirect(`https://${req.header('host')}${req.url}`)
}else{
next()
}
})
Another solution I have been using with no apparent drawbacks is to use the node package ssl-express-www, and that is assuming you are using Express which it looks like you are.
The code is extremely simple:
First install the package npm i ssl-express-www
Then in your server file:
const secure = require("ssl-express-www")
const app = express();
app.use(secure)
That's literally it! Put that code at the top before your route handlers and it will do all the 'heavy-lifting' for you.
I found the solution. As I was using React, I just created file, on client side, called static.json in the main folder, and added that:
{
"root": "build/",
"https_only": true,
"headers": {
"/**": {
"Strict-Transport-Security": "max-age=7776000"
}
}
}

nodejs reverse proxy instead of nginx as reverse proxy

I'm developing a web application using nodejs and I need a reverse proxy for this application.
In many places it is noticed that nginx is used as a reverse proxy.
My questions are
1. "Is there any ready made nodejs based reverse proxy?"
2. "Is it a good idea to implement a nodejs based reverser proxy?"
3. "It is advised to use nginx?"
4. Why is nginx is considered in first place for reverse proxy?
--Ganesh
use following command to install Express.js and http-proxy.
npm install --save express http-proxy
In order to run the reverse proxy server we need some resource server from which Proxy will fetch data.So to do that, develop three Express server running on Port 8000,8001,8002 respectively.
Server.js
var express = require("express");
var app = express();
app.get('/app1',function(req,res) {
res.send("Hello world From Server 1");
});
app.listen(8000);
write the same code for other servers too and change the text.
Example of proxy server code in express.js with multiple targets.
app.js (file)
var express = require('express');
var app = express();
var httpProxy = require('http-proxy');
var apiProxy = httpProxy.createProxyServer();
var serverOne = 'http://localhost:8000',
ServerTwo = 'http://localhost:8001',
ServerThree = 'http://localhost:8002';
app.all("/app1/*", function(req, res) {
console.log('redirecting to Server1');
apiProxy.web(req, res, {target: serverOne});
});
app.all("/app2/*", function(req, res) {
console.log('redirecting to Server2');
apiProxy.web(req, res, {target: ServerTwo});
});
app.all("/app2/*", function(req, res) {
console.log('redirecting to Server3');
apiProxy.web(req, res, {target: ServerThree});
});
app.listen(8000);
You can add as many targets as you want and it will create a proxy for that.Check whether its working or not by first run all the servers and hit request to /app1 and /app2 etc.
I found the DProx node plugin an absolute must. Allows for most of the configuration that one would need from a Reverse proxy server, while making it simple JSON config.

How to proxy to root path with node http-proxy

I am trying to setup a proxy with an express app to a root path from a specific path in my application:
http://my-domain.com/some/route --> http://another-domain:8000/
I have tried multiple things per the http-proxy docs but I keep hitting a wall with the paths/routing. I am trying to do this within a logged in express app so that I can utilize my authentication behind the app i'm trying to proxy too. I keep getting an error with the proxy'd app saying the path '/some/route' is not defined...etc.
var httpProxy = require('http-proxy');
var proxy = httpProxy.createProxyServer({});
proxy.proxyRequest(req, res, {
host:'localhost',
port:8000
});
I've also tried:
var url = 'http://localhost:8000/';
var httpProxy = require('http-proxy'),
proxy = httpProxy.createProxyServer({});
proxy.web(req,res, { target: url }, function(e) {
console.log('proxy.web callback');
console.log(e);
});
The function calls but I end up with an express 404 error...
I would also like to pass in some variables if that is possible so for example:
http://my-domain.com/some/route?var1=something&var2=something --> http://another-domain:8000/?var1=something&var2=something
But could not figure out if that was possible, I tried setting it on the request since that was being sent into the proxyRequest, but was unable to find them in the second application.
No, you can't do this with just node-http-proxy.
But it's possible with http-proxy-middleware (and you likely use it already):
From comment by #chimurai on github:
You can rewrite paths with the pathRewrite option.
var options = {
target: 'http://test.com',
changeOrigin: true,
pathRewrite: {'^/api' : ''} // <-- this will remove the /api prefix
};
server.middleware = proxyMiddleware('/api', options);
And if you come here because you're using webpack-dev-server, note that it also internally uses http-proxy-middleware, starting from version 2.0.0-beta (see PR).
Side note: There is also a node-proxy plugin, http-proxy-rules, so you can use this one if you don't want middleware.
Well, I encounter another problem, but needed to solve this problem first. I came up with this code, which worked fine for me ;)
Just use this for "/some/route"
.... // your stuff
httpProxy.on('error', function (err, req, res) {
res.writeHead(500, {
'Content-Type': 'text/plain'
});
res.end('some error');
});
app.all( '/some/route/*' , function( req , res ) {
var url = req.url;
url = url.slice(11); // to remove "/some/route"
req.url = url;
return httpProxy.web(req, res , { target: "http://another-domain:8000" } );
} );
hope this helps.

Node.js changin the pathname of a http-proxy request

I'm using the RoutingProxy class (found in the http-proxy package) to proxy certain requests in my node app. I'm having difficulty, however, in adding a prefix to the target path. For example, I'm trying to proxy http://localhost:8080/stylesheets/main.css to http://172.30.6.11:51161/mysite/stylesheets/main.css.
Here's a dumb example of what I'm trying to do:
// controllers/proxy.js
var httpProxy = require('http-proxy');
exports.request = function(options){
var proxy = new httpProxy.RoutingProxy();
return function(req, res){
req.url = '/mysite' + req.url;
proxy.proxyRequest(req, res, options);
};
};
// app.js
// ...
var controllers = require('./controllers');
app.use(controllers.proxy.request({
target: {
host: '172.30.6.11',
port: 55161
}
});
// ...
Unfortunately the prefix is never added when calling the target. Does anyone have any idea on how I can make this happen?
Normally we don't use http-proxy with express, but with http.createServer. But here is a workaround in the below comments of this issue

Resources