fix: reflect request origin in CORS responses instead of wildcard#375
fix: reflect request origin in CORS responses instead of wildcard#375mkitti wants to merge 1 commit into
Conversation
Starlette 0.48 sends Access-Control-Allow-Origin: * combined with Access-Control-Allow-Credentials: true when allow_origins=['*'] is used. Browsers reject this combination even for non-credentialed requests (e.g. HTTP Range reads from a cross-origin viewer like zipglancer). Switching to allow_origin_regex=r'.*' causes Starlette to reflect the specific request origin instead of *, which is valid alongside Allow-Credentials: true. Also exposes Accept-Ranges and Content-Length in CORS responses so cross-origin clients can read range-request metadata directly. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
I needed this when running fileglancer locally, but I am not sure if this change is needed with fileglancer deployed: |
|
See https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS/Errors/CORSNotSupportingCredentials regarding ceedentialed requests |
neomorphic
left a comment
There was a problem hiding this comment.
This code will work, but it is using an anti-pattern as described here. Since this is an internal application, that is probably fine.
|
Why does it work with the deployed Fileglancer as in https://janeliascicomp.github.io/zipglancer/?url=https%3A%2F%2Ffileglancer.int.janelia.org%2Ffiles%2FkhVBD0vfObEZppzM%2Fozx_demo%2Fbonsai.ozx ? Perhaps we only need this setting for development use ( |
It works with the deployed version on fileglancer.int.janelia.org, because that installation is already returning mirrored domains and the |
|
@allison-truhlar There appears to be an issue with the dependency chain. Paraphrased from Claude: Local dev env (conda-forge):
Production (PyPI, via the hub installing fileglancer==2.8.1):
So starlette is "pinned" to 0.48 in dev purely because the <0.120 cap on fastapi forces fastapi 0.119.1, whose metadata forbids starlette ≥ 0.49. conda-forge isn't the limiter — it carries newer fastapi/starlette; your own cap blocks the dev env from The real problem: two inconsistent declarations You have the same dependencies declared twice, with different bounds, and dev vs prod use different ones: Prod installs fileglancer from PyPI (the hub's pypi-dependencies), so it follows the open-ended column and floats to fastapi 0.135 / starlette 1.0.0. Dev installs from conda-forge with the capped column and stays at fastapi 0.119 / starlette 0.48. That The fix Relax (or remove) the conda upper cap so the dev env can resolve the same FastAPI/Starlette as prod, then re-lock: then pixi update fastapi starlette uvicorn (or pixi update) to refresh pixi.lock. After that, dev-launch would run Starlette 1.0.0 and reproduce production's origin-reflection behavior. Two caveats worth checking before you bump:
|
|
Okay - it looks like a straightforward fix - just make the dev env requirements match the PyPi requirements. I can try this out in a branch and then Mark can try it out with Zipglancer |
Summary
allow_origins=["*"]withallow_origin_regex=r".*"in the StarletteCORSMiddlewareso the server reflects the specific request origin instead of returning*Accept-RangesandContent-Lengthtoexpose_headersProblem
Starlette 0.48 sends
Access-Control-Allow-Origin: *combined withAccess-Control-Allow-Credentials: truewhenallow_origins=["*"]is configured. Browsers reject this combination even for non-credentialed requests (e.g. HTTP Range reads from a cross-origin viewer).This means any client served from a different origin — such as zipglancer, a companion viewer for ZIP/OME-Zarr archives — cannot make range requests to fileglancer's
/files/shared path endpoint.Fix
allow_origin_regex=r".*"causes Starlette to reflect the actual request origin inAccess-Control-Allow-Origin, which is valid alongsideAllow-Credentials: trueand accepted by all browsers.The additional exposed headers (
Accept-Ranges,Content-Length) allow cross-origin clients to read range-request metadata directly without workarounds.Test plan
pixi run node-install && pixi run node-eslint-check— passes (0 errors).zipor.ozxfilehttps://janeliascicomp.github.io/zipglancer/) and confirm the archive loads without CORS errors🤖 Generated with Claude Code