From d84009648e94417c351c2efcc2456f13bb185c90 Mon Sep 17 00:00:00 2001 From: rrrockey <126512405+rrrockey@users.noreply.github.com> Date: Thu, 6 Mar 2025 05:46:37 -0600 Subject: [PATCH] refactor(server): replace switch statement in sendFile with Record lookup (#16630) * refactor cache control handling in server/utils/file.ts * add ability to null CacheControl.NONE * Cache control handling comment * Added comment to file.ts This comment provides a better understanding of what the cacheControlHeader is doing. * Update file.ts Added comments * Update server/src/utils/file.ts * fix comments in file.ts * run prettier with --write to fix formatting --------- Co-authored-by: pnleguizamo Co-authored-by: drew-kearns Co-authored-by: Sierra (Izumi) Brown <119357873+SierraIBrown@users.noreply.github.com> Co-authored-by: Alex --- server/src/utils/file.ts | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/server/src/utils/file.ts b/server/src/utils/file.ts index 915c60de2a..716e0b1957 100644 --- a/server/src/utils/file.ts +++ b/server/src/utils/file.ts @@ -33,27 +33,28 @@ export class ImmichFileResponse { type SendFile = Parameters; type SendFileOptions = SendFile[1]; +const cacheControlHeaders: Record = { + [CacheControl.PRIVATE_WITH_CACHE]: 'private, max-age=86400, no-transform', + [CacheControl.PRIVATE_WITHOUT_CACHE]: 'private, no-cache, no-transform', + [CacheControl.NONE]: null, // falsy value to prevent adding Cache-Control header +}; + export const sendFile = async ( res: Response, next: NextFunction, handler: () => Promise, logger: LoggingRepository, ): Promise => { + // promisified version of 'res.sendFile' for cleaner async handling const _sendFile = (path: string, options: SendFileOptions) => promisify(res.sendFile).bind(res)(path, options); try { const file = await handler(); - switch (file.cacheControl) { - case CacheControl.PRIVATE_WITH_CACHE: { - res.set('Cache-Control', 'private, max-age=86400, no-transform'); - break; - } - - case CacheControl.PRIVATE_WITHOUT_CACHE: { - res.set('Cache-Control', 'private, no-cache, no-transform'); - break; - } + const cacheControlHeader = cacheControlHeaders[file.cacheControl]; + if (cacheControlHeader) { + // set the header to Cache-Control + res.set('Cache-Control', cacheControlHeader); } res.header('Content-Type', file.contentType); @@ -61,6 +62,7 @@ export const sendFile = async ( res.header('Content-Disposition', `inline; filename*=UTF-8''${encodeURIComponent(file.fileName)}`); } + // configure options for serving const options: SendFileOptions = { dotfiles: 'allow' }; if (!isAbsolute(file.path)) { options.root = process.cwd();