From b9badcc944ccb9838d5cdb4a59a8944cc73bcb3a Mon Sep 17 00:00:00 2001 From: Bobby Wibowo Date: Sun, 31 Jul 2022 14:06:17 +0700 Subject: [PATCH] fix: ServeStatic ensure forward slashes path --- controllers/handlers/ServeStatic.js | 30 +++++++++++++++++++++++++---- controllers/utils/serveUtils.js | 8 ++++++++ 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/controllers/handlers/ServeStatic.js b/controllers/handlers/ServeStatic.js index b818dc0..a134e1d 100644 --- a/controllers/handlers/ServeStatic.js +++ b/controllers/handlers/ServeStatic.js @@ -1,8 +1,26 @@ +/* + * ServeStatic is intended to be used last in middlewares/handlers hierarcy, + * as it has to check the physical disks everytime to lookup for files. + * + * Hence for lolisafe, this is meant to be used solely to serve uploaded files, + * if serving files with node. + * Because of that, it optionally comes with Content-Type overrides, + * and database query for Content-Disposition. + * + * This class also has Conditional GETs support, + * which involves handling cache-related headers such as + * If-Match, If-Unmodified-Since, ETag, etc. + * And partial bytes fetch by handling Content-Range header, + * which is useful for streaming, among other things. + * + * For other generic assets where lookups speed is a priority, + * please use ServeStaticQuick middleware. + */ + const contentDisposition = require('content-disposition') const etag = require('etag') const fs = require('fs') const parseRange = require('range-parser') -const path = require('path') const SimpleDataStore = require('./../utils/SimpleDataStore') const errors = require('./../errorsController') const paths = require('./../pathsController') @@ -24,7 +42,12 @@ class ServeStatic { throw new TypeError('Root directory must be set') } - this.directory = directory + 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.acceptRanges === undefined) { options.acceptRanges = true @@ -141,8 +164,7 @@ class ServeStatic { return errors.handleNotFound(req, res) } - const fullPath = path.join(this.directory, req.path) - + const fullPath = this.directory + req.path const stat = await this.#get(fullPath) .catch(error => { // Only re-throw errors if not due to missing files diff --git a/controllers/utils/serveUtils.js b/controllers/utils/serveUtils.js index 37687da..1d1c134 100644 --- a/controllers/utils/serveUtils.js +++ b/controllers/utils/serveUtils.js @@ -11,6 +11,14 @@ self.isFresh = (req, res) => { }) } +self.forwardSlashes = path => { + return path.split('\\').join('/') +} + +self.relativePath = (root, path) => { + return self.forwardSlashes(path).replace(root, '') +} + /* * Based on https://github.com/pillarjs/send/blob/0.18.0/index.js * Copyright(c) 2012 TJ Holowaychuk