Node express-http-proxy not routing request to server - node.js

I am trying to create and express server that reverse proxies to multiple applications. What I am running in to is that when I go to one of the routes the request never makes it to the server. Here are some code snippets of what I am doing:
let app = express();
app.use('/app2', express.static(__dirname + '/build', {
setHeaders: (res, req, path) => {
console.log(path);
metrics.httpRequestDurationMicroseconds // handles http_request_duration_ms Duration of HTTP requests in ms
.labels(req, path, res.statusCode)
.observe(10)
}
}));
When I go to localhost:5000/app2 it loads fine. Here is my proxy server:
proxyApp.use('/app2', proxy('http://localhost:5000/app2' ) );
proxyApp.use('/', proxy('http://my-site.com/'));
I am running it on port 5001. When i go to localhost:5001 my-site.com loads as expected. When I go to localhost:5001/app2 I get nothing and i see no traffic on the server.
For a little more context, I originally had app2 being served at / instead of /app2 and then I was able to make my proxy server load app2. But when I changed app2 to serve static content at /app2 it started breaking.
Anyone have any ideas on how to make this work or what is going on? It looks like the proxy wants to always send requests to / instead of /app2 no matter what I put in.
I am using express-http-proxy:1.4.0 and express:4.16.4
Any help is appreciated.

