From e6a293a02797311c01d864c9243439a6a6f9b9bb Mon Sep 17 00:00:00 2001 From: "Andrey A." <56412611+aantti@users.noreply.github.com> Date: Sat, 7 Mar 2026 10:39:59 +0100 Subject: [PATCH 1/2] feat: add storagePublicUrl for tus --- src/config.ts | 2 ++ src/http/routes/tus/lifecycle.ts | 12 +++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/config.ts b/src/config.ts index 7b573c1c..1bd95567 100644 --- a/src/config.ts +++ b/src/config.ts @@ -114,6 +114,7 @@ type StorageConfigType = { requestUrlLengthLimit: number requestXForwardedHostRegExp?: string requestAllowXForwardedPrefix?: boolean + storagePublicUrl?: string logLevel?: string logflareEnabled?: boolean logflareApiKey?: string @@ -284,6 +285,7 @@ export function getConfig(options?: { reload?: boolean }): StorageConfigType { ), requestAllowXForwardedPrefix: getOptionalConfigFromEnv('REQUEST_ALLOW_X_FORWARDED_PATH') === 'true', + storagePublicUrl: getOptionalConfigFromEnv('STORAGE_PUBLIC_URL'), requestUrlLengthLimit: Number(getOptionalConfigFromEnv('REQUEST_URL_LENGTH_LIMIT', 'URL_LENGTH_LIMIT')) || 7_500, requestTraceHeader: getOptionalConfigFromEnv('REQUEST_TRACE_HEADER', 'REQUEST_ID_HEADER'), diff --git a/src/http/routes/tus/lifecycle.ts b/src/http/routes/tus/lifecycle.ts index a6627116..24b821d3 100644 --- a/src/http/routes/tus/lifecycle.ts +++ b/src/http/routes/tus/lifecycle.ts @@ -11,7 +11,8 @@ import type { ServerRequest as Request } from 'srvx' import { getConfig } from '../../../config' -const { storageS3Bucket, tusPath, requestAllowXForwardedPrefix } = getConfig() +const { storageS3Bucket, tusPath, requestAllowXForwardedPrefix, storagePublicUrl } = getConfig() +const parsedPublicUrl = storagePublicUrl ? new URL(storagePublicUrl) : undefined const reExtractFileID = /([^/]+)\/?$/ export const SIGNED_URL_SUFFIX = '/sign' @@ -113,7 +114,12 @@ export function generateUrl( throw ERRORS.InvalidParameter('url') } - proto = process.env.NODE_ENV === 'production' ? 'https' : proto + if (parsedPublicUrl) { + proto = parsedPublicUrl.protocol.replace(':', '') + host = parsedPublicUrl.host + } else { + proto = process.env.NODE_ENV === 'production' ? 'https' : proto + } let basePath = path @@ -126,7 +132,7 @@ export function generateUrl( const isSigned = req.url?.endsWith(SIGNED_URL_SUFFIX) const fullPath = isSigned ? `${basePath}${SIGNED_URL_SUFFIX}` : basePath - if (req.headers['x-forwarded-host']) { + if (!parsedPublicUrl && req.headers['x-forwarded-host']) { const port = req.headers['x-forwarded-port'] if (typeof port === 'string' && port && !['443', '80'].includes(port)) { From cd2b1085c536055c57fd11d1cb4e323c933dcfd7 Mon Sep 17 00:00:00 2001 From: "Andrey A." <56412611+aantti@users.noreply.github.com> Date: Tue, 10 Mar 2026 12:19:21 +0100 Subject: [PATCH 2/2] fix: set proto to https for production --- src/http/routes/tus/lifecycle.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/http/routes/tus/lifecycle.ts b/src/http/routes/tus/lifecycle.ts index 24b821d3..afd5ecab 100644 --- a/src/http/routes/tus/lifecycle.ts +++ b/src/http/routes/tus/lifecycle.ts @@ -117,10 +117,10 @@ export function generateUrl( if (parsedPublicUrl) { proto = parsedPublicUrl.protocol.replace(':', '') host = parsedPublicUrl.host - } else { - proto = process.env.NODE_ENV === 'production' ? 'https' : proto } + proto = process.env.NODE_ENV === 'production' ? 'https' : proto + let basePath = path const forwardedPath = req.headers['x-forwarded-prefix']