skillbox/server/core/middleware.py

77 lines
2.6 KiB
Python

from django.conf import settings
from django.http import Http404, HttpResponsePermanentRedirect, HttpResponseRedirect
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import redirect
import re
try:
from threading import local
except ImportError:
from django.utils._threading_local import local
_thread_locals = local()
def get_current_request():
""" returns the request object for this thread """
return getattr(_thread_locals, "request", None)
def get_current_user():
""" returns the current user, if exist, otherwise returns None """
request = get_current_request()
if request:
return getattr(request, "user", None)
class ThreadLocalMiddleware(MiddlewareMixin):
""" Simple middleware that adds the request object in thread local storage."""
def process_request(self, request):
_thread_locals.request = request
def process_response(self, request, response):
if hasattr(_thread_locals, 'request'):
del _thread_locals.request
return response
class CommonRedirectMiddleware(MiddlewareMixin):
"""
redirects common bad requests or missing images
"""
DEFAULT_REDIRECTS = [
(re.compile("(?i)(.+\.php|.+wp-admin.+|.+\.htm|\/wordpress\/|\/wp\/|\/mm5\/|\/wp-content\/)"),
'http://example.org/'),
]
def process_exception(self, request, exception):
if exception.__class__ == Http404:
new_path = self.not_found(request)
if new_path:
return redirect(new_path, permanent=True)
def process_response(self, request, response):
if response.status_code == 404:
new_path = self.not_found(request)
if new_path:
return HttpResponsePermanentRedirect(new_path)
return response
def not_found(self, request):
path = request.get_full_path().lower()
# generic stuff
for re_pattern, to in self.DEFAULT_REDIRECTS:
if re_pattern.match(path):
return to
if settings.USE_404_FALLBACK_IMAGE:
# some static image is missing show a placeholder (use full for local dev)
m = re.match(r".*(max|fill)-(?P<dimensions>\d+x\d+)\.(jpg|png|svg)", path)
if m:
return 'https://picsum.photos/{}'.format(m.group('dimensions').replace('x', '/'))
# or dummy image: return 'http://via.placeholder.com/{}'.format(m.group('dimensions'))
if '.png' in path or '.jpg' in path or '.svg' in path or 'not-found' in path:
return 'https://picsum.photos/400/400'