From ed1a42f7f35a7c6849060d9aeafc896f4a4d2dc2 Mon Sep 17 00:00:00 2001 From: Fabien O'Carroll Date: Tue, 23 Apr 2019 16:24:33 +0200 Subject: [PATCH] Exported raw middleware from serve-public-file no-issue The current public file middleware handles route matching itself, which means it is applied to express via the use method. Due to use being a "global" application of middleware, this means it is not possible to apply a labs middleware before the public file serving middleware without it affecting the entire route stack. This commit exports a piece of raw middleware that can be used with the get method of express, so that we can attach middleware beforehand. This will be used to conditionally serve the members specific public files, based on the labs flag for members. --- .../shared/middlewares/serve-public-file.js | 70 +++++++++++-------- 1 file changed, 41 insertions(+), 29 deletions(-) diff --git a/core/server/web/shared/middlewares/serve-public-file.js b/core/server/web/shared/middlewares/serve-public-file.js index 000fe791c8..f9178dcf5d 100644 --- a/core/server/web/shared/middlewares/serve-public-file.js +++ b/core/server/web/shared/middlewares/serve-public-file.js @@ -4,9 +4,7 @@ const path = require('path'); const config = require('../../../config'); const urlService = require('../../../services/url'); -// ### servePublicFile Middleware -// Handles requests to robots.txt and favicon.ico (and caches them) -function servePublicFile(file, type, maxAge) { +function createPublicFileMiddleware(file, type, maxAge) { let content; const publicFilePath = config.get('paths').publicFilePath; const filePath = file.match(/^public/) ? path.join(publicFilePath, file.replace(/^public/, '')) : path.join(publicFilePath, file); @@ -14,33 +12,45 @@ function servePublicFile(file, type, maxAge) { const apiRegex = /(\{\{api-url\}\})/g; return function servePublicFile(req, res, next) { - if (req.path === '/' + file) { - if (content) { - res.writeHead(200, content.headers); - res.end(content.body); - } else { - fs.readFile(filePath, (err, buf) => { - if (err) { - return next(err); - } - - if (type === 'text/xsl' || type === 'text/plain' || type === 'application/javascript') { - buf = buf.toString().replace(blogRegex, urlService.utils.urlFor('home', true).replace(/\/$/, '')); - buf = buf.toString().replace(apiRegex, urlService.utils.urlFor('api', {cors: true, version: 'v0.1', versionType: 'content'}, true)); - } - content = { - headers: { - 'Content-Type': type, - 'Content-Length': buf.length, - ETag: `"${crypto.createHash('md5').update(buf, 'utf8').digest('hex')}"`, - 'Cache-Control': `public, max-age=${maxAge}` - }, - body: buf - }; - res.writeHead(200, content.headers); - res.end(content.body); - }); + if (content) { + res.writeHead(200, content.headers); + return res.end(content.body); + } + fs.readFile(filePath, (err, buf) => { + if (err) { + return next(err); } + + let str = buf.toString(); + + if (type === 'text/xsl' || type === 'text/plain' || type === 'application/javascript') { + str = str.replace(blogRegex, urlService.utils.urlFor('home', true).replace(/\/$/, '')); + str = str.replace(apiRegex, urlService.utils.urlFor('api', {cors: true, version: 'v0.1', versionType: 'content'}, true)); + } + + content = { + headers: { + 'Content-Type': type, + 'Content-Length': Buffer.from(str).length, + ETag: `"${crypto.createHash('md5').update(str, 'utf8').digest('hex')}"`, + 'Cache-Control': `public, max-age=${maxAge}` + }, + body: str + }; + res.writeHead(200, content.headers); + res.end(content.body); + }); + }; +} + +// ### servePublicFile Middleware +// Handles requests to robots.txt and favicon.ico (and caches them) +function servePublicFile(file, type, maxAge) { + const publicFileMiddleware = createPublicFileMiddleware(file, type, maxAge); + + return function servePublicFile(req, res, next) { + if (req.path === '/' + file) { + return publicFileMiddleware(req, res, next); } else { return next(); } @@ -48,3 +58,5 @@ function servePublicFile(file, type, maxAge) { } module.exports = servePublicFile; +module.exports.servePublicFile = servePublicFile; +module.exports.createPublicFileMiddleware = createPublicFileMiddleware;