moved HTTP static file detection to net layer
This commit is contained in:
parent
dbbae2311c
commit
aa28a72f3f
|
@ -2,8 +2,7 @@
|
||||||
|
|
||||||
module.exports.create = function (deps, conf, greenlockMiddleware) {
|
module.exports.create = function (deps, conf, greenlockMiddleware) {
|
||||||
var PromiseA = require('bluebird');
|
var PromiseA = require('bluebird');
|
||||||
var express = require('express');
|
var statAsync = PromiseA.promisify(require('fs').stat);
|
||||||
var app = express();
|
|
||||||
var domainMatches = require('../domain-utils').match;
|
var domainMatches = require('../domain-utils').match;
|
||||||
var separatePort = require('../domain-utils').separatePort;
|
var separatePort = require('../domain-utils').separatePort;
|
||||||
|
|
||||||
|
@ -119,51 +118,6 @@ module.exports.create = function (deps, conf, greenlockMiddleware) {
|
||||||
redirecters[host.port](req, res);
|
redirecters[host.port](req, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
function respond404(req, res) {
|
|
||||||
res.writeHead(404);
|
|
||||||
res.end('Not Found');
|
|
||||||
}
|
|
||||||
|
|
||||||
function createStaticRoute(mod) {
|
|
||||||
var getStaticApp, staticApp;
|
|
||||||
if (/:hostname/.test(mod.root)) {
|
|
||||||
staticApp = {};
|
|
||||||
getStaticApp = function (hostname) {
|
|
||||||
if (!staticApp[hostname]) {
|
|
||||||
staticApp[hostname] = express.static(mod.root.replace(':hostname', hostname));
|
|
||||||
}
|
|
||||||
return staticApp[hostname];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
staticApp = express.static(mod.root);
|
|
||||||
getStaticApp = function () {
|
|
||||||
return staticApp;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return function (req, res, next) {
|
|
||||||
if (moduleMatchesHost(req, mod)) {
|
|
||||||
getStaticApp(separatePort(req.headers.host).host)(req, res, next);
|
|
||||||
} else {
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
(conf.http.modules || []).forEach(function (mod) {
|
|
||||||
if (mod.name === 'static') {
|
|
||||||
app.use(createStaticRoute(mod));
|
|
||||||
}
|
|
||||||
else if (mod.name !== 'proxy' && mod.name !== 'redirect') {
|
|
||||||
console.warn('unknown HTTP module', mod);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.use(respond404);
|
|
||||||
|
|
||||||
var server = require('http').createServer(app);
|
|
||||||
|
|
||||||
function emitConnection(server, conn, opts) {
|
function emitConnection(server, conn, opts) {
|
||||||
server.emit('connection', conn);
|
server.emit('connection', conn);
|
||||||
|
|
||||||
|
@ -190,7 +144,6 @@ module.exports.create = function (deps, conf, greenlockMiddleware) {
|
||||||
return emitConnection(acmeServer, conn, opts);
|
return emitConnection(acmeServer, conn, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var httpsRedirectServer;
|
var httpsRedirectServer;
|
||||||
function checkHttps(conn, opts, headers) {
|
function checkHttps(conn, opts, headers) {
|
||||||
if (conf.http.allowInsecure || conn.encrypted) {
|
if (conf.http.allowInsecure || conn.encrypted) {
|
||||||
|
@ -297,6 +250,7 @@ module.exports.create = function (deps, conf, greenlockMiddleware) {
|
||||||
'HTTP/1.1 ' + status + ' ' + code
|
'HTTP/1.1 ' + status + ' ' + code
|
||||||
, 'Date: ' + (new Date()).toUTCString()
|
, 'Date: ' + (new Date()).toUTCString()
|
||||||
, 'Location: ' + to
|
, 'Location: ' + to
|
||||||
|
, 'Connection: close'
|
||||||
, 'Content-Length: 0'
|
, 'Content-Length: 0'
|
||||||
, ''
|
, ''
|
||||||
, ''
|
, ''
|
||||||
|
@ -304,6 +258,57 @@ module.exports.create = function (deps, conf, greenlockMiddleware) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var staticServer;
|
||||||
|
var staticHandlers = {};
|
||||||
|
function serveStatic(req, res) {
|
||||||
|
var rootDir = req.connection.rootDir;
|
||||||
|
|
||||||
|
if (!staticHandlers[rootDir]) {
|
||||||
|
staticHandlers[rootDir] = require('express').static(rootDir, { fallthrough: false });
|
||||||
|
}
|
||||||
|
|
||||||
|
staticHandlers[rootDir](req, res, function (err) {
|
||||||
|
if (err) {
|
||||||
|
res.statusCode = err.statusCode;
|
||||||
|
} else {
|
||||||
|
res.statusCode = 404;
|
||||||
|
}
|
||||||
|
res.setHeader('Content-Type', 'text/html');
|
||||||
|
|
||||||
|
if (res.statusCode === 404) {
|
||||||
|
res.end('File Not Found');
|
||||||
|
} else {
|
||||||
|
res.end(require('http').STATUS_CODES[res.statusCode]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function checkStatic(mod, conn, opts, headers) {
|
||||||
|
if (!moduleMatchesHost(headers, mod)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var rootDir = mod.root.replace(':hostname', separatePort(headers.host).host);
|
||||||
|
return statAsync(rootDir)
|
||||||
|
.then(function (stats) {
|
||||||
|
if (!stats || !stats.isDirectory()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!staticServer) {
|
||||||
|
staticServer = require('http').createServer(serveStatic);
|
||||||
|
}
|
||||||
|
conn.rootDir = rootDir;
|
||||||
|
return emitConnection(staticServer, conn, opts);
|
||||||
|
})
|
||||||
|
.catch(function (err) {
|
||||||
|
if (err.code !== 'ENOENT') {
|
||||||
|
console.warn('errored stating', rootDir, 'for serving static files', err);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
})
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
function handleConnection(conn) {
|
function handleConnection(conn) {
|
||||||
var opts = conn.__opts;
|
var opts = conn.__opts;
|
||||||
parseHeaders(conn, opts)
|
parseHeaders(conn, opts)
|
||||||
|
@ -312,19 +317,38 @@ module.exports.create = function (deps, conf, greenlockMiddleware) {
|
||||||
if (checkHttps(conn, opts, headers)) { return; }
|
if (checkHttps(conn, opts, headers)) { return; }
|
||||||
if (checkAdmin(conn, opts, headers)) { return; }
|
if (checkAdmin(conn, opts, headers)) { return; }
|
||||||
|
|
||||||
var handled = (conf.http.modules || []).some(function (mod) {
|
var prom = PromiseA.resolve(false);
|
||||||
|
(conf.http.modules || []).forEach(function (mod) {
|
||||||
|
prom = prom.then(function (handled) {
|
||||||
|
if (handled) {
|
||||||
|
return handled;
|
||||||
|
}
|
||||||
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') {
|
if (mod.name === 'redirect') {
|
||||||
return checkRedirect(mod, conn, opts, headers);
|
return checkRedirect(mod, conn, opts, headers);
|
||||||
}
|
}
|
||||||
});
|
if (mod.name === 'static') {
|
||||||
if (handled) {
|
return checkStatic(mod, conn, opts, headers);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
console.warn('unknown HTTP module found', mod);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
emitConnection(server, conn, opts);
|
prom.then(function (handled) {
|
||||||
|
if (!handled) {
|
||||||
|
conn.end([
|
||||||
|
'HTTP/1.1 404 Not Found'
|
||||||
|
, 'Date: ' + (new Date()).toUTCString()
|
||||||
|
, 'Content-Type: text/html'
|
||||||
|
, 'Content-Length: 9'
|
||||||
|
, 'Connection: close'
|
||||||
|
, ''
|
||||||
|
, 'Not Found'
|
||||||
|
].join('\r\n'));
|
||||||
|
}
|
||||||
|
});
|
||||||
})
|
})
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue