Skip to content

sync server add presigned url params#1033

Merged
helloyongyang merged 1 commit intomainfrom
feat-server
Apr 22, 2026
Merged

sync server add presigned url params#1033
helloyongyang merged 1 commit intomainfrom
feat-server

Conversation

@black-eleven
Copy link
Copy Markdown
Contributor

No description provided.

@helloyongyang helloyongyang merged commit de2bb45 into main Apr 22, 2026
2 checks passed
@helloyongyang helloyongyang deleted the feat-server branch April 22, 2026 09:09
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces the ability to upload image generation results to a presigned URL. Key changes include adding a presigned_url field to the task request schema, implementing an upload method with retry logic in the file service, and updating the image task API to handle the upload process. Review feedback focuses on improving security by strengthening URL validation against SSRF, removing redundant attribute checks, replacing assert statements with proper exception handling for production, and refining exception handling in the retry loop to avoid retrying non-transient errors.

Comment on lines +137 to +139
if hasattr(message, "presigned_url") and message.presigned_url:
if not message.presigned_url.startswith(("http://", "https://")):
raise HTTPException(status_code=400, detail=f"Invalid presigned_url: {message.presigned_url}")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-high high

The validation for presigned_url is weak and does not prevent Server-Side Request Forgery (SSRF). An attacker could provide a URL pointing to internal infrastructure (e.g., http://localhost or cloud metadata services) to perform unauthorized actions. Consider implementing more robust validation, such as resolving the hostname and checking that the IP address is not in a private or reserved range. Additionally, hasattr is redundant as the field is part of the schema.

Suggested change
if hasattr(message, "presigned_url") and message.presigned_url:
if not message.presigned_url.startswith(("http://", "https://")):
raise HTTPException(status_code=400, detail=f"Invalid presigned_url: {message.presigned_url}")
if message.presigned_url:
if not message.presigned_url.startswith(("http://", "https://")):
raise HTTPException(status_code=400, detail=f"Invalid presigned_url: {message.presigned_url}")



async def _upload_sync_result_if_needed(message: ImageTaskRequest, result_png: bytes):
presigned_url = (getattr(message, "presigned_url", "") or "").strip()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The use of getattr and the or "" check are redundant here. presigned_url is a defined field in the ImageTaskRequest schema (via BaseTaskRequest) with a default string value, so it is guaranteed to exist and be a string.

Suggested change
presigned_url = (getattr(message, "presigned_url", "") or "").strip()
presigned_url = message.presigned_url.strip()

return None

services = get_services()
assert services.file_service is not None, "File service is not initialized"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Avoid using assert for runtime logic in production code. assert statements can be optimized away when Python is run with optimizations (-O), which would skip this check entirely. Use an explicit if check and raise an HTTPException instead to ensure the error is handled correctly.

Suggested change
assert services.file_service is not None, "File service is not initialized"
if services.file_service is None:
raise HTTPException(status_code=500, detail="File service is not initialized")

Comment on lines +185 to +187
if attempt < max_retries - 1:
await asyncio.sleep(retry_delay)
retry_delay = min(retry_delay * 2, self.max_retry_delay)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Catching a broad Exception within a retry loop is generally discouraged. It can lead to unnecessary retries for non-transient errors (such as TypeError or ValueError caused by logic bugs) that will never succeed. It is better to only retry on specific network or HTTP status exceptions (like httpx.RequestError) and let unexpected exceptions bubble up for easier debugging.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants