Skip to content

Commit 6b4b7da

Browse files
committed
[3.1.x] Fixed #32299 -- Prevented mutating handlers when processing middlewares marking as unused in an async context.
Thanks Hubert Bielenia for the report. Backport of 98ad327 from master
1 parent 3029e22 commit 6b4b7da

3 files changed

Lines changed: 27 additions & 2 deletions

File tree

django/core/handlers/base.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,18 +51,20 @@ def load_middleware(self, is_async=False):
5151
middleware_is_async = middleware_can_async
5252
try:
5353
# Adapt handler, if needed.
54-
handler = self.adapt_method_mode(
54+
adapted_handler = self.adapt_method_mode(
5555
middleware_is_async, handler, handler_is_async,
5656
debug=settings.DEBUG, name='middleware %s' % middleware_path,
5757
)
58-
mw_instance = middleware(handler)
58+
mw_instance = middleware(adapted_handler)
5959
except MiddlewareNotUsed as exc:
6060
if settings.DEBUG:
6161
if str(exc):
6262
logger.debug('MiddlewareNotUsed(%r): %s', middleware_path, exc)
6363
else:
6464
logger.debug('MiddlewareNotUsed: %r', middleware_path)
6565
continue
66+
else:
67+
handler = adapted_handler
6668

6769
if mw_instance is None:
6870
raise ImproperlyConfigured(

docs/releases/3.1.5.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,7 @@ Bugfixes
1212
* Fixed ``__isnull=True`` lookup on key transforms for
1313
:class:`~django.db.models.JSONField` with Oracle and SQLite
1414
(:ticket:`32252`).
15+
16+
* Fixed a bug in Django 3.1 that caused a crash when processing middlewares in
17+
an async context with a middleware that raises a ``MiddlewareNotUsed``
18+
exception (:ticket:`32299`).

tests/middleware_exceptions/tests.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,25 @@ def test_do_not_log_when_debug_is_false(self):
181181
with self.assertLogs('django.request', 'DEBUG'):
182182
self.client.get('/middleware_exceptions/view/')
183183

184+
@override_settings(MIDDLEWARE=[
185+
'middleware_exceptions.middleware.SyncAndAsyncMiddleware',
186+
'middleware_exceptions.tests.MyMiddleware',
187+
])
188+
async def test_async_and_sync_middleware_chain_async_call(self):
189+
with self.assertLogs('django.request', 'DEBUG') as cm:
190+
response = await self.async_client.get('/middleware_exceptions/view/')
191+
self.assertEqual(response.content, b'OK')
192+
self.assertEqual(response.status_code, 200)
193+
self.assertEqual(
194+
cm.records[0].getMessage(),
195+
'Asynchronous middleware middleware_exceptions.tests.MyMiddleware '
196+
'adapted.',
197+
)
198+
self.assertEqual(
199+
cm.records[1].getMessage(),
200+
"MiddlewareNotUsed: 'middleware_exceptions.tests.MyMiddleware'",
201+
)
202+
184203

185204
@override_settings(
186205
DEBUG=True,

0 commit comments

Comments
 (0)