Added setContentDisposition option

Resolves #192

This added 2 new dependencies:
content-disposition
BobbyWibowo/serve-static

content-disposition:
This has fallback generation for file names that are outside ISO-8859-1.
Plus it was already a sub-dependency due to express to begin with.

BobbyWibowo/serve-static:
A fork of express/serve-static to allow specifying an async setHeaders
function by the name preSetHeaders, that will be awaited before
creating send stream to clients.
This commit is contained in:
Bobby Wibowo 2020-09-27 04:33:42 +07:00
parent a79117f893
commit c8a5f7be16
No known key found for this signature in database
GPG Key ID: 51C3A1E1E22D26CF
4 changed files with 50 additions and 5 deletions

View File

@ -30,6 +30,12 @@ module.exports = {
serveFilesWithNode: false,
domain: 'https://lolisafe.moe',
/*
If you serve files with node, you can optionally choose to set Content-Disposition header
into their original file names. This allows users to save files into their original file names.
*/
setContentDisposition: false,
/*
If you are serving your files with a different domain than your lolisafe homepage,
then fill this option with your lolisafe homepage, otherwise any falsy value.

View File

@ -1,11 +1,13 @@
const bodyParser = require('body-parser')
const clamd = require('clamdjs')
const contentDisposition = require('content-disposition')
const express = require('express')
const helmet = require('helmet')
const nunjucks = require('nunjucks')
const path = require('path')
const RateLimit = require('express-rate-limit')
const readline = require('readline')
const serveStatic = require('serve-static')
const config = require('./config')
const logger = require('./logger')
const versions = require('./src/versions')
@ -65,6 +67,33 @@ let setHeaders = res => {
res.set('Access-Control-Allow-Origin', '*')
}
const initServeStaticUploads = (opts = {}) => {
if (config.setContentDisposition) {
opts.preSetHeaders = async (res, path) => {
// Do only if accessing files from uploads' root directory (i.e. not thumbs, etc.)
// and only if they're GET requests
if (path.indexOf('/', 1) === -1 && res.req.method === 'GET') {
const name = path.substring(1)
try {
const file = await db.table('files')
.where('name', name)
.select('original')
.first()
res.set('Content-Disposition', contentDisposition(file.original, { type: 'inline' }))
} catch (error) {
logger.error(error)
}
}
}
// serveStatic is just a modified express/serve-static module that allows specifying
// an async setHeaders function by the name preSetHeaders.
// The module will wait for the said function before creating send stream to client.
safe.use('/', serveStatic(paths.uploads, opts))
} else {
safe.use('/', express.static(paths.uploads, opts))
}
}
// Cache control (safe.fiery.me)
if (config.cacheControl) {
const cacheControls = {
@ -96,7 +125,7 @@ if (config.cacheControl) {
// If serving uploads with node
if (config.serveFilesWithNode)
safe.use('/', express.static(paths.uploads, {
initServeStaticUploads({
setHeaders: res => {
res.set('Access-Control-Allow-Origin', '*')
// If using CDN, cache uploads in CDN as well
@ -104,7 +133,7 @@ if (config.cacheControl) {
if (config.cacheControl !== 2)
res.set('Cache-Control', cacheControls.cdn)
}
}))
})
// Function for static assets.
// This requires the assets to use version in their query string,
@ -125,8 +154,7 @@ if (config.cacheControl) {
next()
})
} else if (config.serveFilesWithNode) {
// If serving uploads with node
safe.use('/', express.static(paths.uploads))
initServeStaticUploads()
}
// Static assets

View File

@ -36,6 +36,7 @@
"blake3": "~2.1.4",
"body-parser": "~1.19.0",
"clamdjs": "~1.0.2",
"content-disposition": "~0.5.3",
"express": "~4.17.1",
"express-rate-limit": "~5.1.3",
"fluent-ffmpeg": "~2.1.2",
@ -48,6 +49,7 @@
"randomstring": "~1.1.5",
"readline": "~1.3.0",
"search-query-parser": "~1.5.5",
"serve-static": "git+https://git@github.com/BobbyWibowo/serve-static#60049dec396615ab738d29576a65432e4f9d7d4a",
"sharp": "~0.26.0",
"sqlite3": "~5.0.0",
"systeminformation": "~4.27.3"

View File

@ -1440,7 +1440,7 @@ contains-path@^0.1.0:
resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a"
integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=
content-disposition@0.5.3:
content-disposition@0.5.3, content-disposition@~0.5.3:
version "0.5.3"
resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd"
integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==
@ -6788,6 +6788,15 @@ serve-static@1.14.1:
parseurl "~1.3.3"
send "0.17.1"
"serve-static@git+https://git@github.com/BobbyWibowo/serve-static#60049dec396615ab738d29576a65432e4f9d7d4a":
version "1.14.2"
resolved "git+https://git@github.com/BobbyWibowo/serve-static#60049dec396615ab738d29576a65432e4f9d7d4a"
dependencies:
encodeurl "~1.0.2"
escape-html "~1.0.3"
parseurl "~1.3.3"
send "0.17.1"
set-blocking@^2.0.0, set-blocking@~2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"