mirror of
https://github.com/fastapi/fastapi.git
synced 2026-05-26 09:21:01 -04:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8206485753 | ||
|
|
c910e0139f | ||
|
|
063b5bf582 |
@@ -7,6 +7,12 @@ hide:
|
||||
|
||||
## Latest Changes
|
||||
|
||||
## 0.136.3 (2026-05-23)
|
||||
|
||||
### Refactors
|
||||
|
||||
* ♻️ Do not accept underscore headers when using `convert_underscores=True` (the default). PR [#15589](https://github.com/fastapi/fastapi/pull/15589) by [@tiangolo](https://github.com/tiangolo).
|
||||
|
||||
## 0.136.2 (2026-05-23)
|
||||
|
||||
### Refactors
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""FastAPI framework, high performance, easy to learn, fast to code, ready for production"""
|
||||
|
||||
__version__ = "0.136.2"
|
||||
__version__ = "0.136.3"
|
||||
|
||||
from starlette import status as status
|
||||
|
||||
|
||||
@@ -826,6 +826,10 @@ def request_params_to_args(
|
||||
if value is not None:
|
||||
params_to_process[get_validation_alias(field)] = value
|
||||
processed_keys.add(alias or get_validation_alias(field))
|
||||
# For headers with convert_underscores=True, mark both the converted
|
||||
# header name and the original field alias as processed to avoid
|
||||
# accepting the original alias as an extra header.
|
||||
processed_keys.add(get_validation_alias(field))
|
||||
|
||||
for key in received_params.keys():
|
||||
if key not in processed_keys:
|
||||
|
||||
@@ -11,6 +11,10 @@ class Model(BaseModel):
|
||||
model_config = {"extra": "allow"}
|
||||
|
||||
|
||||
class AuthHeaders(BaseModel):
|
||||
x_user_id: str
|
||||
|
||||
|
||||
@app.get("/query")
|
||||
async def query_model_with_extra(data: Model = Query()):
|
||||
return data
|
||||
@@ -26,6 +30,11 @@ async def cookies_model_with_extra(data: Model = Cookie()):
|
||||
return data
|
||||
|
||||
|
||||
@app.get("/header-requires-hyphen")
|
||||
async def header_model_requires_hyphen(data: AuthHeaders = Header()):
|
||||
return data
|
||||
|
||||
|
||||
def test_query_pass_extra_list():
|
||||
client = TestClient(app)
|
||||
resp = client.get(
|
||||
@@ -91,6 +100,32 @@ def test_header_pass_extra_single():
|
||||
assert resp_json["param2"] == "456"
|
||||
|
||||
|
||||
def test_header_model_prefers_hyphenated_header_with_convert_underscores():
|
||||
client = TestClient(app)
|
||||
|
||||
resp = client.get(
|
||||
"/header-requires-hyphen",
|
||||
headers=[
|
||||
("x-user-id", "hyphenated-value"),
|
||||
("x_user_id", "underscore-value"),
|
||||
],
|
||||
)
|
||||
|
||||
assert resp.status_code == 200
|
||||
assert resp.json() == {"x_user_id": "hyphenated-value"}
|
||||
|
||||
|
||||
def test_header_model_rejects_underscore_header_with_convert_underscores():
|
||||
client = TestClient(app)
|
||||
|
||||
resp = client.get(
|
||||
"/header-requires-hyphen", headers={"x_user_id": "underscore-value"}
|
||||
)
|
||||
|
||||
assert resp.status_code == 422
|
||||
assert resp.json()["detail"][0]["loc"] == ["header", "x_user_id"]
|
||||
|
||||
|
||||
def test_cookie_pass_extra_list():
|
||||
client = TestClient(app)
|
||||
client.cookies = [
|
||||
|
||||
Reference in New Issue
Block a user