refactor: ServeLiveDirectory

ensure forward slashes path

refactored init method

ensure internal res.type is set before attempting to call external
setHeaders function, to allow overrides
This commit is contained in:
Bobby Wibowo 2022-07-31 14:08:13 +07:00
parent b9badcc944
commit b1566c5abf
No known key found for this signature in database
GPG Key ID: 51C3A1E1E22D26CF
2 changed files with 47 additions and 15 deletions

View File

@ -1,3 +1,18 @@
/*
* ServeLiveDirectory is a middleware wrapper for LiveDirectory library.
*
* It is mainly intended to add Conditional GETs support,
* which involves handling cache-related headers such as
* If-Match, If-Unmodified-Since, ETag, etc.
*
* LiveDirectory monitors and caches all the files in the configure directory into memory,
* which allows very fast lookups, thus allowing multiple instances of this middleware
* to be used together, if needed.
*
* However, due to the fact that it caches all the files into memory,
* this may not be the best choice in an environment where memory space is a premium.
*/
const LiveDirectory = require('live-directory')
const serveUtils = require('./../utils/serveUtils')
@ -6,15 +21,17 @@ class ServeLiveDirectory {
#options
constructor (instanceOptions = {}, options = {}) {
if (!instanceOptions.ignore) {
instanceOptions.ignore = path => {
// ignore dot files
return path.startsWith('.')
}
constructor (directory, options = {}) {
if (!directory || typeof directory !== 'string') {
throw new TypeError('Root directory must be set')
}
this.instance = new LiveDirectory(instanceOptions)
this.directory = serveUtils.forwardSlashes(directory)
// Ensure does not end with a forward slash
if (this.directory.endsWith('/')) {
this.directory = this.directory.slice(0, -1)
}
if (options.etag === undefined) {
options.etag = true
@ -28,6 +45,20 @@ class ServeLiveDirectory {
throw new TypeError('Middleware option setHeaders must be a function')
}
const instanceOptions = Object.assign({}, options.instanceOptions)
instanceOptions.path = this.directory
delete options.instanceOptions
if (!instanceOptions.ignore) {
instanceOptions.ignore = path => {
// ignore dot files
return path.startsWith('.')
}
}
this.instance = new LiveDirectory(instanceOptions)
this.#options = options
}
@ -39,12 +70,12 @@ class ServeLiveDirectory {
*/
handler (req, res, file) {
// set header fields
this.#setHeaders(req, res, file)
// set content-type
res.type(file.extension)
// set header fields
this.#setHeaders(req, res, file)
// conditional GET support
if (serveUtils.isConditionalGET(req)) {
if (serveUtils.isPreconditionFailure(req, res)) {

View File

@ -190,12 +190,12 @@ if (config.cacheControl) {
// Init LiveDirectory middlewares for static assets
// Static assets in /public directory
const serveLiveDirectoryPublicInstance = new ServeLiveDirectory({ path: paths.public }, {
const serveLiveDirectoryPublicInstance = new ServeLiveDirectory(paths.public, {
setHeaders: setHeadersForStaticAssets
})
safe.use(serveLiveDirectoryPublicInstance.middleware)
// Static assets in /dist directory
const serveLiveDirectoryDistInstance = new ServeLiveDirectory({ path: paths.dist }, {
const serveLiveDirectoryDistInstance = new ServeLiveDirectory(paths.dist, {
setHeaders: setHeadersForStaticAssets
})
safe.use(serveLiveDirectoryDistInstance.middleware)
@ -231,9 +231,10 @@ safe.use('/api', api)
}
}
const serveLiveDirectoryCustomPagesInstance = new ServeLiveDirectory({
path: paths.customPages,
keep: ['.html']
const serveLiveDirectoryCustomPagesInstance = new ServeLiveDirectory(paths.customPages, {
instanceOptions: {
keep: ['.html']
}
})
// Cookie Policy