I would like to extend the functionality of httpStatic
in settings.js
to receive an options object and have that passed to express.static(filePath, options)
.
The change would be non-breaking and give a finer control over how the files are served by express.static. The lines of code where the proposed changes are at line 424 of red.js .
I tested giving express.static bad data, such as a string or number. That will trigger an error stating that it wants an object or null, which is the reason for the mild sanitizing
const options = typeof sp.options === 'object' ? sp.options : null;
before changes:
if (settings.httpStatic) {
let appUseMem = {};
for (let si = 0; si < settings.httpStatic.length; si++) {
const sp = settings.httpStatic[si];
const filePath = sp.path;
const thisRoot = sp.root || "/";
if(appUseMem[filePath + "::" + thisRoot]) {
continue;// this path and root already registered!
}
appUseMem[filePath + "::" + thisRoot] = true;
if (settings.httpStaticAuth) {
app.use(thisRoot, basicAuthMiddleware(settings.httpStaticAuth.user, settings.httpStaticAuth.pass));
}
app.use(thisRoot, express.static(filePath));
}
}
after changes:
if (settings.httpStatic) {
let appUseMem = {};
for (let si = 0; si < settings.httpStatic.length; si++) {
const sp = settings.httpStatic[si];
const filePath = sp.path;
const thisRoot = sp.root || "/";
const options = typeof sp.options === 'object' ? sp.options : null;
if(appUseMem[filePath + "::" + thisRoot]) {
continue;// this path and root already registered!
}
appUseMem[filePath + "::" + thisRoot] = true;
if (settings.httpStaticAuth) {
app.use(thisRoot, basicAuthMiddleware(settings.httpStaticAuth.user, settings.httpStaticAuth.pass));
}
app.use(thisRoot, express.static(filePath, options));
}
}
I have had this running for about 1 week and have had no issues. This is an excerpt from my setting.js that I am using for better integration and control when using nginx as a reverse proxy
.
httpStatic: [
{
path: '/run/media/system/surveillance1/cctv/recordings/',
root: '/recordings/',
options : {
setHeaders: (res, path, stat) => {
if (path.endsWith('.mp4')) {
if (Date.now() - stat.mtimeMs < 60000) {
res.header('Cache-Control', 'no-store');
} else {
res.header('Cache-Control', 'public');
}
}
}
}
}
],
If this seems acceptable, I can make a PR to the dev branch.