Skip to content

Instantly share code, notes, and snippets.

@rahuljiresal
Last active July 22, 2016 08:53
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save rahuljiresal/244f6d4dcb5f5eeb3645 to your computer and use it in GitHub Desktop.
Save rahuljiresal/244f6d4dcb5f5eeb3645 to your computer and use it in GitHub Desktop.
This is a middleware for Connect and Express that redirects any requests to a default domain. Based on https://github.com/goloroden/node-force-domain, modified to work on Openshift platform.
/*
Openshift uses haproxy (haproxy.org) as a front proxy to route request to instances of the app.
This proxy does the job of unwrapping https and sets the 'x-forwarded-proto' header.
Because of this, the Node.JS app never sees the actual protocol of the request, unless it checks the presence of this header.
I modified the code written by goloroden (https://github.com/goloroden/node-force-domain) to check this header instead of ports.
This gist does exactly what his code does, except checks for actual protocol instead of relying on the port for the protocol.
*/
var rewrite = function (route, options) {
options = _.defaults({
protocol: undefined,
hostname: undefined
}, options);
var parsedRoute = url.parse(route);
parsedRoute.host = undefined;
if (options.protocol) { parsedRoute.protocol = options.protocol; }
if (options.hostname) { parsedRoute.hostname = options.hostname; }
return url.format(parsedRoute);
};
var redirect = function (req, url, options) {
options = _.defaults(options, {
protocol: 'http',
type: 'temporary'
});
var hostHeader = req.headers.host;
var hostHeaderParts = (hostHeader || '').split(':'),
hostname = hostHeaderParts[0] || '';
var protocol = req.headers['x-forwarded-proto'];
if (
(hostname === 'localhost') ||
(hostname === options.hostname && protocol === options.protocol)
) {
return;
}
var route = options.protocol + '://' + hostname + url,
rewrittenRoute = rewrite(route, options);
return {
type: options.type,
url: rewrittenRoute
};
};
var forceDomain = function (options) {
return function (req, res, next) {
var newRoute = redirect(req, req.url, options);
if (!newRoute) {
return next();
}
var statusCode = (newRoute.type === 'permanent') ? 301 : 307;
res.writeHead(statusCode, {
'Location': newRoute.url
});
res.end();
};
};
/* This is how it should be used */
/* The following example will redirect all traffic to "https://example.com" from "http://www.example.com",
"https://www.example.com" or even any other URL pointing to the same app. */
app.use(forceDomain({
hostname: 'www.example.com',
protocol: 'https'
}));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment