From dbbae2311cec70813610bc8f77b2db7c12f87e7c Mon Sep 17 00:00:00 2001 From: tigerbot Date: Thu, 18 May 2017 11:58:10 -0600 Subject: [PATCH] moved HTTP redirection to the net layer --- lib/modules/http.js | 82 ++++++++++++++++++++++++++------------------- 1 file changed, 47 insertions(+), 35 deletions(-) diff --git a/lib/modules/http.js b/lib/modules/http.js index 709bf28..5cbb5b8 100644 --- a/lib/modules/http.js +++ b/lib/modules/http.js @@ -124,36 +124,6 @@ module.exports.create = function (deps, conf, greenlockMiddleware) { res.end('Not Found'); } - function createRedirectRoute(mod) { - // Escape any characters that (can) have special meaning in regular expression - // but that aren't the special characters we have interest in. - var from = mod.from.replace(/[-\/\\^$+?.()|[\]{}]/g, '\\$&'); - // Then modify the characters we are interested in so they do what we want in - // the regular expression after being compiled. - from = from.replace(/\*/g, '(.*)'); - var fromRe = new RegExp('^' + from + '/?$'); - - return function (req, res, next) { - if (!moduleMatchesHost(req, mod)) { - next(); - return; - } - - var match = fromRe.exec(req.url); - if (!match) { - next(); - return; - } - - var to = mod.to; - match.slice(1).forEach(function (globMatch, index) { - to = to.replace(':'+(index+1), globMatch); - }); - res.writeHead(mod.status || 301, { 'Location': to }); - res.end(); - }; - } - function createStaticRoute(mod) { var getStaticApp, staticApp; if (/:hostname/.test(mod.root)) { @@ -182,13 +152,10 @@ module.exports.create = function (deps, conf, greenlockMiddleware) { } (conf.http.modules || []).forEach(function (mod) { - if (mod.name === 'redirect') { - app.use(createRedirectRoute(mod)); - } - else if (mod.name === 'static') { + if (mod.name === 'static') { app.use(createStaticRoute(mod)); } - else if (mod.name !== 'proxy') { + else if (mod.name !== 'proxy' && mod.name !== 'redirect') { console.warn('unknown HTTP module', mod); } }); @@ -295,6 +262,48 @@ module.exports.create = function (deps, conf, greenlockMiddleware) { return true; } + function checkRedirect(mod, conn, opts, headers) { + if (!moduleMatchesHost(headers, mod)) { + return false; + } + + if (!mod.fromRe || mod.fromRe.origSrc !== mod.from) { + // Escape any characters that (can) have special meaning in regular expression + // but that aren't the special characters we have interest in. + var from = mod.from.replace(/[-\/\\^$+?.()|[\]{}]/g, '\\$&'); + // Then modify the characters we are interested in so they do what we want in + // the regular expression after being compiled. + from = from.replace(/\*/g, '(.*)'); + var fromRe = new RegExp('^' + from + '/?$'); + fromRe.origSrc = mod.from; + // We don't want this property showing up in the actual config file or the API, + // so we define it this way so it's not enumberable. + Object.defineProperty(mod, 'fromRe', {value: fromRe, configurable: true}); + } + + var match = mod.fromRe.exec(headers.url); + if (!match) { + return false; + } + + var to = mod.to; + match.slice(1).forEach(function (globMatch, index) { + to = to.replace(':'+(index+1), globMatch); + }); + var status = mod.status || 301; + var code = require('http').STATUS_CODES[status] || 'Unknown'; + + conn.end([ + 'HTTP/1.1 ' + status + ' ' + code + , 'Date: ' + (new Date()).toUTCString() + , 'Location: ' + to + , 'Content-Length: 0' + , '' + , '' + ].join('\r\n')); + return true; + } + function handleConnection(conn) { var opts = conn.__opts; parseHeaders(conn, opts) @@ -307,6 +316,9 @@ module.exports.create = function (deps, conf, greenlockMiddleware) { if (mod.name === 'proxy') { return checkProxy(mod, conn, opts, headers); } + else if (mod.name === 'redirect') { + return checkRedirect(mod, conn, opts, headers); + } }); if (handled) { return;