middleware.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. from asgiref.sync import iscoroutinefunction, markcoroutinefunction
  2. from django.http import Http404, HttpResponse
  3. from django.template import engines
  4. from django.template.response import TemplateResponse
  5. from django.utils.decorators import (
  6. async_only_middleware,
  7. sync_and_async_middleware,
  8. sync_only_middleware,
  9. )
  10. log = []
  11. class BaseMiddleware:
  12. def __init__(self, get_response):
  13. self.get_response = get_response
  14. if iscoroutinefunction(self.get_response):
  15. markcoroutinefunction(self)
  16. def __call__(self, request):
  17. return self.get_response(request)
  18. class ProcessExceptionMiddleware(BaseMiddleware):
  19. def process_exception(self, request, exception):
  20. return HttpResponse("Exception caught")
  21. @async_only_middleware
  22. class AsyncProcessExceptionMiddleware(BaseMiddleware):
  23. async def process_exception(self, request, exception):
  24. return HttpResponse("Exception caught")
  25. class ProcessExceptionLogMiddleware(BaseMiddleware):
  26. def process_exception(self, request, exception):
  27. log.append("process-exception")
  28. class ProcessExceptionExcMiddleware(BaseMiddleware):
  29. def process_exception(self, request, exception):
  30. raise Exception("from process-exception")
  31. class ProcessViewMiddleware(BaseMiddleware):
  32. def process_view(self, request, view_func, view_args, view_kwargs):
  33. return HttpResponse("Processed view %s" % view_func.__name__)
  34. @async_only_middleware
  35. class AsyncProcessViewMiddleware(BaseMiddleware):
  36. async def process_view(self, request, view_func, view_args, view_kwargs):
  37. return HttpResponse("Processed view %s" % view_func.__name__)
  38. class ProcessViewNoneMiddleware(BaseMiddleware):
  39. def process_view(self, request, view_func, view_args, view_kwargs):
  40. log.append("processed view %s" % view_func.__name__)
  41. return None
  42. class ProcessViewTemplateResponseMiddleware(BaseMiddleware):
  43. def process_view(self, request, view_func, view_args, view_kwargs):
  44. template = engines["django"].from_string(
  45. "Processed view {{ view }}{% for m in mw %}\n{{ m }}{% endfor %}"
  46. )
  47. return TemplateResponse(
  48. request,
  49. template,
  50. {"mw": [self.__class__.__name__], "view": view_func.__name__},
  51. )
  52. class TemplateResponseMiddleware(BaseMiddleware):
  53. def process_template_response(self, request, response):
  54. response.context_data["mw"].append(self.__class__.__name__)
  55. return response
  56. @async_only_middleware
  57. class AsyncTemplateResponseMiddleware(BaseMiddleware):
  58. async def process_template_response(self, request, response):
  59. response.context_data["mw"].append(self.__class__.__name__)
  60. return response
  61. class LogMiddleware(BaseMiddleware):
  62. def __call__(self, request):
  63. response = self.get_response(request)
  64. log.append((response.status_code, response.content))
  65. return response
  66. class NoTemplateResponseMiddleware(BaseMiddleware):
  67. def process_template_response(self, request, response):
  68. return None
  69. @async_only_middleware
  70. class AsyncNoTemplateResponseMiddleware(BaseMiddleware):
  71. async def process_template_response(self, request, response):
  72. return None
  73. class NotFoundMiddleware(BaseMiddleware):
  74. def __call__(self, request):
  75. raise Http404("not found")
  76. class PaymentMiddleware(BaseMiddleware):
  77. def __call__(self, request):
  78. response = self.get_response(request)
  79. response.status_code = 402
  80. return response
  81. @async_only_middleware
  82. def async_payment_middleware(get_response):
  83. async def middleware(request):
  84. response = await get_response(request)
  85. response.status_code = 402
  86. return response
  87. return middleware
  88. @sync_and_async_middleware
  89. class SyncAndAsyncMiddleware(BaseMiddleware):
  90. pass
  91. @sync_only_middleware
  92. class DecoratedPaymentMiddleware(PaymentMiddleware):
  93. pass
  94. class NotSyncOrAsyncMiddleware(BaseMiddleware):
  95. """Middleware that is deliberately neither sync or async."""
  96. sync_capable = False
  97. async_capable = False
  98. def __call__(self, request):
  99. return self.get_response(request)