Disabling cacheFileIdentifiers will now restore the old behavior of having less strict collision checks.
Fulfills https://github.com/BobbyWibowo/lolisafe/issues/12.
This commit is contained in:
Bobby Wibowo 2018-12-08 07:38:12 +07:00
parent 1b687de98d
commit 2fab5becb0
No known key found for this signature in database
GPG Key ID: 51C3A1E1E22D26CF
2 changed files with 22 additions and 24 deletions

View File

@ -162,22 +162,25 @@ module.exports = {
/* /*
Cache file identifiers. Cache file identifiers.
They will be used for a stricter collision check, such that a single identifier They will be used for stricter collision checks, such that a single identifier
may not be used by more than a single file (e.i. if "abcd.jpg" already exists, a new PNG may not be used by more than a single file (e.i. if "abcd.jpg" already exists, a new PNG
file may not be named as "abcd.png"). file may not be named as "abcd.png").
If this is enabled, the safe will attempt to read file list of the uploads directory If this is enabled, the safe will then attempt to read file list of the uploads directory
during first launch, parse the names, then cache the identifiers into memory. during first launch, parse the names, then cache the identifiers into memory.
Its downside is that it will use a bit more memory, generally a few MBs increase Its downside is that it will use a bit more memory, generally a few MBs increase
on a safe with over >10k uploads. on a safe with over >10k uploads.
If this is disabled, the safe will instead read file list of the uploads directory EVERYTIME If this is disabled, collision check will become less strict.
there is a new upload. As in, the same identifier may be used by multiple different extensions (e.i. if "abcd.jpg"
Its downside will be slower upload handling and memory usage "spikes", already exists, new files can be possibly be named as "abcd.png", "abcd.mp4", etc).
since reading the file list will still consume memory, Its downside will be, in the rare chance that multiple image/video files are sharing the same
just that it will only stay in memory for a few moments. identifier, they will end up with the same thumbnail in dashboard, since thumbnails will
only be saved as PNG in storage (e.i. "abcd.jpg" and "abcd.png" will share a single thumbnail
named "abcd.png" in thumbs directory, in which case, the file that's uploaded the earliest will
be the source for the thumbnail).
On most caces, leaving this enabled is recommended. Unless you do not use thumbnails, it is highly recommended to enable this feature.
*/ */
cacheFileIdentifiers: true, cacheFileIdentifiers: true,

View File

@ -116,9 +116,9 @@ uploadsController.getUniqueRandomName = (length, extension, set) => {
const access = i => { const access = i => {
const identifier = randomstring.generate(length) const identifier = randomstring.generate(length)
if (config.uploads.cacheFileIdentifiers) { if (config.uploads.cacheFileIdentifiers) {
// Filter matching names from uploads tree (as in the identifier) // Check whether the identifier is already used in cache
if (set.has(identifier)) { if (set.has(identifier)) {
console.log(`Identifier ${identifier} is already used (${++i}/${maxTries}).`) console.log(`Identifier ${identifier} is already in use (${++i}/${maxTries}).`)
if (i < maxTries) { return access(i) } if (i < maxTries) { return access(i) }
// eslint-disable-next-line prefer-promise-reject-errors // eslint-disable-next-line prefer-promise-reject-errors
return reject('Sorry, we could not allocate a unique random name. Try again?') return reject('Sorry, we could not allocate a unique random name. Try again?')
@ -127,20 +127,15 @@ uploadsController.getUniqueRandomName = (length, extension, set) => {
// console.log(`Added ${identifier} to identifiers cache`) // console.log(`Added ${identifier} to identifiers cache`)
return resolve(identifier + extension) return resolve(identifier + extension)
} else { } else {
// Read all files names from uploads directory, then filter matching names (as in the identifier) // Less stricter collision check, as the same identifier
fs.readdir(uploadsDir, (error, names) => { // can be used by multiple different extensions
if (error) { return reject(error) } const name = identifier + extension
if (names.length) { fs.access(path.join(uploadsDir, name), error => {
for (const name of names.filter(name => name.startsWith(identifier))) { if (error) { return resolve(name) }
if (name.split('.')[0] === identifier) { console.log(`A file named ${name} already exists (${++i}/${maxTries}).`)
console.log(`Identifier ${identifier} is already used (${++i}/${maxTries}).`)
if (i < maxTries) { return access(i) } if (i < maxTries) { return access(i) }
// eslint-disable-next-line prefer-promise-reject-errors // eslint-disable-next-line prefer-promise-reject-errors
return reject('Sorry, we could not allocate a unique random name. Try again?') return reject('Sorry, we could not allocate a unique random name. Try again?')
}
}
}
return resolve(identifier + extension)
}) })
} }
} }