Fixed #32299 -- Prevented mutating handlers when processing middlewares marking as unused in an async context.

Thanks Hubert Bielenia for the report.
This commit is contained in:
Mariusz Felisiak 2020-12-29 09:04:35 +01:00 committed by GitHub
parent 45519937e5
commit 98ad327864
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 27 additions and 2 deletions

View File

@ -51,11 +51,11 @@ class BaseHandler:
middleware_is_async = middleware_can_async
try:
# Adapt handler, if needed.
handler = self.adapt_method_mode(
adapted_handler = self.adapt_method_mode(
middleware_is_async, handler, handler_is_async,
debug=settings.DEBUG, name='middleware %s' % middleware_path,
)
mw_instance = middleware(handler)
mw_instance = middleware(adapted_handler)
except MiddlewareNotUsed as exc:
if settings.DEBUG:
if str(exc):
@ -63,6 +63,8 @@ class BaseHandler:
else:
logger.debug('MiddlewareNotUsed: %r', middleware_path)
continue
else:
handler = adapted_handler
if mw_instance is None:
raise ImproperlyConfigured(

View File

@ -12,3 +12,7 @@ Bugfixes
* Fixed ``__isnull=True`` lookup on key transforms for
:class:`~django.db.models.JSONField` with Oracle and SQLite
(:ticket:`32252`).
* Fixed a bug in Django 3.1 that caused a crash when processing middlewares in
an async context with a middleware that raises a ``MiddlewareNotUsed``
exception (:ticket:`32299`).

View File

@ -181,6 +181,25 @@ class MiddlewareNotUsedTests(SimpleTestCase):
with self.assertLogs('django.request', 'DEBUG'):
self.client.get('/middleware_exceptions/view/')
@override_settings(MIDDLEWARE=[
'middleware_exceptions.middleware.SyncAndAsyncMiddleware',
'middleware_exceptions.tests.MyMiddleware',
])
async def test_async_and_sync_middleware_chain_async_call(self):
with self.assertLogs('django.request', 'DEBUG') as cm:
response = await self.async_client.get('/middleware_exceptions/view/')
self.assertEqual(response.content, b'OK')
self.assertEqual(response.status_code, 200)
self.assertEqual(
cm.records[0].getMessage(),
'Asynchronous middleware middleware_exceptions.tests.MyMiddleware '
'adapted.',
)
self.assertEqual(
cm.records[1].getMessage(),
"MiddlewareNotUsed: 'middleware_exceptions.tests.MyMiddleware'",
)
@override_settings(
DEBUG=True,