Fix presigned URL: use public endpoint for signature generation
Host replacement broke S3 signatures since host is a signed header. Instead, create a separate boto3 client with public_endpoint for presign. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -41,8 +41,20 @@ def upload_image(file_bytes: bytes, original_filename: str) -> str:
|
||||
return object_key
|
||||
|
||||
|
||||
def _get_presign_client():
|
||||
"""Client using public endpoint so presigned URL signatures match the public host."""
|
||||
endpoint = settings.minio.public_endpoint or settings.minio.endpoint
|
||||
return boto3.client(
|
||||
"s3",
|
||||
endpoint_url=endpoint,
|
||||
aws_access_key_id=settings.minio.access_key,
|
||||
aws_secret_access_key=settings.minio.secret_key,
|
||||
config=BotoConfig(signature_version="s3v4"),
|
||||
)
|
||||
|
||||
|
||||
def generate_presigned_put_url(object_key: str) -> str:
|
||||
client = _get_client()
|
||||
client = _get_presign_client()
|
||||
url: str = client.generate_presigned_url(
|
||||
"put_object",
|
||||
Params={
|
||||
@@ -51,11 +63,4 @@ def generate_presigned_put_url(object_key: str) -> str:
|
||||
},
|
||||
ExpiresIn=300,
|
||||
)
|
||||
# Replace internal endpoint with public endpoint
|
||||
if settings.minio.public_endpoint:
|
||||
from urllib.parse import urlparse, urlunparse
|
||||
|
||||
internal = urlparse(settings.minio.endpoint)
|
||||
public = urlparse(settings.minio.public_endpoint)
|
||||
url = url.replace(f"{internal.scheme}://{internal.netloc}", f"{public.scheme}://{public.netloc}", 1)
|
||||
return url
|
||||
|
||||
Reference in New Issue
Block a user