[4.1.x] Fixed #33754 -- Fixed crash with prematurely closed ASGI request body.
Regression in441103a04d
. Backport off1e0fc645b
from main
This commit is contained in:
parent
000e8e0d38
commit
6df6c1b970
1
AUTHORS
1
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>
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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"):
|
||||
|
|
|
@ -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),
|
||||
]
|
||||
|
|
Loading…
Reference in New Issue