Use configured base_url for signed upload/download URLs#100
Conversation
The signed upload and download URLs were built from request.scheme and request.host, which ignored the configured SUPERNOTE_BASE_URL. Build them from config.base_url instead so the application's base URL is honored (falling back to the configured host:port when unset). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR updates the Supernote server’s signed upload/download URL generation so that externally visible URLs honor the configured SUPERNOTE_BASE_URL (via config.base_url) instead of being derived from the incoming request’s scheme/host.
Changes:
- Switched signed upload URL construction to use
config.base_urlin summary, web, and device upload-apply endpoints. - Switched signed download URL construction to use
config.base_urlin summary and device download/convert endpoints.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 7 comments.
| File | Description |
|---|---|
| supernote/server/routes/summary.py | Uses config.base_url for signed upload/apply-summary and download-summary URLs. |
| supernote/server/routes/file_web.py | Uses config.base_url for web upload/apply signed URL generation. |
| supernote/server/routes/file_device.py | Uses config.base_url for device upload/apply, download/apply, and note conversion download URLs. |
| config = request.app["config"] | ||
| encoded_name = urllib.parse.quote(summary.handwrite_inner_name) | ||
| download_path = f"/api/oss/download?path={encoded_name}" | ||
| signed_path = await url_signer.sign(download_path, user=user_email) | ||
| download_url = f"{request.scheme}://{request.host}{signed_path}" | ||
| download_url = f"{config.base_url}{signed_path}" |
| path_to_sign = f"/api/oss/upload?path={encoded_name}" | ||
| signed_path = await url_signer.sign(path_to_sign, user=request["user"]) | ||
| full_url = f"{request.scheme}://{request.host}{signed_path}" | ||
| full_url = f"{config.base_url}{signed_path}" |
| simple_path = f"/api/oss/upload?path={encoded_name}" | ||
| full_upload_url_path = await url_signer.sign(simple_path, user=request["user"]) | ||
| full_upload_url = f"{request.scheme}://{request.host}{full_upload_url_path}" | ||
| full_upload_url = f"{config.base_url}{full_upload_url_path}" | ||
|
|
||
| # Extract signature and timestamp using UrlSigner helpers |
| path_to_sign = f"/api/oss/download?path={info.id}" | ||
|
|
||
| # helper returns: ...?signature=... | ||
| signed_path = await url_signer.sign(path_to_sign, user=user_email) | ||
| download_url = f"{request.scheme}://{request.host}{signed_path}" | ||
| download_url = f"{config.base_url}{signed_path}" |
| path_to_sign = f"/api/oss/download?path={res.storage_key}" | ||
| signed_path = await url_signer.sign(path_to_sign, user=user_email) | ||
| download_url = f"{request.scheme}://{request.host}{signed_path}" | ||
| download_url = f"{config.base_url}{signed_path}" | ||
|
|
||
| png_pages.append(PngPageVO(page_no=res.page_no, url=download_url)) |
| # Generate signed URL for PDF | ||
| path_to_sign = f"/api/oss/download?path={storage_key}" | ||
| signed_path = await url_signer.sign(path_to_sign, user=user_email) | ||
| download_url = f"{request.scheme}://{request.host}{signed_path}" | ||
| download_url = f"{config.base_url}{signed_path}" | ||
|
|
| full_url = f"{config.base_url}{full_url_path}" | ||
|
|
||
| part_path = f"/api/oss/upload/part?path={encoded_name}" | ||
| part_url_path = await url_signer.sign(part_path, user=user_email) | ||
| part_url = f"{request.scheme}://{request.host}{part_url_path}" | ||
| part_url = f"{config.base_url}{part_url_path}" |
allenporter
left a comment
There was a problem hiding this comment.
Hi,
I agree this is a valid issue to fix, thank you for the contribution. co-piilot is calling out that of the base url is not set this may not perform properly (e.g. it will now always return localhost when the environment variable is not set). What's your take on this?
Generally please reply / ack / respond to the co-pilot comments and you can mark ready for review when ready.
The signed upload and download URLs were built from request.scheme and request.host, which ignored the configured SUPERNOTE_BASE_URL.
Build them from config.base_url instead so the application's base URL is honored (falling back to the configured host:port when unset).