From d9bdc444a3054a1a86c3b79a2cf63dd361f60b2e Mon Sep 17 00:00:00 2001 From: Hannah Wolfe Date: Thu, 4 Nov 2021 11:54:22 +0000 Subject: [PATCH] Ensured nonexistant public files fallback to 404 - If we register the serve public file middleware for a file that doesn't exist, this will currently throw an ENOENT error - Instead, we want to fall back to a standard 404 so that this behaves normally - This will be useful for the card asset service, where the cards.min.css and cards.min.js files may or may not exist --- .../web/middleware/serve-public-file.js | 11 +++++++++- .../web/middleware/serve-public-file.test.js | 21 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/core/frontend/web/middleware/serve-public-file.js b/core/frontend/web/middleware/serve-public-file.js index 2fb6b86ab9..8071528fa3 100644 --- a/core/frontend/web/middleware/serve-public-file.js +++ b/core/frontend/web/middleware/serve-public-file.js @@ -7,7 +7,8 @@ const urlUtils = require('../../../shared/url-utils'); const tpl = require('@tryghost/tpl'); const messages = { - imageNotFound: 'Image not found' + imageNotFound: 'Image not found', + fileNotFound: 'File not found' }; function createPublicFileMiddleware(file, type, maxAge) { @@ -43,6 +44,14 @@ function createPublicFileMiddleware(file, type, maxAge) { // modify text files before caching+serving to ensure URL placeholders are transformed fs.readFile(filePath, (err, buf) => { if (err) { + // Downgrade to a simple 404 if the file didn't exist + if (err.code === 'ENOENT') { + err = new errors.NotFoundError({ + message: tpl(messages.fileNotFound), + code: 'PUBLIC_FILE_NOT_FOUND', + property: err.path + }); + } return next(err); } diff --git a/test/unit/frontend/web/middleware/serve-public-file.test.js b/test/unit/frontend/web/middleware/serve-public-file.test.js index 723b3f8b09..5fc97394ff 100644 --- a/test/unit/frontend/web/middleware/serve-public-file.test.js +++ b/test/unit/frontend/web/middleware/serve-public-file.test.js @@ -101,4 +101,25 @@ describe('servePublicFile', function () { res.end.calledWith('User-agent: http://127.0.0.1:2369').should.be.true(); }); + + it('should 404 for ENOENT on general files', function () { + const middleware = servePublicFile('robots.txt', 'text/plain', 3600); + req.path = '/robots.txt'; + + sinon.stub(fs, 'readFile').callsFake(function (file, cb) { + const err = new Error(); + err.code = 'ENOENT'; + cb(err, null); + }); + + res = { + writeHead: sinon.spy(), + end: sinon.spy() + }; + + middleware(req, res, next); + + next.called.should.be.true(); + next.calledWith(sinon.match({errorType: 'NotFoundError', code: 'PUBLIC_FILE_NOT_FOUND'})).should.be.true(); + }); });