fix: reject oversized bodies before app response
This commit is contained in:
parent
1794640f9d
commit
f2345e482c
1 changed files with 19 additions and 23 deletions
|
|
@ -116,41 +116,37 @@ class BodyLimit:
|
||||||
if scope.get("type") != "http":
|
if scope.get("type") != "http":
|
||||||
await self.app(scope, receive, send)
|
await self.app(scope, receive, send)
|
||||||
return
|
return
|
||||||
seen = 0
|
class TooLarge(Exception):
|
||||||
blocked = False
|
pass
|
||||||
|
|
||||||
|
seen = 0
|
||||||
async def limited() -> Dict[str, Any]:
|
async def limited() -> Dict[str, Any]:
|
||||||
nonlocal seen, blocked
|
nonlocal seen
|
||||||
if blocked:
|
|
||||||
return {"type": "http.request", "body": b"", "more_body": False}
|
|
||||||
message = await receive()
|
message = await receive()
|
||||||
if message.get("type") != "http.request":
|
if message.get("type") != "http.request":
|
||||||
return message
|
return message
|
||||||
body = message.get("body") or b""
|
body = message.get("body") or b""
|
||||||
seen += len(body)
|
seen += len(body)
|
||||||
if seen > self.max_bytes:
|
if seen > self.max_bytes:
|
||||||
blocked = True
|
raise TooLarge
|
||||||
await send(
|
|
||||||
{
|
|
||||||
"type": "http.response.start",
|
|
||||||
"status": 413,
|
|
||||||
"headers": [(b"content-type", b"application/json")],
|
|
||||||
}
|
|
||||||
)
|
|
||||||
await send(
|
|
||||||
{
|
|
||||||
"type": "http.response.body",
|
|
||||||
"body": b'{"error":{"code":"PAYLOAD_TOO_LARGE","message":"request body too large"}}',
|
|
||||||
}
|
|
||||||
)
|
|
||||||
return {"type": "http.request", "body": b"", "more_body": False}
|
|
||||||
return message
|
return message
|
||||||
|
|
||||||
try:
|
try:
|
||||||
await self.app(scope, limited, send)
|
await self.app(scope, limited, send)
|
||||||
except RuntimeError:
|
except TooLarge:
|
||||||
if not blocked:
|
await send(
|
||||||
raise
|
{
|
||||||
|
"type": "http.response.start",
|
||||||
|
"status": 413,
|
||||||
|
"headers": [(b"content-type", b"application/json")],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
await send(
|
||||||
|
{
|
||||||
|
"type": "http.response.body",
|
||||||
|
"body": b'{"error":{"code":"PAYLOAD_TOO_LARGE","message":"request body too large"}}',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
SERVICE_TYPE = "_dorayaki._tcp"
|
SERVICE_TYPE = "_dorayaki._tcp"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue