summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Lundberg <jonas@5monkeys.se>2022-05-30 22:45:48 +0200
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2022-05-31 08:38:00 +0200
commitf1e0fc645bb0b2c15d1510c9a8501743297dec9d (patch)
treebd5aab51f0778e321b6c72e8ee65887f7479b81c
parent292f372768836e2aebc713064c5139e8067eebcb (diff)
downloaddjango-f1e0fc645bb0b2c15d1510c9a8501743297dec9d.tar.gz
Fixed #33754 -- Fixed crash with prematurely closed ASGI request body.
Regression in 441103a04d1d167dc870eaaf90e3fba974f67c93.
-rw-r--r--AUTHORS1
-rw-r--r--django/core/handlers/asgi.py12
-rw-r--r--tests/asgi/tests.py12
-rw-r--r--tests/asgi/urls.py7
4 files changed, 26 insertions, 6 deletions
diff --git a/AUTHORS b/AUTHORS
index 1f39fdb6c4..4444ee16af 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -490,6 +490,7 @@ answer newbie questions, and generally made Django that much better:
Jökull Sólberg Auðunsson <jokullsolberg@gmail.com>
Jon Dufresne <jon.dufresne@gmail.com>
Jonas Haag <jonas@lophus.org>
+ Jonas Lundberg <jonas.lundberg@gmail.com>
Jonathan Davis <jonathandavis47780@gmail.com>
Jonatas C. D. <jonatas.cd@gmail.com>
Jonathan Buchanan <jonathan.buchanan@gmail.com>
diff --git a/django/core/handlers/asgi.py b/django/core/handlers/asgi.py
index 11c8bc209b..cfe5101ea4 100644
--- a/django/core/handlers/asgi.py
+++ b/django/core/handlers/asgi.py
@@ -171,14 +171,14 @@ class ASGIHandler(base.BaseHandler):
)
# Get the request and check for basic issues.
request, error_response = self.create_request(scope, body_file)
+ if request is None:
+ await self.send_response(error_response, send)
+ return
+ # Get the response, using the async mode of BaseHandler.
+ response = await self.get_response_async(request)
+ response._handler_class = self.__class__
finally:
body_file.close()
- if request is None:
- await self.send_response(error_response, send)
- return
- # Get the response, using the async mode of BaseHandler.
- response = await self.get_response_async(request)
- response._handler_class = self.__class__
# Increase chunk size on file responses (ASGI servers handles low-level
# chunking).
if isinstance(response, FileResponse):
diff --git a/tests/asgi/tests.py b/tests/asgi/tests.py
index ef7b55724e..cfee11802c 100644
--- a/tests/asgi/tests.py
+++ b/tests/asgi/tests.py
@@ -163,6 +163,18 @@ class ASGITest(SimpleTestCase):
self.assertEqual(response_body["type"], "http.response.body")
self.assertEqual(response_body["body"], b"From Scotland,Wales")
+ async def test_post_body(self):
+ application = get_asgi_application()
+ scope = self.async_request_factory._base_scope(method="POST", path="/post/")
+ communicator = ApplicationCommunicator(application, scope)
+ await communicator.send_input({"type": "http.request", "body": b"Echo!"})
+ response_start = await communicator.receive_output()
+ self.assertEqual(response_start["type"], "http.response.start")
+ self.assertEqual(response_start["status"], 200)
+ response_body = await communicator.receive_output()
+ self.assertEqual(response_body["type"], "http.response.body")
+ self.assertEqual(response_body["body"], b"Echo!")
+
async def test_get_query_string(self):
application = get_asgi_application()
for query_string in (b"name=Andrew", "name=Andrew"):
diff --git a/tests/asgi/urls.py b/tests/asgi/urls.py
index e6c74ab488..bd286c9b2f 100644
--- a/tests/asgi/urls.py
+++ b/tests/asgi/urls.py
@@ -2,6 +2,7 @@ import threading
from django.http import FileResponse, HttpResponse
from django.urls import path
+from django.views.decorators.csrf import csrf_exempt
def hello(request):
@@ -23,6 +24,11 @@ def sync_waiter(request):
return hello(request)
+@csrf_exempt
+def post_echo(request):
+ return HttpResponse(request.body)
+
+
sync_waiter.active_threads = set()
sync_waiter.lock = threading.Lock()
sync_waiter.barrier = threading.Barrier(2)
@@ -35,5 +41,6 @@ urlpatterns = [
path("", hello),
path("file/", lambda x: FileResponse(open(test_filename, "rb"))),
path("meta/", hello_meta),
+ path("post/", post_echo),
path("wait/", sync_waiter),
]