Try to use proxyReqPathResolver option
app.use('/app2', proxy("http://localhost:5000", {
proxyReqPathResolver: function (req) {
return "/app2"
},
}

Related

How to forward http/https request to socks5 in node js

The initial problem is nginx proxy_pass with a socks5 proxy?
I decided to proxy_pass to localhost with node js server. So then I need to somehow convert http/https requests to socksv5.
I have very simple node js server let's it handle simple get and post requests like
const express = require('express');
const app = express();
app.get('/', function(req,res) {
// need to forward via socks5
});
app.post('/', function(req,res) {
// need to forward via socks5
});
app.listen(3000,() => {
console.log("Started on PORT 3000");
})
There are some libraries like https://www.npmjs.com/package/socks or https://github.com/mattcg/socks5-https-client but it can only do get requests and also without handle 301 redirect response.
It seems that it's very easy and simple task but I still can not find the turnkey solution. Is there some or at least some good libraries to convert post and get (put, delete) to socks5?

Is it possible to render another express application from express?

Basically what happened was we have an app server that is running express and routes to a bunch of SPAs. This was great but then we wanted to have an app that runs its own node/express script (ghost). I can't figure out how to set the route /ghost to go to ./webapps/ghost/index.js
Is this just not possible?
You need to redirect incoming requests to the ghost express instance. I have done so in my personal site by adding a /blog route to my primary express instance and forwarding any request to it to the ghost expresss instance. Check it out here: https://github.com/evanshortiss/evanshortiss.com/blob/master/server.js
The basic gist is that you do the following:
app.use('/blog', function(req, res, next) {
// Forward this request on...
return next();
}, ghostServer.rootApp); //...but we forward it to a different express instance
If you're running both as separate processes then you could use Apache or nginx to just redirect the requests. If you absolutely must use an express application to forward requests then try the node-http-proxy module.
If you need to proxy from express you could do this using the http-proxy module by Nodejitsu:
var proxy = require('http-proxy').createProxyServer({});
app.use('/blog', function (req, res) {
// You may need to edit req.url (or similar) to strip the /blog part of the url or ghost might not recognise it
proxy.web(req, res, {
target: 'http://127.0.0.1:'+GHOST_PORT
});
});

The best deployment architecture for angularjs nodejs app

I have Moto Adverts application in angularjs and nodejs.
Angularjs-client-side is running on Apache HTTP Server (localhost:8000) but nodejs-server-side is runnning as node.js http server (localhost:3000).
Piece of client-side code (angularjs):
var motoAdsServices = angular.module('motoAdsServices', ['ngResource']);
motoAdsServices.factory('Brand', ['$resource', function($resource) {
return $resource('http://localhost\\:3000/api/:id', {}, {
query: {
method: 'GET',
params: {
id: 'brands'
},
isArray: true
}
});
}]);
Piece of server-side code (nodejs):
var express = require('express');
var path = require('path');
var http = require('http');
var brands = require('./routes/brands');
var app = express();
var allowCrossDomain = function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
next();
};
app.configure(function() {
app.set('port', process.env.PORT || 3000);
app.use(express.logger('dev')); /* 'default', 'short', 'tiny', 'dev' */
app.use(express.bodyParser()),
app.use(allowCrossDomain);
app.use(express.static(path.join(__dirname, 'public')));
});
app.get('/api/brands', brands.findAll);
http.createServer(app).listen(app.get('port'), function() {
console.log("Express server listening on port " + app.get('port'));
});
My questions are:
What I should do to run client-side and server-side on the same server.
a) On Apache HTTP Server (localhost:8000).
b) On Node.js self http server on (localhost:3000).
What architecture will be the best for production use - two independent servers for client-side and server-side or only one?
Is it good practise to use Cross-origin resource sharing (CORS) on server-side (if I should hava two independed servers)?
What I should do to not hard code address http://localhost:3000/api/brands to server-side (best practise)?
Node.js
One server will be more maintainable. To optimize you can cache static files with nginx later if you need to. (Just search 'nginx Node.js static' but it will work fine without that if you have light traffic and not a ton of static files). I would not use Apache for anything.
Here is a sample nginx config:
server {
listen 80;
server_name myserver.net;
root /mnt/app;
index index.html index.htm;
location /static/ {
try_files $uri $uri/ =404;
}
location /api/ {
proxy_pass http://127.0.0.1:8080;
}
}
You won't need CORS with one.
The ports will be the same so that isn't an issue.
I believe this is the most popular architecture for apache nodejs angularjs.
(A) in the figure.
I recommend for you to serve all files including static files via nodejs server as I wrote in my figure.
On the other hand, you could use node server only for dynamic contents and use apache to serve static files including your client side codes if you like.
But if you do so, you need apache server ALWAYS even when you develop your application. I feel that will be troublesome.
(B) in the figure.
You can serve your client side codes including other static files by locating them in public directory.
If you decide to serve all files from nodejs server, you can develop without apache and avoid to write specific port number in your code.
I think your application code should not be conscious about the port number you will use.
I hope this could be answer for your all questions.
What I should do to run client-side and server-side on the same server. a) On Apache HTTP Server (localhost:8000). b) On Node.js self http server on (localhost:3000).
Ans : you don't need to run nodejs as self hosted.instead run nodejs through Apache server and use fusion passenger too. fusion passenger will take care of running your node application in background forever. Personally I prefer Nginx + fusion for my nodejs applications.
What architecture will be the best for production use - two independent servers for client-side and server-side or only one?
Ans : I don't understand what you mean by having two servers one for client and one for server-side. Keep your client and server code on single server.
Is it good practice to use Cross-origin resource sharing (CORS) on server-side (if I should have two independent servers)?
Ans : if your server and your client are under same domain then you don't need to worry about CORS but if in future you want to expose your API to any of your client apps, then you will need to do CORS configurations.
What I should do to not hard code address http://localhost:3000/api/brands to server-side (best practice)?
Ans : I use constant to declare my base path and then do the DI in my services and factory that make the API Calls.
motoAdsServices.constant("API", {
"endpoint": "http://localhost:8080",
})
motoAdsServices.factory('Brand', ['$resource','API', function($resource,API) {
return $resource(API.endpoint + '/api/:id', {}, {
query: {
method: 'GET',
params: {
id: 'brands'
},
isArray: true
}
});
}]);

how can I check that a request is coming over https in express

