diff --git a/api/server/services/Files/S3/crud.js b/api/server/services/Files/S3/crud.js index 0721e33b29ae..0ba8645cbc28 100644 --- a/api/server/services/Files/S3/crud.js +++ b/api/server/services/Files/S3/crud.js @@ -11,8 +11,12 @@ 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; @@ -252,6 +256,18 @@ 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('/') ? 0 : 1) + + bucketName.length + + 1; + + return url.pathname.substring(startPos); + } + return url.pathname.substring(1); } catch (error) { const parts = fileUrlOrKey.split('/'); diff --git a/packages/api/src/cdn/s3.ts b/packages/api/src/cdn/s3.ts index 683a7887fa7a..fe4ef3292b8f 100644 --- a/packages/api/src/cdn/s3.ts +++ b/packages/api/src/cdn/s3.ts @@ -28,9 +28,13 @@ export const initializeS3 = (): S3Client | null => { const endpoint = process.env.AWS_ENDPOINT_URL; const accessKeyId = process.env.AWS_ACCESS_KEY_ID; const secretAccessKey = process.env.AWS_SECRET_ACCESS_KEY; + const forcePathStyle = ['1', 'true', 'yes'].includes( + (process.env.AWS_FORCE_PATH_STYLE ?? '').toLowerCase(), + ); const config = { region, + forcePathStyle, // Conditionally enable path-style addressing // Conditionally add the endpoint if it is provided ...(endpoint ? { endpoint } : {}), };