Fix screenshot images failing with RustFS presign host mismatch - #334
Conversation
Presigned GETs were signed for the in-cluster rustfs:9000 Host. Browsers
request try.playwright.tech/file-uploads/..., so SigV4 verification fails
(host mismatch / SignatureDoesNotMatch) and screenshots do not render.
Return a host-relative /file-uploads/{uuid} URL and stream objects from
file-service. Caddy and ingress proxy that path to file, not rustfs.
Co-authored-by: Max Schmitt <max@schmitt.mx>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 630d164979
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| } | ||
|
|
||
| // objectNameRe matches UUID object keys written by processUploadedFile. | ||
| var objectNameRe = regexp.MustCompile(`^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.(png|pdf|webm|zip)$`) |
There was a problem hiding this comment.
Accept every object name generated during upload
When an allowed payload uses a filename such as result.PNG, or a PNG explicitly written without a .png suffix, processUploadedFile still stores it and returns 201 because validation is MIME-based, but the returned URL always receives 400 here because this regex accepts only four lowercase suffixes. Derive the object suffix from the validated MIME type, or reject unsupported filename extensions before storing and returning an unusable files[].publicURL.
AGENTS.md reference: AGENTS.md:L108-L108
Useful? React with 👍 / 👎.
#334 moved /file-uploads GET from RustFS to file-service, but upgrade_k3s_containers.sh pulled frontend:latest and explicitly skipped file. Production Caddy now proxies screenshots to file:8080 while the file pod still has no download handler, so every image 404s. Pull file-service:latest, restart deployment/file, and re-exec the repo script after reset so this list is used on the same deploy cycle. Co-authored-by: Max Schmitt <max@schmitt.mx>
#334 moved /file-uploads GET from RustFS to file-service, but upgrade_k3s_containers.sh pulled frontend:latest and explicitly skipped file. Production Caddy now proxies screenshots to file:8080 while the file pod still has no download handler, so every image 404s. Pull file-service:latest, restart deployment/file, and re-exec the repo script after reset so this list is used on the same deploy cycle. Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Problem
Running snippets (including
?e=crawl-y-combinator) stored screenshots in RustFS and returned a SigV4 presigned GET. Those URLs are signed for the in-cluster Hostrustfs:9000(X-Amz-SignedHeaders=host), then shown ashttps://try.playwright.tech/file-uploads/{uuid}.png?....Opening that URL fails (host / signature mismatch; production Cloudflare often surfaces this as a 502). The
<img>in the output panel stays broken.minio-gois still the right S3 client for talking to RustFS. The bug is using presigned URLs whose signed Host cannot match every public hostname (prod, localhost NodePort, etc.).RUSTFS_SERVER_DOMAINSis for virtual-host S3 (bucket.example.com), not same-origin path-style/file-uploads/on the app host.Fix
Serve downloads through file-service (same pattern as
/service/control), keep RustFS cluster-internal:/file-uploads/{uuid}.extwith no presign query./file-uploads/tofile:8080instead of proxying browsers to RustFS.Verification
go test ./...S3_ENDPOINT=127.0.0.1:9000 ... go test ./file-service/ -vagainst k3s RustFSpublicURLis/file-uploads/{uuid}.png(no query)Host: try.playwright.techvia Caddy and via Traefik ingress →200 image/png/?e=crawl-y-combinatorloads the example