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
This commit is contained in:
Hannah Wolfe 2021-11-04 11:54:22 +00:00
parent 72b90151bb
commit d9bdc444a3
No known key found for this signature in database
GPG Key ID: 9F8C7532D0A6BA55
2 changed files with 31 additions and 1 deletions

View File

@ -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);
}

View File

@ -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();
});
});