moved HTTP redirection to the net layer

This commit is contained in:
tigerbot 2017-05-18 11:58:10 -06:00
parent 27e818f41a
commit dbbae2311c
1 changed files with 47 additions and 35 deletions

View File

@ -124,36 +124,6 @@ module.exports.create = function (deps, conf, greenlockMiddleware) {
res.end('Not Found'); 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) { function createStaticRoute(mod) {
var getStaticApp, staticApp; var getStaticApp, staticApp;
if (/:hostname/.test(mod.root)) { if (/:hostname/.test(mod.root)) {
@ -182,13 +152,10 @@ module.exports.create = function (deps, conf, greenlockMiddleware) {
} }
(conf.http.modules || []).forEach(function (mod) { (conf.http.modules || []).forEach(function (mod) {
if (mod.name === 'redirect') { if (mod.name === 'static') {
app.use(createRedirectRoute(mod));
}
else if (mod.name === 'static') {
app.use(createStaticRoute(mod)); app.use(createStaticRoute(mod));
} }
else if (mod.name !== 'proxy') { else if (mod.name !== 'proxy' && mod.name !== 'redirect') {
console.warn('unknown HTTP module', mod); console.warn('unknown HTTP module', mod);
} }
}); });
@ -295,6 +262,48 @@ module.exports.create = function (deps, conf, greenlockMiddleware) {
return true; 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) { function handleConnection(conn) {
var opts = conn.__opts; var opts = conn.__opts;
parseHeaders(conn, opts) parseHeaders(conn, opts)
@ -307,6 +316,9 @@ module.exports.create = function (deps, conf, greenlockMiddleware) {
if (mod.name === 'proxy') { if (mod.name === 'proxy') {
return checkProxy(mod, conn, opts, headers); return checkProxy(mod, conn, opts, headers);
} }
else if (mod.name === 'redirect') {
return checkRedirect(mod, conn, opts, headers);
}
}); });
if (handled) { if (handled) {
return; return;