Nodejs - Proxy multiple applications to a single url locally - node.js

I'd like to have multiple nodejs applications all listening on different ports proxied to a URL on my local machine.
An example would be
localhost:3000 -> mysite.dev
localhost:3030 -> mysite.dev/api
It would make developing locally match my production setup and help immensely with my stateless authentication setep. I thought hotel was going to be the solution I wanted, but it doesn't do exactly what I'm looking for.
If possible I'd like to avoid using nginx locally.

You can try http-proxy module and you can specify proxy as
var http = require('http'),
httpProxy = require('http-proxy');
//
// Create your proxy server and set the target in the options.
//
httpProxy.createProxyServer({target:'http://localhost:9000'}).listen(8000); // See (†)
//
// Create your target server
//
http.createServer(function (req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.write('request successfully proxied!' + '\n' + JSON.stringify(req.headers, true, 2));
res.end();
}).listen(9000);
they have nice docs available here https://github.com/nodejitsu/node-http-proxy

Related

Node Proxy - Proxy a SSL localhost target from a basic http server

What I am trying to do:
Proxy a java api that runs on https://127.0.0.1:443/api/ along side my UI that runs on non-SSL http://127.0.0.1:1337/ in order to circumnavigate some CORS issues.
My attempt:
Proxy the api at the SSL port 443 to my non-SSL development port of 1338.
proxy my UI to 1337
Proxy 1137 to :8080/index.html and proxy 1338 to :8080/api/
Access my app from localhost:8080
My problem:
The UI comes in just fine... but I can not hit the API at :8080/api/httpSession/init
Yes, I can still hit the API at https://localhost/api/httpSession/init
api.js - Renders index.html at :1337
var app = express();
app.all('*', function (req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
});
var options = {
changeOrigin: true,
target: {
https: true
}
};
httpProxy.createServer(443, '127.0.0.1', options).listen(1338);
start.js - Proxies 1337 and 1338 into 8080
// First I start my two servers
uiServer.start(); // renders index.html at 1337
apiServer.start(); //
// I attempt to patch them back into one single non-SSL port.
app
.use('/', proxy({target: 'http://localhost:1337/'}))
.all('/api/*', proxy({target: 'http://localhost:1338/'}))
.listen(8080, function () {
console.log('PROXY SERVER listening at http://localhost:%s', 8080);
});
What you're looking for is request piping. Try this example:
// Make sure request is in your package.json
// if not, npm install --save request
var request = require('request');
// Intercept all routes to /api/...
app.all('/api/*', function (req, res) {
// Get the original url, it's a fully qualified path
var apiPath = req.originalUrl;
// Form the proxied URL to your java API
var url = 'https://127.0.0.1' + apiPath;
// Fire off the request, and pipe the response
// to the res handler
request.get(url).pipe(res);
});
Make sure to add some error handling if the api can't be reached, such as this SO solution.
For the proxy issue, my guess is that it is keeping the /api/* in the url and that's not present on the router in your API service. You could try adding /api to the router in the API service since it's going to keep the url string the same when it sends it. Otherwise, you likely need to proxy and rewrite the url so that the API will match the request to a route.
On another note, what about just installing the cors module and using in the app? I do something similar and it's working well without all the proxy items. https://www.npmjs.com/package/cors

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.

proxying requests from a secure application

im trying to proxy requests from a secure web application(https) in node (its an internal application) and im not quite sure how to do it...
the below is my code which works when i try it from an non secured app (http).
It just strips out a page name and uses it in another app. I read the docs but still not sure how to do it. Do i need to have the ssl info from my application for this to work?
var http = require('http');
var httpProxy = require('http-proxy');
var request = require('request');
var app = require('express.io')();
app.http().io();
//
// Create proxy server
//
var proxy = httpProxy.createProxyServer({target:'http://localhost:9000'}).listen(9085);
// Send the client html.
app.get('/', function(req, res) {
res.sendfile(__dirname + '/client1.html');
})
proxy.on('error', function (err, req, res) {
res.writeHead(500, {
'Content-Type': 'text/plain'
});
res.end('Something went wrong!');
});
app.all('/Domain/*', function(req, res) {
console.log(req.url);
if (req.url.indexOf("Page.do") > -1) {
// URL to Atlas
var otherAppURL = "http://myotherapp/pages/";
var temp = req.url.split("Page.do")[0].split("/");
var pageName = temp[temp.length - 1];;
app.io.broadcast('update', {
url: atlasURL + pageName + '.html'
});
};
// This doesnt work
//var url = "https://mysecureapp:9044" + req.url;
// This works
var url = "http://localhost:9080" + req.url;
req.pipe(request(url)).pipe(res);
})
app.listen(9000);
Yes, you do need an SSL Certificate for an HTTPS connection. According to the website https://www.globalsign.com/en/ssl-information-center/what-is-an-ssl-certificate/ :
The standard HTTP is changed to HTTPS, automatically telling the browser that the connection between the server and the browser must be secured using SSL.
This means that with an HTTPS connection, you need to have the server secured with SSL.
For connecting with HTTPS in Node, this website might help you:
http://gaboesquivel.com/blog/2014/nodejs-https-and-ssl-certificate-for-development/
Ok i might be mistaking but this line doesn't make sense ,
req.pipe(request(url)).pipe(res);
by the time the route handler hits, the req object is ready
so req.pipe has no meaning.
please check that url returns a valid response
request(url).pipe(res); should work
http / https is not an issue

Ajax request from another domain using AngularJs

I'm using this book to learn AngularJS where I build this webapp with Angular, Node, Deployd. Now, my app stays at localhost:5000/app.html, 5000 is the port where node web server listen. I try to retrieve my data stored with deployd in this way:
$http.get("localhost:5500/products")
.success(function (data) {
$scope.data.products = data;
})
.error(function (error) {
$scope.data.error = error;
});
But this cause an error: no 'Access-Control-Allow-Origin' header is present on the requested resource. How can I solve this? Thanks :)
Kevin B is right. It's the Same Origin Policy blocking your request.
What you should do here is to direct your requests from the client to your node server ("/products"). Here, you can easily proxy them to localhost:5500, e.g. using node-http-proxy (https://github.com/nodejitsu/node-http-proxy).
From the node-http-proxy README.md (adapted the host/port to your use-case):
var httpProxy = require('http-proxy');
var proxy = httpProxy.createProxyServer(options);
require('http').createServer(function(req, res) {
proxy.web(req, res, { target: 'http://localhost:5500' });
});
It might be, that this interferes with your current node server (serving you the client-side angular code in the first place). In case you're using Express for this, you can combine "http" and "http-proxy" like this: https://stackoverflow.com/a/22244101/3651406

Node.js Http-proxy How to pass information to target server

I am building a web application using node.js and I need to proxy certain routes to another Node.js (express) server
I have the below code
var express = require('express'),
http=require('http'),
httpProxy = require('http-proxy'),
proxy = new httpProxy.RoutingProxy();
var server = express();
server.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
server.use(express.logger());
server.use(express.cookieParser());
server.use(express.query());
server.use(express.session({secret:"secret-key", maxAge:10*60*1000}));
server.use(routeRequest);
var routeRequest = function (req, res, next) {
req.url=req.url.substring(1);
if (req.url.indexOf("client")==0) {
proxyToClientServer(9001,req,res)
}else{
res.writeHead(404, { 'Content-Type': 'text/plain' });
res.end();
}
}
var proxyToClientServer=function(port, req, res){
req.headers["data_context"]='customer_details';
proxy.proxyRequest(req, res, {
host: 'localhost',
port: port,
headers:req.headers
})
}
server.listen(8000);
My problem is the request gets routed properly, but the data context (custom header) i added is removed from the request at the target server
Can somebody please advice how to pass more information to the server thats is being proxied
As robertklep mentioned, the code was working , I was looking at the wrong place.
But one thing to remember is that we could only add Strings. Any objects I added was gone but I had to JSON.stringify(obj) and add to header to make it go through.
Objects that could not be stringified (like socket handles) could not be passed along.

Resources