diff --git a/index.js b/index.js index 4f662df..10dc566 100644 --- a/index.js +++ b/index.js @@ -1,94 +1,98 @@ -'use strict'; +"use strict"; module.exports = function (opts) { - var escapeHtml = require('escape-html'); + var escapeHtml = require("escape-html"); - if (!opts) { - opts = {}; - } - if (!isFinite(opts.port)) { - opts.port = 443; - } - if (!opts.browsers) { - opts.browsers = 301; - } - if (!opts.apis) { - opts.apis = 'meta'; - } - if (!Array.isArray(opts.paths)) { - opts.paths = [ { match: '/' } ]; - } - if (!('body' in opts)) { - opts.body = ""; - } - opts.body = opts.body.replace(/{{\s+PORT\s+}}/ig, opts.port); - - return function (req, res, next) { - if (req.connection.encrypted - || 'https' === req.protocol - || (opts.trustProxy && 'https' === req.headers['x-forwarded-proto']) - ) { - next(); - return; + if (!opts) { + opts = {}; } - - var url = (req.originalUrl || req.url); - // We don't want chrome showing the "Not Secure" badge during the redirect. - var probablyBrowser = (0 === (req.headers['user-agent']||'').indexOf('Mozilla/')); - // But we don't want devs, APIs, or Bots to accidentally browse insecure. - var redirect = probablyBrowser ? opts.browsers : opts.apis; - var host = req.headers.host || ''; - if (!/:\d+/.test(host) && 443 !== opts.port) { - // we are using standard port 80, but we aren't using standard port 443 - host += ':80'; - } - var newLocation = 'https://' - + host.replace(/:\d+/, ':' + opts.port) + url - ; - - //var encodedLocation = encodeURI(newLocation); - var escapedLocation = escapeHtml(newLocation); - var decodedLocation; - try { - decodedLocation = decodeURIComponent(newLocation); - } catch(e) { - decodedLocation = newLocation; // "#/error/?error_message=" + e.toString(); + if (!isFinite(opts.port)) { + opts.port = 443; } - - var body = opts.body - .replace(/{{\s*HTML_URL\s*}}/ig, escapeHtml(decodedLocation)) - .replace(/{{\s*URL\s*}}/ig, escapedLocation) - .replace(/{{\s*UNSAFE_URL\s*}}/ig, newLocation) - ; - - var metaRedirect = '' - + '' - + '\n
' - + '\n' + body + '' - + '\n\n' - ; - var pathMatch; - - opts.paths.some(function (p) { - if (!p.match) { - // ignore - } else if ('string' === typeof p.match) { - pathMatch = (url === p.match) && (p.redirect || 301); - } else { - pathMatch = p.match.test && p.match.test(url) && (p.redirect || 301); - } - if (pathMatch) { - redirect = pathMatch; - } - return pathMatch; - }); - // If it's not a non-0 number (because null is 0) then 'meta' is assumed. - if (redirect && isFinite(redirect)) { - res.statusCode = redirect; - res.setHeader('Location', newLocation); + if (!opts.browsers) { + opts.browsers = 301; } - res.setHeader('Content-Type', 'text/html; charset=utf-8'); - res.end(metaRedirect); - }; + if (!opts.apis) { + opts.apis = "meta"; + } + if (!Array.isArray(opts.paths)) { + opts.paths = [{ match: "/" }]; + } + if (!("body" in opts)) { + opts.body = + ""; + } + opts.body = opts.body.replace(/{{\s+PORT\s+}}/gi, opts.port); + + return function (req, res, next) { + if ( + req.connection.encrypted || + "https" === req.protocol || + (opts.trustProxy && "https" === req.headers["x-forwarded-proto"]) + ) { + next(); + return; + } + + var url = req.originalUrl || req.url; + // We don't want chrome showing the "Not Secure" badge during the redirect. + var probablyBrowser = + 0 === (req.headers["user-agent"] || "").indexOf("Mozilla/"); + // But we don't want devs, APIs, or Bots to accidentally browse insecure. + var redirect = probablyBrowser ? opts.browsers : opts.apis; + var host = req.headers.host || ""; + if (!/:\d+/.test(host) && 443 !== opts.port) { + // we are using standard port 80, but we aren't using standard port 443 + host += ":80"; + } + var newLocation = + "https://" + host.replace(/:\d+/, ":" + opts.port) + url; + //var encodedLocation = encodeURI(newLocation); + var escapedLocation = escapeHtml(newLocation); + var decodedLocation; + try { + decodedLocation = decodeURIComponent(newLocation); + } catch (e) { + decodedLocation = newLocation; // "#/error/?error_message=" + e.toString(); + } + + var body = opts.body + .replace(/{{\s*HTML_URL\s*}}/gi, escapeHtml(decodedLocation)) + .replace(/{{\s*URL\s*}}/gi, escapedLocation) + .replace(/{{\s*UNSAFE_URL\s*}}/gi, newLocation); + var metaRedirect = + "" + + "" + + '\n" + + "\n" + + body + + "" + + "\n\n"; + var pathMatch; + + opts.paths.some(function (p) { + if (!p.match) { + // ignore + } else if ("string" === typeof p.match) { + pathMatch = url === p.match && (p.redirect || 301); + } else { + pathMatch = + p.match.test && p.match.test(url) && (p.redirect || 301); + } + if (pathMatch) { + redirect = pathMatch; + } + return pathMatch; + }); + // If it's not a non-0 number (because null is 0) then 'meta' is assumed. + if (redirect && isFinite(redirect)) { + res.statusCode = redirect; + res.setHeader("Location", newLocation); + } + res.setHeader("Content-Type", "text/html; charset=utf-8"); + res.end(metaRedirect); + }; };