feat: allow specifying root path in serve classes

when used on non-root paths
This commit is contained in:
Bobby 2022-08-23 15:12:25 +07:00
parent ff7ec4aeaf
commit 414afc7ae6
No known key found for this signature in database
GPG Key ID: 941839794CBF5A09
4 changed files with 51 additions and 21 deletions

View File

@ -62,7 +62,13 @@ class ServeLiveDirectory {
this.#options = options this.#options = options
} }
handler (req, res, file) { get (path) {
const file = this.instance.get(path)
return file
}
handler (req, res, path, file) {
// Set Content-Type // Set Content-Type
res.type(file.extension) res.type(file.extension)
@ -93,12 +99,24 @@ class ServeLiveDirectory {
return next() return next()
} }
const file = this.instance.get(req.path) // If root path is set, ensure it matches the request
let path = req.path
if (this.#options.root) {
if (path.indexOf(this.#options.root) === 0) {
// Re-map path for internal .get()
path = path.replace(this.#options.root, '')
} else {
// Immediately proceed to next middleware otherwise
return next()
}
}
const file = this.get(path)
if (file === undefined) { if (file === undefined) {
return next() return next()
} }
return this.handler(req, res, file) return this.handler(req, res, path, file)
} }
#setHeaders (req, res, file) { #setHeaders (req, res, file) {

View File

@ -77,9 +77,17 @@ class ServeStaticQuick {
this.#options = options this.#options = options
} }
handler (req, res, stat) { get (path) {
const stat = this.files.get(path)
if (!stat || stat.isDirectory()) return
return stat
}
handler (req, res, path, stat) {
// Set Content-Type // Set Content-Type
res.type(req.path) res.type(path)
// Set header fields // Set header fields
this.#setHeaders(req, res, stat) this.#setHeaders(req, res, stat)
@ -106,7 +114,7 @@ class ServeStaticQuick {
res.end() res.end()
} }
return this.#stream(req, res, stat, result) return this.#stream(req, res, path, stat, result)
} }
// Returns a promise which resolves to true once ServeStaticQuick is ready // Returns a promise which resolves to true once ServeStaticQuick is ready
@ -154,26 +162,30 @@ class ServeStaticQuick {
}) })
} }
#get (path) {
const stat = this.files.get(path)
if (!stat || stat.isDirectory()) return
return stat
}
#middleware (req, res, next) { #middleware (req, res, next) {
// Only process GET and HEAD requests // Only process GET and HEAD requests
if (req.method !== 'GET' && req.method !== 'HEAD') { if (req.method !== 'GET' && req.method !== 'HEAD') {
return next() return next()
} }
const stat = this.#get(req.path) // If root path is set, ensure it matches the request
let path = req.path
if (this.#options.root) {
if (path.indexOf(this.#options.root) === 0) {
// Re-map path for internal .get()
path = path.replace(this.#options.root, '')
} else {
// Immediately proceed to next middleware otherwise
return next()
}
}
const stat = this.get(path)
if (stat === undefined) { if (stat === undefined) {
return next() return next()
} }
return this.handler(req, res, stat) return this.handler(req, res, path, stat)
} }
#setHeaders (req, res, stat) { #setHeaders (req, res, stat) {
@ -198,8 +210,8 @@ class ServeStaticQuick {
} }
} }
#stream (req, res, stat, result) { #stream (req, res, path, stat, result) {
const fullPath = this.directory + req.path const fullPath = this.directory + path
const readStream = fs.createReadStream(fullPath, result.options) const readStream = fs.createReadStream(fullPath, result.options)
readStream.on('error', error => { readStream.on('error', error => {

View File

@ -24,7 +24,7 @@ self.relativePath = (root, path) => {
* Based on https://github.com/pillarjs/send/blob/0.18.0/index.js * Based on https://github.com/pillarjs/send/blob/0.18.0/index.js
* Copyright(c) 2012 TJ Holowaychuk * Copyright(c) 2012 TJ Holowaychuk
* Copyright(c) 2014-2022 Douglas Christopher Wilson * Copyright(c) 2014-2022 Douglas Christopher Wilson
* MIT Licensed * MIT License
*/ */
self.isRangeFresh = (req, res) => { self.isRangeFresh = (req, res) => {

View File

@ -268,9 +268,9 @@ safe.use('/api', api)
safe.use((req, res, next) => { safe.use((req, res, next) => {
if (req.method === 'GET' || req.method === 'HEAD') { if (req.method === 'GET' || req.method === 'HEAD') {
const page = req.path === '/' ? 'home' : req.path.substring(1) const page = req.path === '/' ? 'home' : req.path.substring(1)
const customPage = serveLiveDirectoryCustomPagesInstance.instance.get(`${page}.html`) const customPage = serveLiveDirectoryCustomPagesInstance.get(`${page}.html`)
if (customPage) { if (customPage) {
return serveLiveDirectoryCustomPagesInstance.handler(req, res, customPage) return serveLiveDirectoryCustomPagesInstance.handler(req, res, req.path, customPage)
} else if (config.pages.includes(page)) { } else if (config.pages.includes(page)) {
// These rendered pages are persistently cached during production // These rendered pages are persistently cached during production
return res.render(page, { return res.render(page, {