Is it possible to render another express application from express? - node.js

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
});
});

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?

Alter hostname in Express request

Is there a way to alter the hostname for a request on an express web server? Lets say i have web server that can be hit via the following urls:
https://servername.company.location.com/login
and
https://servername/login
is there a way to route all requests that use "https://servername/login" to "https://servername.company.location.com/login" ? I know this can be done via apache with the RewriteRule and .htaccess file.
Thanks
You can use res.redirect to forward your traffic on to the new location. You can access the current path from the request object in order to append the path:
// purely an example, implementation is up to you
app.get('/login', function (req, res) {
res.redirect('https://servername.company.location.com/' + req.path);
});

URI bind Express.js

Hello I want to bind the URI of my app, for example lets imagine this scenario.
I am running express app on port 3000,
nginx on port 80, proxying requests of URI api to port 3000
And have this route on express
// Home
app.get('/', function(req, res) {
res.send('Hello!');
});
If I try access from localhost:3000 I get Hello! in my browser (that's expected),
but if I try to access from localhost/api I will get an error, of course he can't find the route I'm tryng to access.
If I change app.get to app.get('/api/... it works as expected, but this isn't what I want... I would need to prepend api in every route, there must be another way to do this, something like:
URI binding
URI filter ??
I read the documentation but can't find anything to solve my problem, and I'm thinking of doing a package that does URI bindings on express to solve this problem.
See my answer here for a solution that lets you point every request matching a leading /api to a particular express app. In the linked case, the user wanted to do some things without the leading fragment. You could leave out the app.use(app.router) for the main express app since you only care about the /api/ routes.
<snip>
var http = require('http');
var express = require('express');
var desktopApp = express();
var mobileApp = require('./mobile.js');
desktopApp.use('/mobile', mobileApp)
desktopApp.use(desktopApp.router);
</snip>
Also I am pretty sure that you can actually rewrite request.url yourself. I have never tried this so I can't promise it works! see docs http://expressjs.com/4x/api.html#req.originalUrl Also be sure to put this at the very top of your routing functions, so it is executed before any subsequent routes.
app.all('*', function(req, res, next){
req.url = req.url.replace(/^\/api/, '');
//the regex replaces leading /api with empty string
//req.originalUrl will keep the old url
next();
});

How to use AngularJS routes with Express (Node.js) when a new page is requested?

I'm using Express, which loads AngularJS from a static directory. Normally, I will request http://localhost/, in which Express serves me my index.html and all of the correct Angular files, etc. In my Angular app, I have these routes setup, which replace the content in an ng-view:
$routeProvider.when('/', {
templateUrl: '/partials/main.html',
controller: MainCtrl,
});
$routeProvider.when('/project/:projectId', {
templateUrl: '/partials/project.html',
controller: ProjectCtrl,
});
$locationProvider.html5Mode(true);
On my main page, I have a link to <a href="/project/{{project.id}}">, which will successfully load the template and direct me to http://localhost/project/3 or whatever ID I have specified. The problem is when I try to direct my browser to http://localhost/project/3 or refresh the page, the request is going to the Express/Node server, which returns Cannot GET /project/3.
How do I setup my Express routes to accommodate for this? I'm guessing it will require the use of $location in Angular (although I'd prefer to avoid the ugly ?searches and #hashes they use), but I'm clueless about how to go about setting up the Express routes to handle this.
Thanks.
with express 4, you probably want to catch all requests and redirect to angularjs index.html page.
app.use(app.router); doesn't exist anymore and res.sendfile is deprecated, use res.sendFilewith an uppercase F.
app.post('/projects/', projectController.createProject);
app.get('/projects/:id', projectController.getProject);
app.get('*', function (req, res) {
res.sendFile('/public/index.html');
});
put all your API routes before the route for every path app.get('*', function (req, res){...})
I would create a catch-all handler that runs after your regular routes that sends the necessary data.
app = express();
// your normal configuration like `app.use(express.bodyParser());` here
// ...
app.use(app.router);
app.use(function(req, res) {
// Use res.sendfile, as it streams instead of reading the file into memory.
res.sendfile(__dirname + '/public/index.html');
});
app.router is the middleware that runs all of your Express routes (like app.get and app.post); normally, Express puts this at the very end of the middleware chain automatically, but you can also add it to the chain explicitly, like we did here.
Then, if the URL isn't handled by app.router, the last middleware will send the Angular HTML view down to the client. This will happen for any URL that isn't handled by the other middleware, so your Angular app will have to handle invalid routes correctly.
I guess I should have clarified that I wasn't interested in using a template engine, but having Angular pull all of the HTML partials on it's own, Node is functioning completely as a static server here (but it won't be for the JSON API. Brian Ford shows how to do it using Jade here: http://briantford.com/blog/angular-express.html
My app is a single-page app, so I created an Express route for each possible URL pattern, and each of them does the same thing.
fs.readFile(__dirname + '/public/index.html', 'utf8', function(err, content) {
res.send(content);
});
I was assuming I would have to pass some request variables to Angular, but it looks like Angular takes care of it automatically.

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.

Resources