fix(web-player): send presigned uploads to a reachable S3 endpoint

The PUT was always sent to 127.0.0.1, which is nothing inside the container, so
uploads failed whenever the web player did not run on the same host as
SeaweedFS. Take an optional S3_UPLOAD_ENDPOINT instead (the compose stacks
point it at seaweedfs:8333) and fall back to the host in the presigned URL. The
signed Host header is preserved either way, so the signature still matches.
This commit is contained in:
2026-07-20 15:13:21 +02:00
parent e277ea0bc5
commit 9826c1c718
2 changed files with 15 additions and 6 deletions
+5 -4
View File
@@ -2,7 +2,7 @@ import http from 'node:http';
import https from 'node:https';
import { env } from '$env/dynamic/private';
const CONNECT_HOST = env.S3_UPLOAD_CONNECT_HOST || '127.0.0.1';
const UPLOAD_ENDPOINT = env.S3_UPLOAD_ENDPOINT ?? '';
export const IMAGE_TYPES: Record<string, string> = {
jpg: 'image/jpeg',
@@ -48,14 +48,15 @@ export async function putPresigned(
if (signed.has('content-type')) headers['Content-Type'] = contentType;
if (signed.has('if-none-match')) headers['If-None-Match'] = '*';
const secure = url.protocol === 'https:';
const target = UPLOAD_ENDPOINT ? new URL(UPLOAD_ENDPOINT) : url;
const secure = target.protocol === 'https:';
const transport = secure ? https : http;
const port = url.port || (secure ? 443 : 80);
const port = target.port || (secure ? 443 : 80);
await new Promise<void>((resolve, reject) => {
const request = transport.request(
{
host: CONNECT_HOST,
host: target.hostname,
port,
method: 'PUT',
path: url.pathname + url.search,