Multiple values for access-control-allow-origin
See original GitHub issueChecklist
- [ x] The bug is reproducible against the latest release and/or
master
. - [ x] There are no similar issues or pull requests to fix it yet.
Describe the bug
When using starlette (through FastAPI) CORSMiddleware with python-socketio (another ASGI app mounted via app.mount()), I got multiple values for the access-control-allow-origin headers. This is because both python socketio and the CORSMiddleware will inject CORS headers in different cases. In the response I see two duplicated headers:
Access-Control-Allow-Origin: http://localhost:3000
access-control-allow-origin: http://localhost:3000
And the browser complain it as a CORS error.
To reproduce
from fastapi import FastAPI
import socketio
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
sio = socketio.AsyncServer(async_mode="asgi", cors_allowed_origins="http://localhost:3000")
sio_app = socketio.ASGIApp(socketio_server=sio)
app.mount("/", sio_app)
app.add_middleware(
CORSMiddleware,
allow_origins= ["http://localhost:3000"],
allow_credentials=False,
allow_methods=["*"],
allow_headers=["Content-Type", "Authorization"],
)
Expected behavior
The CORSMiddleware should check existing headers in different cases and update them only if the headers in different cases not exists.
Actual behavior
The CORSMiddleware add the cors haders and result in multiple duplicated values.
Environment
- OS: MacOS
- Python version: 3.8.11
- Starlette version: 0.14.2
Additional context
Issue Analytics
- State:
- Created 2 years ago
- Reactions:1
- Comments:15 (6 by maintainers)
Top Results From Across the Web
Access-Control-Allow-Origin Multiple Origin Domains?
Sounds like the recommended way to do it is to have your server read the Origin header from the client, compare that to...
Read more >Reason: Multiple CORS header 'Access-Control-Allow-Origin ...
More than one Access-Control-Allow-Origin header was sent by the server. This isn't allowed. If you have access to the server you can change ......
Read more >【Access-control-allow-origin】multiple domains explained
The Access-Control-Allow-Origin header cannot contain multiple domains, like separating different domains via spaces or commas. Besides ...
Read more >The 'Access-Control-Allow-Origin ... - Jitsi Community Forum
When Access-Control-Allow-Origin is sent multiple times in a response, it's the same as a single header with the values comma-separated.
Read more >Access-Control-Allow-Origin with multiple origin domains ...
In your Episerver-site, you can add a single domain to your web.config file like this. ... You can allow all origins by replacing...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
This is an unfortunate design decision that appears to be based on a misreading of RFC7230. ASGI spec:
"Multiple header fields with the same name are complex in HTTP. RFC 7230 states that for any header field that can appear multiple times, it is exactly equivalent to sending that header field only once with all the values joined by commas.
However, RFC 7230 and RFC 6265 make it clear that this rule does not apply to the various headers used by HTTP cookies (Cookie and Set-Cookie). The Cookie header must only be sent once by a user-agent, but the Set-Cookie header may appear repeatedly and cannot be joined by commas. The ASGI design decision is to transport both request and response headers as lists of 2-element [name, value] lists and preserve headers exactly as they were provided."
RFC 7230:
" A sender MUST NOT generate multiple header fields with the same field name in a message unless either the entire field value for that header field is defined as a comma-separated list [i.e., #(values)] or the header field is a well-known exception (as noted below)."
Not all header fields are defined as comma-separated lists.
@oeway Sorry, closed the wrong issue. I’ll re-open this.