mirror of https://github.com/django/django.git
Fixed #33754 -- Fixed crash with prematurely closed ASGI request body.
Regression in 441103a04d
.
This commit is contained in:
parent
292f372768
commit
f1e0fc645b
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>
|
Jökull Sólberg Auðunsson <jokullsolberg@gmail.com>
|
||||||
Jon Dufresne <jon.dufresne@gmail.com>
|
Jon Dufresne <jon.dufresne@gmail.com>
|
||||||
Jonas Haag <jonas@lophus.org>
|
Jonas Haag <jonas@lophus.org>
|
||||||
|
Jonas Lundberg <jonas.lundberg@gmail.com>
|
||||||
Jonathan Davis <jonathandavis47780@gmail.com>
|
Jonathan Davis <jonathandavis47780@gmail.com>
|
||||||
Jonatas C. D. <jonatas.cd@gmail.com>
|
Jonatas C. D. <jonatas.cd@gmail.com>
|
||||||
Jonathan Buchanan <jonathan.buchanan@gmail.com>
|
Jonathan Buchanan <jonathan.buchanan@gmail.com>
|
||||||
|
|
|
@ -171,14 +171,14 @@ class ASGIHandler(base.BaseHandler):
|
||||||
)
|
)
|
||||||
# Get the request and check for basic issues.
|
# Get the request and check for basic issues.
|
||||||
request, error_response = self.create_request(scope, body_file)
|
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:
|
finally:
|
||||||
body_file.close()
|
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
|
# Increase chunk size on file responses (ASGI servers handles low-level
|
||||||
# chunking).
|
# chunking).
|
||||||
if isinstance(response, FileResponse):
|
if isinstance(response, FileResponse):
|
||||||
|
|
|
@ -163,6 +163,18 @@ class ASGITest(SimpleTestCase):
|
||||||
self.assertEqual(response_body["type"], "http.response.body")
|
self.assertEqual(response_body["type"], "http.response.body")
|
||||||
self.assertEqual(response_body["body"], b"From Scotland,Wales")
|
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):
|
async def test_get_query_string(self):
|
||||||
application = get_asgi_application()
|
application = get_asgi_application()
|
||||||
for query_string in (b"name=Andrew", "name=Andrew"):
|
for query_string in (b"name=Andrew", "name=Andrew"):
|
||||||
|
|
|
@ -2,6 +2,7 @@ import threading
|
||||||
|
|
||||||
from django.http import FileResponse, HttpResponse
|
from django.http import FileResponse, HttpResponse
|
||||||
from django.urls import path
|
from django.urls import path
|
||||||
|
from django.views.decorators.csrf import csrf_exempt
|
||||||
|
|
||||||
|
|
||||||
def hello(request):
|
def hello(request):
|
||||||
|
@ -23,6 +24,11 @@ def sync_waiter(request):
|
||||||
return hello(request)
|
return hello(request)
|
||||||
|
|
||||||
|
|
||||||
|
@csrf_exempt
|
||||||
|
def post_echo(request):
|
||||||
|
return HttpResponse(request.body)
|
||||||
|
|
||||||
|
|
||||||
sync_waiter.active_threads = set()
|
sync_waiter.active_threads = set()
|
||||||
sync_waiter.lock = threading.Lock()
|
sync_waiter.lock = threading.Lock()
|
||||||
sync_waiter.barrier = threading.Barrier(2)
|
sync_waiter.barrier = threading.Barrier(2)
|
||||||
|
@ -35,5 +41,6 @@ urlpatterns = [
|
||||||
path("", hello),
|
path("", hello),
|
||||||
path("file/", lambda x: FileResponse(open(test_filename, "rb"))),
|
path("file/", lambda x: FileResponse(open(test_filename, "rb"))),
|
||||||
path("meta/", hello_meta),
|
path("meta/", hello_meta),
|
||||||
|
path("post/", post_echo),
|
||||||
path("wait/", sync_waiter),
|
path("wait/", sync_waiter),
|
||||||
]
|
]
|
||||||
|
|
Loading…
Reference in New Issue