From e28e9969fae27c3acf57b55d15a588ed9ebcf74c Mon Sep 17 00:00:00 2001 From: David Newman Date: Thu, 13 Nov 2025 11:36:28 +1000 Subject: [PATCH] Include the path length when substring-ing the url when using forcePathStyle --- api/server/services/Files/S3/crud.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/api/server/services/Files/S3/crud.js b/api/server/services/Files/S3/crud.js index 8dac767aa2..e9118c2a77 100644 --- a/api/server/services/Files/S3/crud.js +++ b/api/server/services/Files/S3/crud.js @@ -11,8 +11,10 @@ const { DeleteObjectCommand, } = require('@aws-sdk/client-s3'); +const endpoint = process.env.AWS_ENDPOINT_URL; const bucketName = process.env.AWS_BUCKET_NAME; const defaultBasePath = 'images'; +const forcePathStyle = ['1', 'true', 'yes'].includes(process.env.AWS_FORCE_PATH_STYLE?.toLowerCase()); let s3UrlExpirySeconds = 2 * 60; // 2 minutes let s3RefreshExpiryMs = null; @@ -250,6 +252,13 @@ function extractKeyFromS3Url(fileUrlOrKey) { try { const url = new URL(fileUrlOrKey); + + if (endpoint?.trim() && forcePathStyle) { + const endpointUrl = new URL(endpoint) + const startPos = endpointUrl.pathname.length + (endpointUrl.pathname.endsWith('/') ? 2 : 1) + bucketName.length + 1; + return url.pathname.substring(startPos); + } + return url.pathname.substring(1); } catch (error) { const parts = fileUrlOrKey.split('/'); @@ -258,6 +267,12 @@ function extractKeyFromS3Url(fileUrlOrKey) { return fileUrlOrKey; } + if (endpoint?.trim() && forcePathStyle) { + const endpointUrl = new URL(endpoint) + const startPos = endpointUrl.pathname.length + (endpointUrl.pathname.endsWith('/') ? 2 : 1) + bucketName.length + 1; + return fileUrlOrKey.substring(startPos); + } + return fileUrlOrKey.startsWith('/') ? fileUrlOrKey.substring(1) : fileUrlOrKey; } }