Skip to content

Commit

Permalink
Apply comments
Browse files Browse the repository at this point in the history
  • Loading branch information
Kludex committed Nov 27, 2023
1 parent 6aeb532 commit 4d0415d
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 17 deletions.
23 changes: 9 additions & 14 deletions starlette/middleware/limits.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def __init__(self, max_body_size: int) -> None:
self.max_body_size = max_body_size


class LimitRequestMiddleware:
class LimitRequestSizeMiddleware:
def __init__(
self, app: ASGIApp, max_body_size: int = DEFAULT_MAX_BODY_SIZE
) -> None:
Expand All @@ -22,17 +22,6 @@ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
if scope["type"] != "http": # pragma: no cover
return await self.app(scope, receive, send)

headers = Headers(scope=scope)
content_length = headers.get("content-length")
if content_length is not None:
if int(content_length) > self.max_body_size:
return await _content_too_large_app(scope)(scope, receive, send)

# NOTE: The server makes sure that the content-length header sent by the
# client is the same as the length of the body.
# Ref.: https://github.com/django/asgiref/issues/422
return await self.app(scope, receive, send)

total_size = 0
response_started = False

Expand All @@ -52,15 +41,21 @@ async def wrap_receive() -> Message:
raise ContentTooLarge(self.max_body_size)
return message

headers = Headers(scope=scope)
content_length = headers.get("content-length")
if content_length is not None:
if int(content_length) > self.max_body_size:
return await _content_too_large_app()(scope, receive, send)

try:
await self.app(scope, wrap_receive, wrap_send)
except ContentTooLarge as exc:
# NOTE: If response has already started, we can't return a 413, because the
# headers have already been sent.
if not response_started:
return await _content_too_large_app(scope)(scope, receive, send)
return await _content_too_large_app()(scope, receive, send)
raise exc


def _content_too_large_app(scope: Scope) -> PlainTextResponse:
def _content_too_large_app() -> PlainTextResponse:
return PlainTextResponse("Content Too Large", status_code=413)
16 changes: 13 additions & 3 deletions tests/middleware/test_limits.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from starlette.applications import Starlette
from starlette.middleware import Middleware
from starlette.middleware.limits import ContentTooLarge, LimitRequestMiddleware
from starlette.middleware.limits import ContentTooLarge, LimitRequestSizeMiddleware
from starlette.requests import Request
from starlette.routing import Route
from starlette.testclient import TestClient
Expand All @@ -24,7 +24,7 @@ async def echo_app(scope: Scope, receive: Receive, send: Send) -> None:
break


app = LimitRequestMiddleware(echo_app, max_body_size=1024)
app = LimitRequestSizeMiddleware(echo_app, max_body_size=1024)


def test_no_op(test_client_factory: Callable[..., TestClient]) -> None:
Expand Down Expand Up @@ -81,10 +81,20 @@ async def read_body_endpoint(request: Request) -> None:

app = Starlette(
routes=[Route("/", read_body_endpoint, methods=["POST"])],
middleware=[Middleware(LimitRequestMiddleware, max_body_size=1024)],
middleware=[Middleware(LimitRequestSizeMiddleware, max_body_size=1024)],
)
client = test_client_factory(app)

response = client.post("/", content=[b"X" * 1024, b"X"])
assert response.status_code == 413
assert response.text == "Content Too Large"


def test_content_too_large_and_content_length_mismatch(
test_client_factory: Callable[..., TestClient]
) -> None:
client = test_client_factory(app)

response = client.post("/", content="X" * 1025, headers={"Content-Length": "1024"})
assert response.status_code == 413
assert response.text == "Content Too Large"

0 comments on commit 4d0415d

Please sign in to comment.