Fix remaining CORB warnings on cross-origin player photo loads #210
Labels
No labels
domain:backend
domain:devops
domain:frontend
status:approved
status:in-progress
status:needs-fix
status:qa
type:bug
type:devops
type:feature
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
forgejo_admin/basketball-api#210
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Type
Feature
Lineage
Follows from #207 / PR #208 which fixed the primary CORS issue (StaticFiles mount moved so CORSMiddleware applies). 5 CORB warnings remain in the browser console. The page works but some photos may silently fail to load.
Repo
forgejo_admin/basketball-apiUser Story
WS-S6: As a coach or admin viewing the draft board, I expect all player photos to load without browser console warnings, so the roster view is reliable and complete.
Context
Investigation findings from code audit (2026-03-28):
PR #208 fixed the main CORS issue by moving
StaticFiles("/uploads/photos", ...)to module level soCORSMiddlewarewraps it withAccess-Control-Allow-Originheaders. However, 5 CORB (Cross-Origin Read Blocking) warnings persist in the console.CORB is a browser-side protection (distinct from CORS). It blocks cross-origin responses where the
Content-Typeheader doesn't match what the browser expects for the resource type.Root cause analysis — three contributing factors:
Content-Type may be wrong for some files. Starlette's
StaticFilesuses Python'smimetypesmodule to guess Content-Type from file extensions. On minimal container images, themimetypesDB may be incomplete, causing some.jpg/.jpegfiles to be served asapplication/octet-stream. CORB blocksapplication/octet-streamfor<img>requests.No explicit MIME type validation on the serving side. The upload route (
upload.pyline 42) validatesfile.content_typestarts withimage/at upload time, but the static file server relies entirely on extension-based guessing at serve time. There's no fallback or override.Frontend
<img>tags lackcrossoriginattribute. The admin teams page (admin/teams/+page.svelteline 196) and player profile page (players/[id]/+page.sveltelines 265, 277) load photos cross-origin without thecrossoriginattribute. When CORS headers are present but the fetch mode is "no-cors" (browser default for<img>), some browsers emit CORB warnings.Current architecture:
POST /upload/photo→ saved to/data/uploads/photos/{uuid}.{ext}StaticFiles("/uploads/photos", directory=settings.upload_dir)westsidekingsandqueens.tail5b443a.ts.netfrombasketball-api.tail5b443a.ts.net/uploads/photos/...File Targets
basketball-api (backend):
src/basketball_api/main.py— Add explicit MIME type mapping or a custom middleware that sets correctContent-Typefor image responses from/uploads/photos/src/basketball_api/routes/upload.py— Consider storing the original Content-Type alongside the file, or validate extension-to-MIME mapping at upload timewestside-app (frontend — separate repo):
src/routes/(app)/admin/teams/+page.svelte(line 196) — Addcrossorigin="anonymous"to player photo<img>tagssrc/routes/(app)/players/[id]/+page.svelte(lines 265, 277) — Addcrossorigin="anonymous"to player photo<img>tagsAcceptance Criteria
/uploads/photos/return correctContent-Typeheaders (image/jpeg,image/png, orimage/webp— neverapplication/octet-stream)Test Expectations
/uploads/photos/{file}.jpgreturnsContent-Type: image/jpeg/uploads/photos/{file}.pngreturnsContent-Type: image/pngConstraints
Checklist
crossorigin="anonymous"to cross-origin<img>tags (westside-app PR)Related