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
|
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:
|
def generate_presigned_put_url(object_key: str) -> str:
|
||||||
client = _get_client()
|
client = _get_presign_client()
|
||||||
url: str = client.generate_presigned_url(
|
url: str = client.generate_presigned_url(
|
||||||
"put_object",
|
"put_object",
|
||||||
Params={
|
Params={
|
||||||
@@ -51,11 +63,4 @@ def generate_presigned_put_url(object_key: str) -> str:
|
|||||||
},
|
},
|
||||||
ExpiresIn=300,
|
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
|
return url
|
||||||
|
|||||||
Reference in New Issue
Block a user