I want force certain routes to always use a secure connection in my express app. How can I check to make sure it is using https?
I am using piggyback ssl on heroku for my deployments.
I deploy on Heroku as well. They add a bunch of their headers when they use nginx to reverse proxy. The one of interest in this case would be x-forwarded-proto.
This is what I did:
app.get(/\/register$/, function(req, res){
console.log(JSON.stringify(req.headers)); //to see all headers that heroku adds
if(req.headers['x-forwarded-proto'] && req.headers['x-forwarded-proto'] === "http") {
res.redirect("https://" + req.headers.host + req.url);
}
else {
//the rest of your logic to handle this route
}
});
app.enable('trust proxy');
"Using Express behind a reverse proxy such as Varnish or Nginx is trivial, however it does require configuration. By enabling the "trust proxy" setting via app.enable('trust proxy'), Express will have knowledge that it's sitting behind a proxy and that the X-Forwarded-* header fields may be trusted, which otherwise may be easily spoofed."
Express behind proxies doco
In order to run a secure server (https) it would have to be created independently from a non-secure server (http). They would also listen on separate ports. Try something like this:
var express = require('express)
, app_insecure = express.createServer()
, app_secure = express.createServer({ key: 'mysecurekey' })
app_insecure.get('/secure-page',function(req, res){
// This is an insecure page, redirect to secure
res.redirect('https://www.mysecuresite.com/secure-page')
})
app_secure.get('/secure-page', function(req,res){
// Now we're on a secure page
})
app_insecure.listen(80)
app_secure.listen(443)
OR this could be implemented as route middleware
var redirect_secure = function(req, res, next){
res.redirect('https://mysite.com' + req.url)
}
app_insecure.get('/secure-page',redirect_secure,function(req, res){})
Now you would only have to include the function reference: redirect_secure() on the paths that you would like redirected to a secure location.

How to combine two Node.js App server together.

I have two apps. which current run in two different ports.
script1.js:
var express = require('express'),
app = require('express').createServer(
express.cookieParser(),
// Parses x-www-form-urlencoded request bodies (and json)
express.bodyParser()
)
;
app.get('/s1/output', function(sReq, sRes){
// set cookie
sRes.send('<div>Out from 1!</div>');
});
app.listen(3000);
and here is script2.js
var express = require('express'),
app = require('express').createServer(
express.cookieParser(),
// Parses x-www-form-urlencoded request bodies (and json)
express.bodyParser()
)
;
app.get('/s2/output', function(sReq, sRes){
// set cookie
sRes.send('<div>Out from 2!</div>');
});
app.listen(3001);
ok.. it runs separately on two different ports and have no problem.
Now. the story is that, I can only use port 80 for production. System Admin doesn't want to open 3000 nor other ports.
Instead of merging code. (in fact, my real code is a lot. and have different config settings for script1 and script2), what can I do to make both of them on port 80? but calling /s1/output will go to script1, and /s2/output will go to script2?
I am thinking about having another scripts. script80.js that runs on port 80.
and it require both script1, and script2.
But, the question is, what should I export from script 1 and script2? should I:
define all get / post methods, and then,
module.exports.app =app?
and in script80.js, should I do soemthing like that:
app.get('/s1/*', function (res, req)) {
// and what do now? app1(res) ?
}
mmmm
If you have domains or subdomains pointing to this server, you can also use the vhost middleware:
app.use(express.vhost('s1.domain.com', require('s1').app));
app.use(express.vhost('s2.domain.com', require('s2').app));
app.listen(80);
Complete example: https://github.com/expressjs/express/blob/master/examples/vhost/index.js
You can use nginx listening on port 80 and reverse proxying traffic to the 2 different express app servers behind it.
location /s1/ {
rewrite /s1(.*) $1 break;
proxy_pass http://localhost:3000;
}
location /s2/ {
rewrite /s2(.*) $1 break;
proxy_pass http://localhost:3001;
}
You could also code this by hand in express as you are asking about, but why reinvent the wheel?

Resources