0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-04-08 02:52:39 -05:00

Merged our two maintenance middleware into one

- Reduced our maintenance middleware code down to the bare minimum!
  - We have an old maintenance middleware in place to handle when a site is forcibly put into maintenance mode, or the urlService hasn't finished booting
    - This maintenance middleware was mounted on every sub app, instead of globally for reasons I no longer remember
  - Recently, we introduced a new, static version of maintenence middleware to show during the boot process so we can get the server started earlier & not drop requests
    - This version has its own HTML template and doesn't depend on any of Ghost's error rendering code
  - To simplify and help with decoupling, this commit merges the two middleware, so that the new independent & static middleware renders its template for any one of the 3 possible maintenance modes
    - It only needs to exist in the top level app 🙌

TODO: move the maintenance middleware to its own file/package so it's not part of the app.js as that is weird
This commit is contained in:
Hannah Wolfe 2021-11-24 09:02:59 +00:00
parent 45b0b907e5
commit f417c4c732
No known key found for this signature in database
GPG key ID: AB586C3B5AE5C037
14 changed files with 14 additions and 63 deletions

View file

@ -1,14 +1,25 @@
const sentry = require('./shared/sentry');
const express = require('./shared/express');
const config = require('./shared/config');
const urlService = require('./server/services/url');
const fs = require('fs');
const path = require('path');
const isMaintenanceModeEnabled = (req) => {
if (req.app.get('maintenance') || config.get('maintenance').enabled || !urlService.hasFinished()) {
return true;
}
return false;
};
// We never want middleware functions to be anonymous
const maintenanceMiddleware = (req, res, next) => {
if (!req.app.get('maintenance')) {
if (!isMaintenanceModeEnabled(req)) {
return next();
}
res.set({
'Cache-Control': 'no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0'
});

View file

@ -96,8 +96,8 @@ async function initCore({ghostServer, config, bootLogger, frontend}) {
debug('Begin: Url Service');
const urlService = require('./server/services/url');
// Note: there is no await here, we do not wait for the url service to finish
// We can return, but the site will remain in (the shared, not global) maintenance mode until this finishes
// This is managed on request: https://github.com/TryGhost/Ghost/blob/main/core/server/web/shared/middleware/maintenance.js#L13
// We can return, but the site will remain in maintenance mode until this finishes
// This is managed on request: https://github.com/TryGhost/Ghost/blob/main/core/app.js#L10
urlService.init({
onFinished: () => {
bootLogger.log('URL Service Ready');

View file

@ -153,9 +153,6 @@ module.exports = function setupSiteApp(options = {}) {
sitemapHandler(siteApp);
debug('Internal apps done');
// send 503 error page in case of maintenance
siteApp.use(shared.middleware.maintenance);
// Add in all trailing slashes & remove uppercase
// must happen AFTER asset loading and BEFORE routing
siteApp.use(shared.middleware.prettyUrls);

View file

@ -26,9 +26,6 @@ module.exports = function setupAdminApp() {
});
}
// Render error page in case of maintenance
adminApp.use(shared.middleware.maintenance);
// Force SSL if required
// must happen AFTER asset loading and BEFORE routing
adminApp.use(shared.middleware.urlRedirects.adminSSLAndHostRedirect);

View file

@ -19,9 +19,6 @@ module.exports = function setupApiApp() {
// Query parsing
apiApp.use(boolParser());
// send 503 json response in case of maintenance
apiApp.use(shared.middleware.maintenance);
// Check version matches for API requests, depends on res.locals.safeVersion being set
// Therefore must come after themeHandler.ghostLocals, for now
apiApp.use(apiMw.versionMatch);

View file

@ -17,9 +17,6 @@ module.exports = function setupApiApp() {
// Query parsing
apiApp.use(boolParser());
// send 503 json response in case of maintenance
apiApp.use(shared.middleware.maintenance);
// API shouldn't be cached
apiApp.use(shared.middleware.cacheControl('private'));

View file

@ -19,9 +19,6 @@ module.exports = function setupApiApp() {
// Query parsing
apiApp.use(boolParser());
// send 503 json response in case of maintenance
apiApp.use(shared.middleware.maintenance);
// Check version matches for API requests, depends on res.locals.safeVersion being set
// Therefore must come after themeHandler.ghostLocals, for now
apiApp.use(apiMw.versionMatch);

View file

@ -17,9 +17,6 @@ module.exports = function setupApiApp() {
// Query parsing
apiApp.use(boolParser());
// send 503 json response in case of maintenance
apiApp.use(shared.middleware.maintenance);
// API shouldn't be cached
apiApp.use(shared.middleware.cacheControl('private'));

View file

@ -19,9 +19,6 @@ module.exports = function setupApiApp() {
// Query parsing
apiApp.use(boolParser());
// send 503 json response in case of maintenance
apiApp.use(shared.middleware.maintenance);
// Check version matches for API requests, depends on res.locals.safeVersion being set
// Therefore must come after themeHandler.ghostLocals, for now
apiApp.use(apiMw.versionMatch);

View file

@ -17,9 +17,6 @@ module.exports = function setupApiApp() {
// Query parsing
apiApp.use(boolParser());
// send 503 json response in case of maintenance
apiApp.use(shared.middleware.maintenance);
// API shouldn't be cached
apiApp.use(shared.middleware.cacheControl('private'));

View file

@ -13,9 +13,6 @@ module.exports = function setupMembersApp() {
debug('Members App setup start');
const membersApp = express('members');
// send 503 json response in case of maintenance
membersApp.use(shared.middleware.maintenance);
// Members API shouldn't be cached
membersApp.use(shared.middleware.cacheControl('private'));

View file

@ -2,7 +2,6 @@ const debug = require('@tryghost/debug')('web:oauth:app');
const {URL} = require('url');
const express = require('../../../shared/express');
const urlUtils = require('../../../shared/url-utils');
const shared = require('../shared');
const settingsCache = require('../../../shared/settings-cache');
const models = require('../../models');
const auth = require('../../services/auth');
@ -24,9 +23,6 @@ module.exports = function setupOAuthApp() {
}
oauthApp.use(labsMiddleware);
// send 503 json response in case of maintenance
oauthApp.use(shared.middleware.maintenance);
/**
* Configure the passport.authenticate middleware
* We need to configure it on each request because clientId and secret

View file

@ -15,10 +15,6 @@ module.exports = {
return require('./error-handler');
},
get maintenance() {
return require('./maintenance');
},
get prettyUrls() {
return require('./pretty-urls');
},

View file

@ -1,25 +0,0 @@
const errors = require('@tryghost/errors');
const config = require('../../../../shared/config');
const tpl = require('@tryghost/tpl');
const urlService = require('../../../services/url');
const messages = {
maintenance: 'Site is currently undergoing maintenance, please wait a moment then retry.',
maintenanceUrlService: 'Site is starting up, please wait a moment then retry.'
};
module.exports = function maintenance(req, res, next) {
if (config.get('maintenance').enabled) {
return next(new errors.MaintenanceError({
message: tpl(messages.maintenance)
}));
}
if (!urlService.hasFinished()) {
return next(new errors.MaintenanceError({
message: tpl(messages.maintenanceUrlService)
}));
}
next();
};